模型

一、定义

1.模型定义

<?php
namespace app\index\model;

use think\Model;

class User extends Model
{
}

模型自动对应数据表名称,遵循小写+下划线规范,如果表名有大写情况,必须设置模型的table属性。

不同模块的模型是不需要独立的,因此可以统一在common模块下面定义模型。

2.模型设置

默认主键为id,如果没有使用id作为主键名,需要在模型中设置属性。

protected $pk = 'uid';

5.1中模型不会自动获取主键名称,必须设置pk属性。

常用的模型设置属性包括(以下属性都不是必须设置):

属性描述
name模型名(默认为当前不含后缀的模型类名)
table数据表名(默认自动获取)
pk主键名(默认为id
connection数据库连接(默认读取数据库配置)
query模型使用的查询类名称
field

模型对应数据表的字段列表(数组)

3.模型初始化

<?php
namespace app\index\model;

use think\Model;

class User extends Model
{

    // 模型初始化
    protected static function init()
    {
        //通常用于注册模型的事件操作
        //TODO:初始化内容
    }
}

init必须是静态方法,并且只在第一次实例化的时候执行

二、新增

1.添加一条数据

save方法返回影响的记录数(通常是1),而不是自增主键值。从v5.1.6+版本开始统一返回布尔值

①实例化模型对象后赋值并保存

$user           = new User;
$user->name     = 'thinkphp';
$user->email    = 'thinkphp@qq.com';
$user->save();

②直接传入数据到save方法批量赋值

$user = new User;
$user->save([
    'name'  =>  'thinkphp',
    'email' =>  'thinkphp@qq.com'
]);

③直接在实例化的时候传入数据

$user = new User([
    'name'  =>  'thinkphp',
    'email' =>  'thinkphp@qq.com'
]);
$user->save();

实例化传入的模型数据也不会经过修改器处理。

★ 过滤非数据表字段数据

$user = new User;
// 过滤post数组中的非数据表字段数据
$user->allowField(true)->save($_POST);

★ 指定写入某些字段

$user = new User;
// post数组中只有name和email字段会写入
$user->allowField(['name','email'])->save($_POST);

★ 模型数据赋值之前进行数据过滤

$user = new User;
// 过滤post数组中的非数据表字段数据
$data = Request::only(['name','email']);
$user->save($data);

2.获取自增ID

$user->id;

3.添加多条数据(最佳

saveAll方法新增数据返回的是包含新增模型(带自增ID)的数据集对象。

$user = new User;
$list = [
    ['name'=>'thinkphp','email'=>'thinkphp@qq.com'],
    ['name'=>'onethink','email'=>'onethink@qq.com']
];
$user->saveAll($list);

saveAll方法新增数据默认会自动识别数据是需要新增还是更新操作,当数据中存在主键的时候会认为是更新操作,如果你需要带主键数据批量新增,可以使用下面的方式:

$user = new User;
$list = [
    ['id'=>1, 'name'=>'thinkphp', 'email'=>'thinkphp@qq.com'],
    ['id'=>2, 'name'=>'onethink', 'email'=>'onethink@qq.com'],
];
$user->saveAll($list, false);

4.静态方法(最佳

create方法返回的是当前模型的对象实例

①直接静态调用create方法创建并写入

$user = User::create([
    'name'  =>  'thinkphp',
    'email' =>  'thinkphp@qq.com'
]);
echo $user->id; // 获取自增ID

②第二个参数可以传入允许写入的字段列表(传入true则表示仅允许写入数据表定义的字段数据)

// 只允许写入name和email字段的数据
$user = User::create([
    'name'  =>  'thinkphp',
    'email' =>  'thinkphp@qq.com'
], ['name', 'email']);
echo $user->id; // 获取自增ID

三、更新

1.查找并更新(使用模型事件时最佳

save方法返回影响的记录数,从V5.1.6+版本开始统一返回布尔值

$user = User::get(1);
//复杂的查询条件
$user = User::where('status',1)
	->where('name','liuchen')
	->find();
$user->name     = 'thinkphp';
$user->email    = 'thinkphp@qq.com';
$user->save();

save方法更新数据,只会更新变化的数据,对于没有变化的数据是不会进行重新更新的。如果你需要强制更新数据,可以使用下面的方法:

$user = User::get(1);
$user->name     = 'thinkphp';
$user->email    = 'thinkphp@qq.com';
$user->force()->save();

★ 执行SQL函数更新(V5.1.8+)

$user->score	=  Db::raw('score+1');

★ 只是字段的增加/减少

$user->score	= ['inc', 1];

2.直接更新数据

直接带更新条件来更新数据

$user = new User;
// save方法第二个参数为更新条件
$user->save([
    'name'  => 'thinkphp',
    'email' => 'thinkphp@qq.com'
],['id' => 1]);

★ 过滤非数据表字段的数据,可以使用:

$user = new User;
// 过滤post数组中的非数据表字段数据
$user->allowField(true)->save($_POST,['id' => 1]);

★ 指定某些字段写入,可以使用:

$user = new User();
// post数组中只有name和email字段会写入
$user->allowField(['name','email'])->save($_POST, ['id' => 1]);

★ 传入模型数据之前就进行过滤,例如:

$user = new User();
// post数组中只有name和email字段会写入
$data = Request::only(['name','email']);
$user->save($data, ['id' => 1]);

3.批量更新数据(避免

使用saveAll方法批量更新数据,需要在批量更新的数据中包含主键

批量更新方法返回的是一个数据集对象。

$user = new User;
$list = [
    ['id'=>1, 'name'=>'thinkphp', 'email'=>'thinkphp@qq.com'],
    ['id'=>2, 'name'=>'onethink', 'email'=>'onethink@qq.com']
];
$user->saveAll($list);

批量更新仅能根据主键值进行更新,其它情况请自行处理。

4.静态方法(最佳

①调用数据库的方法直接更新数据

数据库的update方法返回影响的记录数

User::where('id', 1)
    ->update(['name' => 'thinkphp']);

②使用模型的静态update方法更新

模型的update方法返回模型的对象实例(可以支持模型的修改器、事件和自动完成)

User::update(['id' => 1, 'name' => 'thinkphp']);

5.自动识别

  • 实例化模型后调用save方法表示新增;
  • 查询数据后调用save方法表示更新;
  • save方法传入更新条件后表示更新;

数据操作比较复杂,可以用isUpdate方法显式的指定当前调用save方法是新增操作还是更新操作。

★ 显式更新数据:

// 实例化模型
$user = new User;
// 显式指定更新数据操作
$user->isUpdate(true)
    ->save(['id' => 1, 'name' => 'thinkphp']);

★ 显式新增数据:

$user = User::get(1);
$user->name = 'thinkphp';
// 显式指定当前操作为新增操作
$user->isUpdate(false)->save();

不要在一个模型实例里面做多次更新,会导致部分重复数据不再更新,正确的方式应该是先查询后更新或者使用模型类的update方法更新。

如果你调用save方法进行多次数据写入的时候,需要注意,第二次save方法的时候必须使用isUpdate(false),否则会视为更新数据。

四、查询

模型查询的最佳实践原则是:在模型外部使用静态方法进行查询,内部使用动态方法查询,包括使用数据库的查询构造器。模型的查询始终返回对象实例,但可以和数组一样使用。

1.获取单个数据

使用get还是find方法查询,返回的是都当前模型的对象实例,如果查询数据不存在,则返回Null

①取出主键为1的数据

$user = User::get(1);

②使用查询构造器查询满足条件的数据

$user = User::where('name', 'thinkphp')->find();

V5.1.5+ getOrFail,当查询的数据不存在的时候会抛出ModelNotFound异常。

V5.1.23+ findOrEmpty,当查询数据不存在的话,返回空模型而不是Null

如果你是在模型内部获取模型数据,请不要使用$this->name的方式来获取数据,请使用$this->getAttr('name') 替代。

2.获取多个数据

①取出多个数据:

// 根据主键获取多个数据
$list = User::all('1,2,3');
// 或者使用数组
$list = User::all([1,2,3]);
// 对数据集进行遍历操作
foreach($list as $key=>$user){
    echo $user->name;
}

V5.1.21+版本开始,可以在all方法之前使用Db类的查询链式操作

②要更多的查询支持,一样可以使用查询构造器:

// 使用查询构造器查询
$list = User::where('status', 1)->limit(3)->order('id', 'asc')->select();
foreach($list as $key=>$user){
    echo $user->name;
}

3.使用查询构造器

①获取某个字段或者某个列的值

// 获取某个用户的积分
User::where('id',10)->value('score');
// 获取某个列的所有值
User::where('status',1)->column('name');
// 以id为索引
User::where('status',1)->column('name','id');

valuecolumn方法返回的不再是一个模型对象实例,而是纯粹的值或者某个列的数组。

②动态查询

// 根据name字段查询用户
$user = User::getByName('thinkphp');

// 根据email字段查询用户
$user = User::getByEmail('thinkphp@qq.com');

③聚合查询

User::count();
User::where('status','>',0)->count();
User::where('status',1)->avg('score');
User::max('score');

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值