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();
        }
    }
    
  • 相关阅读:
    scrapy中selenium的应用
    Django的锁和事务
    redis
    【leetcode】187. Repeated DNA Sequences
    【leetcode】688. Knight Probability in Chessboard
    【leetcode】576. Out of Boundary Paths
    【leetcode】947. Most Stones Removed with Same Row or Column
    【leetcode】948. Bag of Tokens
    【leetcode】946. Validate Stack Sequences
    【leetcode】945. Minimum Increment to Make Array Unique
  • 原文地址:https://www.cnblogs.com/oneboi/p/8266942.html
Copyright © 2011-2022 走看看