zoukankan      html  css  js  c++  java
  • 关联模型(1:n)

    关联模型 (1对n)

    ThinkPHP5.0 的关联采用了对象化的操作模式,你无需继承不同的模型类
    只是把关联定义成一个方法,并且直接通过当前模型对象的属性名获取定义的关联数据。

    关联定义:一个user有多本书book

    DROP TABLE IF EXISTS `think_user`;
    CREATE TABLE IF NOT EXISTS `think_user` (
    `id` int(6) UNSIGNED NOT NULL AUTO_INCREMENT,
    `nickname` varchar(25) NOT NULL,
    `name` varchar(25) NOT NULL,
    `password` varchar(50) NOT NULL,
    `create_time` int(11) UNSIGNED NOT NULL,
    `update_time` int(11) UNSIGNED NOT NULL,
    `status` tinyint(1) DEFAULT 0,
    PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
    
    
    
    DROP TABLE IF EXISTS `think_book`;
    CREATE TABLE IF NOT EXISTS `think_book` (
    `id` int(8) UNSIGNED NOT NULL AUTO_INCREMENT,
    `title` varchar(255) NOT NULL,
    `publish_time` int(11) UNSIGNED DEFAULT NULL,
    `create_time` int(11) UNSIGNED NOT NULL,
    `update_time` int(11) UNSIGNED NOT NULL,
    `status` tinyint(1) NOT NULL,
    `user_id` int(6) UNSIGNED NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
    
    

    在User 模型类添加Book 关联如下:

    • hasMany

    hasMany 的参数如下:
    hasMany('关联模型名','关联外键','关联模型主键','别名定义')

    步骤一、定义Uer模型和关联方法book

    <?php 
    namespace appindexmodel;
    use thinkModel;
    class User extends Model
    {
    // 开启自动写入时间戳
    protected $autoWriteTimestamp = true;
    // 定义自动完成的属性
    protected $insert = ['status' => 1];
    
        // 定义关联hasMany
        public function books()
        {
        return $this->hasMany('Book');
        }
    }
    

    步骤二、定义book模型

    <?php 
    namespace appindexmodel;
    use thinkModel;
    class Book extends Model
    {
    protected $type = [
    'publish_time' => 'timestamp:Y-m-d',
    ];
        // 开启自动写入时间戳
        protected $autoWriteTimestamp = true;
        // 定义自动完成的属性
        protected $insert = ['status' => 1];
    }
    
     ?>
    

    1. 关联新增

    添加addBook 方法用于新增关联数据:

    public function addBook()
    {
    $user = UserModel::get(1);
    $book = new Book;
    $book->title = 'ThinkPHP5快速入门';
    $book->publish_time = '2016-05-06';
    $user->books()->save($book);
    return '添加Book成功';
    }
    

    对于一对多关联,也可以批量增加数据:

    public function addBook()
    {
    $user = UserModel::get(1);
    $books = [
    ['title' => 'ThinkPHP5快速入门', 'publish_time' => '2016-05-06'],
    ['title' => 'ThinkPHP5开发手册', 'publish_time' => '2016-03-06'],
    ];
    $user->books()->saveAll($books);
    return '添加Book成功';
    }
    

    2.关联查询

    可以直接调用模型的属性获取全部关联数据,例如:

    public function read()
    {
    $user = UserModel::get(1);
    $books = $user->books;
    dump($books);
    
    

    一对多查询同样可以使用预载入查询,例如:

    public function read()
    {
    $user = UserModel::get(1,'books');
    $books = $user->books;
    dump($books);
    }
    

    一对多预载入查询会在原先延迟查询的基础上增加一次查询,可以解决典型的N+1 次查询问题。
    如果要过滤查询,可以调用关联方法:

    public function read()
    {
    $user = UserModel::get(1);
    // 获取状态为1的关联数据
    $books = $user->books()->where('status',1)->select();
    dump($books);
    // 获取作者写的某本书
    $book = $user->books()->getByTitle('ThinkPHP5快速入门');
    dump($book);
    }
    

    还可以根据关联数据来查询当前模型数据,例如:

    public function read()
    {
    // 查询有写过书的作者列表
    $user = UserModel::has('books')->select();
    // 查询写过三本书以上的作者
    $user = UserModel::has('books', '>=', 3)->select();
    // 查询写过ThinkPHP5快速入门的作者
    $user = UserModel::hasWhere('books', ['title' => 'ThinkPHP5快速入门'])->select();
    }
    

    3.关联更新

    public function update($id)
    {
    $user = UserModel::get($id);
    $book = $user->books()->getByTitle('ThinkPHP5开发手册');
    $book->title = 'ThinkPHP5快速入门';
    $book->save();
    

    或者使用查询构建器的update 方法进行更新(但可能无法触发关联模型的事件

    public function update($id)
    {
    $user = UserModel::get($id);
    $user->books()->where('title', 'ThinkPHP5快速入门')->update(['title' => 'ThinkPHP5开
    发手册']);
    }
    

    4. 关联删除

    删除部分关联数据:

        public function delete($id){
        $user = UserModel::get($id);
        // 删除部分关联数据
        $book = $user->books()->getByTitle('ThinkPHP5开发手册');
        $book->delete();
        }
    

    删除所有的关联数据:

    public function delete($id){
        $user = UserModel::get($id);
        if($user->delete()){
        // 删除所有的关联数据
        $user->books()->delete();
        }
    }
    
  • 相关阅读:
    Spring 整合过滤器
    Spring Boot 整合 AOP
    Linux IO模式及 select、poll、epoll详解
    java 集合之ArrayList、Vector、LinkedList、CopyOnWriteArrayList
    java 集合之HashMap、Hashtable、LinkedHashMap、TreeMap
    java modCount和fail-fast
    java ArrayList迭代过程中删除
    JVM metaspace元空间
    反转链表
    合并两个排序的链表
  • 原文地址:https://www.cnblogs.com/oneboi/p/8266942.html
Copyright © 2011-2022 走看看