thinkphp about the use of model one-to-many, many-to-many, many-to-one

  1. First look at the model introduction of thinkphp5.0

There are one-to-one, many-to-many, one-to-many, and many-to-one associations here. There is also pre-loading (that is, the query is pre-written, and it is queried when the php interface is called), as well as related statistics, aggregation, etc. Here we only explain how to launch others through one-to-one preloading.

  • This document gives an example of a one-to-one relationship between Profile and User.

  • Model layer

Profile has a foreign key ($foreignKey) uid associated with User id, because id is the default field, you don’t need to write it, so the relationship is written like this

class Profile extends Model{
    public functionuser(){
        return $this->belongsTo('User','uid');
    }
}

It can also be written in this way, which is equivalent to select * from user where id = (?1), ?1 is the uid of the detected Profile, and the value is assigned to it, which is equivalent to two queries, one querying Profile, and then querying User

class Profile extends Model{
    public functionuser(){
        return $this->belongsTo('User','uid','id');
    }
}
  • control layer

$profile = Profile::get(1);

Here $profile gets all the fields (including uid (? 1)), which is equivalent to select * from profile. The first layer of query. Then the belongsTo query can continue (select * from user where id = (?1))

  1. Practical

Write control layer (first layer query)

$question = new Question();
$lists = $question->field('id,question_category,name,right_num,"show",content')
->with('questionCategory1')
->order('create_time asc')
->paginate($this->web_data['list_rows'], false, $page_param);
$this->assign([
    'lists' => $lists,
    'page'  => $lists->render(),
    'total' => $lists->total()
]);
  • The focus is on the question_category in the field, where the foreign key is queried to prepare for the preloaded subquery

  • inside with is the name of the preloaded method and the name of the attribute to be called, for example, questionCategory1 in this article.

Write view layer (second layer call)

{foreach name="lists" item="list"}
<tr>
    <td><input type="checkbox" onclick="check_this(this)" name="data-checkbox"
               data-id="{$list.id}" class="checkbox data-list-check" value="{$list.id}"
               placeholder="选择/取消"></td>
    <td>{$list.id}</td>
    </td>
    <td>{$list.name}</td>
    <td>{$list.content}</td>
    <td>{$list.right_num}</td>
    <td>{$list->questionCategory1['title']}</td>
    <td>
        {if condition="$list.show eq '1'"}已显示
        {else /} 已隐藏
        {/if}
    </td>
    <td>
        {if condition="$list.show eq '1'"}
            <a href="{:url($web_data['do_url'].'unground','id='.$list.id)}"
               class="btn btn-default btn-sm margin">
                <i class="fa fa-edit"></i>
                隐藏
            </a>
        {else /}
            <a href="{:url($web_data['do_url'].'detail','id='.$list.id)}"
               class="btn btn-default btn-sm margin">
                <i class="fa fa-edit"></i>
                修改
            </a>
            <a href="{:url($web_data['do_url'].'ground','id='.$list.id)}"
               class="btn btn-default btn-sm margin">
                <i class="fa fa-edit"></i>
               显示
            </a>
            <a data-toggle="modal" data-target="#modal"
               class="btn btn-danger btn-sm margin"
               title="删除" onclick="del({$list.id})">
                <i class="fa fa-close"></i>
                删除
            </a>
        {/if}
    </td>
</tr>
{/foreach}
  • The ${lists} here is the parameter from the background transfer (assign), which is an object array, which is displayed on the interface through a loop.

{$list->questionCategory1['title']} is to call the questionCategory1 method to get the title attribute inside, and this call triggers the preloading function

write model layer

  • Question

namespace app\common\model;

use think\Model;

class Question extends Model
{
    protected $name = 'question';

    public function questionAnswer() {
        return $this->hasMany("QuestionAnswer", "question_id", "id");
    }
    
    //注意这里的questionCategory1特地加1是因为防止和和question_category的驼峰一致导致报错
    //这里field一定要查询出QuestionCategory的主键id,因为这个作为第二层查询的条件,如果去掉id会报错
    //这里的QuestionCategory的主键是id,question_category是Question的外键(关联QuestionCategory)
    public function questionCategory1()
    {
        return $this->belongsTo('QuestionCategory','question_category','id')->field('id,title');
    }
}

A: The preloading method of Question here is questionCategory1 (declaration), which matches with (preloading) of the control layer and also matches questionCategory1 (calling) of the view layer

B:然后从属关系,是一对一的QuestionCategory和Question,外键在Question上,外键名字是question_category,主键在QuestionCategory上的id

C:belongsTo的field代表Question这个模型的方法questionCategory1预加载了模型QuestionCategory的id和title属性,id作为第二次查询的条件和第一层查出来的question_category匹配作为条件

D:而且question_category不能和方法名驼峰一致。必须不相同。例如该方法的questionCategory和question_category相同会报错。所以改成了questionCategory1方法名

  • QuestionCategory

namespace app\common\model;
use think\Model;

class QuestionCategory extends Model
{
    protected $name = 'question_category';

}

同理推得一对多

    public function questionAnswer() {
        return $this->hasMany("QuestionAnswer", "question_id", "id");
    }

同理推理的一对一

 public function adminLogData()
    {
        return $this->hasOne('AdminLogData','log_id','id')->field('data_id,log_id,data');
    }

等等

Guess you like

Origin blog.csdn.net/weixin_36667844/article/details/128931779