飞道的博客

Thinkphp5使用model模型操作数据库

274人阅读  评论(0)

thinkphp标准数据表设计:

创建时间字段:create_time

更新时间字段:update_time

删除时间字段:delete_time 

类型选int,如下图:

一、创建model的文件夹

在application文件夹下的二级对象目录中新建名为model的文件夹,该文件夹与对应的controller和view目录同级,如下图:

如果有多个模块(比如前台index,后台admin),操作的数据库都差不多,那么可以把model模型放到common公共模块里,如下:

二、创建model模型类

1、在model目录下创建model对象文件,一般model的名字和表名是对应的,例如:


  
  1. 表名 pre_user ---------------> 模型名 User.php
  2. 表名 pre_user_info ---------------> 模型名 UserInfo.php

 2、定义model模型


  
  1. <?php
  2. namespace app\ index\ model;
  3. use think\ Model;
  4. use think\ Db;
  5. class User extends Model{
  6. /**
  7. * 定义变量
  8. * 1.变量名称应与数据表中的字段名相同
  9. * 2.此处可根据需求省略,因为如果没有,thinkphp会自动在数据表中寻找的对应字段名
  10. */
  11. public $username;
  12. public $password;
  13. }
  14. ?>

3、如果数据模型定义名和表名不一致,那么就需要额外定义和声明,如下:


  
  1. <?php
  2. namespace app\ index\ model;
  3. use think\ Model;
  4. use think\ Db;
  5. class User extends Model
  6. {
  7. protected $table = "admin_user"; //指定数据表名
  8. protected $pk = 'id'; //指定主键的字段
  9. }
  10. ?>

三、调用model模型的方法


  
  1. //导入定义的数据模型类
  2. use \ app\ index\ model\ User;
  3. //方法一:
  4. $res = User::get( 1);
  5. //方法二:
  6. $user = new User;
  7. $res = $user::get( 1);
  8. //方法三:
  9. use think\ Loader;
  10. $user = Loader::model( "User");
  11. $res = $user::get( 1);
  12. //方法四:
  13. $user = model( "User");
  14. $res = $user::get( 1);

四、查询操作

get 获取一条记录

$res = User::get(1);

all 获取多条记录

1、不传参

$result = User::all(); //查询出所有记录 

2、参数为n,n为正整数 

$result = User::all(1); //查询出id为1的记录

3、参数为'n1, n2, n3...'

$result = User::all('7, 8, 9, 10'); //查询出id为7、8、9、10的4条记录 

4、参数为[n1, n2, n3...] 

$result = User::all([7, 8, 9, 10]); //查询出id为7、8、9、10的4条记录

find 查询某一条

 $res = User::where('id','1')->field('name')->find();

 不等于

->where('id','neq',1)

select 多条查询

$res = User::where('id','1')->field('name')->limit(2)->order('id DESC')->select();

value 按字段查询一条

$res = User::where('id','1')->value('name');

将结果转换成数组

$res = $res->toArray();

查询数目


  
  1. //查询总条数
  2. $res = User::count();
  3. //按条件统计条数
  4. $res = User::where( 'id', '>', 3)->count();

whereTime() 时间条件查询

1、获取今天的信息


  
  1. db( 'table')->whereTime( 'c_time', 'today')->select();
  2. //也可以简化为下面方式
  3. db( 'table')->whereTime( 'c_time', 'd')->select();

2、获取昨天的信息

db('table')->whereTime('c_time', 'yesterday')->select();

3、获取本周的信息


  
  1. db( 'table')->whereTime( 'c_time', 'week')->select();
  2. //也可以简化为下面方式
  3. db( 'table')->whereTime( 'c_time', 'w')->select();

4、获取本月的信息


  
  1. db( 'table')->whereTime( 'c_time', 'month')->select();
  2. //也可以简化为下面方式
  3. db( 'table')->whereTime( 'c_time', 'm')->select();

 5、获取上月的信息

db('table')->whereTime('c_time','last month')->select();    

6、获取今年的信息


  
  1. db( 'table')->whereTime( 'c_time', 'year')->select();
  2. //也可以简化为下面方式
  3. db( 'table')->whereTime( 'c_time', 'y')->select();

 7、获取去年的信息

db('table')->whereTime('c_time','last year')->select();     

8、日期区间查询


  
  1. //根据时间戳查询今天到后天
  2. db( 'table')->whereTime( 'time', 'between', [strtotime(date( 'Y-m-d')), strtotime(date( 'Y-m-d', strtotime( '+2 day')))])->select();
  3. 根据日期查询今天到后天
  4. db( 'table')->whereTime( 'time', 'between', [ '2020-3-28', '2020-3-30'])->select();

五、添加操作

1、使用create()方法添加


  
  1. $res = User::create([
  2. 'name' => '安阳',
  3. 'age' => 23,
  4. 'sex' => 1,
  5. 'password' => '123456'
  6. ]);

2、添加数据,并返回添加的主键


  
  1. $uid=UserModel::create([
  2. 'name' => '安阳',
  3. 'age' => 23,
  4. 'sex' => 1,
  5. 'password' => '123456'
  6. ])->id;

也可以使用DB类的insertGetId方法,如下:


  
  1. $uid = User::insertGetId([
  2. 'name' => '安阳',
  3. 'age' => 23,
  4. 'sex' => 1,
  5. 'password' => '123456'
  6. ]);

3、实例化方式添加

 


  
  1. $user = new User;
  2. $user->name = '安阳';
  3. $user->age = 23;
  4. $user->save();

4、实例化方式过滤插入字段,返回插入行数


  
  1. $user = new User;
  2. $data = [
  3. 'name' => '安阳',
  4. 'age' => 23,
  5. 'email' => '123456@qq.com'
  6. ];
  7. //只有name和age字段会写入
  8. $res = $user->allowField([ 'name', 'age'])->save($data);

5、模型使用allowField()过滤非数据表字段的数据


  
  1. //定义模型对象,并传入post数据
  2. $user = new User($_POST);
  3. //过滤post数组中的非数据表字段数据
  4. $user->allowField( true)->save();

6、模型使用allowField()指定某些字段写入


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

7、批量添加使用saveAll()


  
  1. user = new User;
  2. $list = [
  3. [ 'name'=> '安阳', 'email'=> 'thinkphp@qq.com'],
  4. [ 'name'=> '小柒', 'email'=> '12345678@qq.com']
  5. ];
  6. $user->saveAll($list);

也可以使用DB类的insertAll()方法,返回添加成功的条数 


  
  1. $res = User::insertAll([
  2. 'name' => '安阳',
  3. 'age' => 23,
  4. 'sex' => 1,
  5. 'password' => '123456'
  6. ]);

补充,过滤字段的其他方法:

1、在DB操作中,可以使用 strict 关闭字段严格检查

Db::name(‘user’)->strict(false)->insert($data);

2、使用php的 unset() 方法销毁变量

unset($data[‘file’]);

6、saveAll添加多条数据,返回对象列表


  
  1. $user = new User;
  2. $data = [
  3. [
  4. 'name' => '安阳',
  5. 'age' => 20,
  6. 'email' => '123456@qq.com'
  7. ],
  8. [
  9. 'name' => '小柒',
  10. 'age' => 25,
  11. 'email' => 'ap555@qq.com'
  12. ]
  13. ];
  14. $res = $user->allowField([ 'name', 'age'])->saveAll($data);

六、更新操作

1、update 返回影响行数

 $res = User::where(['id'=>1])->update(['name'=>'安阳']);

2、setField 单独更新某个字段

User::where('id',1)->setField('name','安阳');

3、setInc


  
  1. //setInc('money',10)表示将money字段加上10
  2. User::where([ 'id'=> 1])->setInc( 'money', 10);

4、setDec


  
  1. //setDec('money',10)表示将money字段减去10
  2. User::where([ 'id'=> 1])->setDec( 'money', 10);

5、批量更新,要求数据中含有主键,返回更新对象列表


  
  1. $user = new User;
  2. $res = $user->saveAll([
  3. [ 'id'=> 1, 'name' => '安阳'],
  4. [ 'id'=> 2, 'name' => '小柒']
  5. ]);

七、删除操作

1、传入主键,返回影响行数

$res = User::destroy(1);

2、传入条件,返回影响行数

 $res = User::destroy(['name'=>'安阳']);

3、条件删除 返回影响行数

 $res = User::where(['id'=>1])->delete();

八、事务

1、自动控制事务处理


  
  1. Db::transaction( function(){
  2. Db::table( 'order')->where([ 'id'=> 1])->delete();
  3. Db::table( 'user')->where( 'id'=> 1)->setInc( 'money', 10);
  4. });

2、手动控制事务


  
  1. Db::startTrans(); //启动事务
  2. try {
  3. Order::where([ 'id'=> 1])->delete();
  4. User::where( 'id'=> 1)->setInc( 'money', 10);
  5. Db::commit(); //提交事务
  6. } catch ( Exception $e) {
  7. Db::rollback(); //回滚
  8. }

九、model模型的获取器

读取器的命名规范是:->get + 属性名的驼峰命名 + Attr


  
  1. <?php
  2. namespace app\ index\ model;
  3. use think\ Model;
  4. class User extends Model
  5. {
  6. //获取器:将性别的012修改为男、女、未知 返回
  7. public function getSexAttr($val)
  8. {
  9. switch ($val) {
  10. case 1:
  11. return '男';
  12. case 2:
  13. return '女';
  14. default:
  15. return '未知';
  16. }
  17. }
  18. //获取器:格式化时间戳后返回
  19. public function getUpdateTimeAttr($val){
  20. if(! empty($val)){
  21. //如果是时间戳,就格式化
  22. if(!strtotime($val)) {
  23. return date( 'Y-m-d H:i:s',$val);
  24. } else{
  25. return $val;
  26. }
  27. } else{
  28. return '';
  29. }
  30. }
  31. }

补充说明:strtotime()将任何英文文本的日期时间描述解析为Unix 时间戳,成功则返回时间戳,否则返回 FALSE(在 PHP 5.1.0之前本函数在失败时返回 -1)

十、model模型的修改器


  
  1. <?php
  2. namespace app\ index\ model;
  3. use think\ Model;
  4. class User extends Model
  5. {
  6. //修改器
  7. public function setTimeAttr()
  8. {
  9. return time();
  10. }
  11. /** 修改器:对密码字段加密之后存储
  12. * $val 第一个参数是密码
  13. * $data 第二个参数是添加的数据(可选)
  14. */
  15. public function setPasswordAttr($val,$data){
  16. if($val === '') {
  17. return $val;
  18. } else{
  19. return md5($val.$data[ 'email']);
  20. }
  21. }
  22. }

十一、model模型的自动完成

auto       新增及更新的时候,自动完成的属性数组
insert     仅新增的时候,自动完成的属性数组
update   仅更新的时候,自动完成的属性数组

1、自动完成 


  
  1. <?php
  2. namespace app\ index\ model;
  3. use think\ Model;
  4. class User extends Model
  5. {
  6. //添加和修改时,都会自动完成的字段
  7. protected $auto = [ 'addtime'];
  8. public function setAddtimeAttr(){
  9. return time();
  10. }
  11. }

2、添加数据时,自动完成 


  
  1. <?php
  2. namespace app\ index\ model;
  3. use think\ Model;
  4. class User extends Model
  5. {
  6. // 新增 自动完成
  7. protected $insert = [ 'addtime'];
  8. public function setAddtimeAttr(){
  9. return time();
  10. }
  11. }

3、更新数据时,自动完成:


  
  1. <?php
  2. namespace app\ index\ model;
  3. use think\ Model;
  4. class User extends Model
  5. {
  6. // 更新 自动完成
  7. protected $update = [ 'addtime'];
  8. public function setAddtimeAttr(){
  9. return time();
  10. }
  11. }

十二、自动完成时间戳

在数据库配置文件database.php中,有下列这项配置:


  
  1. //自动写入时间戳字段
  2. 'auto_timestamp' => false,
  3. //如果开启(设置为true),则会自动完成所有表的时间戳,但是不建议这样,只在需要的地方设置更安全。

例如对用户表的时间戳自动完成,就在User的model中设置:


  
  1. <?php
  2. namespace app\ index\ model;
  3. use think\ Model;
  4. class User extends Model{
  5. //开启自动完成时间戳功能
  6. protected $autoWriteTimestamp = true;
  7. //开启后,
  8. //添加数据时,默认自动完成的字段是:create_time和update_time
  9. //修改数据时,默认自动完成的字段是:update_time
  10. //如果数据表里不是这两个字段,则会报错。需要进行如下修改:
  11. protected $createTime = 'addtime'; //修改默认的添加时间字段
  12. protected $updateTime = 'updtime'; //修改默认的修改时间字段
  13. protected $updateTime = false; //当不需要这个字段时设置为false
  14. }

Thinkphp更新时,自动更新update_time字段时间戳的方法:

1、使用update


   
  1. User::update([ 'name'=> '安阳'],[ 'id'=> 1]);

Thinkphp中update方法的源代码如下:


   
  1. /**
  2. * 更新数据
  3. * @access public
  4. * @param array $data 数据数组
  5. * @param array $where 更新条件
  6. * @param array|true $field 允许字段
  7. * @return $this
  8. */
  9. public static function update($data = [], $where = [], $field = null)
  10. {
  11. $model = new static();
  12. if (! empty($field)) {
  13. $model->allowField($field);
  14. }
  15. $result = $model->isUpdate( true)->save($data, $where);
  16. return $model;
  17. }

2、使用save


   
  1. $user= new User;
  2. $user->isUpdate( true)->save([ 'name'=> '安阳'],[ 'id'=> 1]);

 

 

十三、软删除

什么是软删除?

当删除某些记录时,有时我们需要假删除,只通过修改某个字段状态来标记该记录已删除,但实际上,数据库中还是存在这些记录的。假删除的应用场景还是比较多的,例如支付宝的收款记录,我们在APP上删除后,就不会再显示出来,你是不是以为真的删掉了,不会再留下任何痕迹?非也,非也,删除支付宝收款记录只是软删除,在支付宝的数据库中,实际上还保留有这些收款记录,如果你的收款涉嫌违规或者触犯法律,警方还是能通过支付宝的网警后台查看到的。

1、开启软删除


  
  1. <?php
  2. namespace app\ index\ model;
  3. use think\ Model;
  4. use traits\ model\ SoftDelete; //引入软删除的类
  5. class Order extends Model{
  6. //使用软删除
  7. //删除时,默认更新的字段是delete_time
  8. use SoftDelete;
  9. //如果数据表里不是delete_time这个字段,则会报错。需要进行如下修改:
  10. protected $deleteTime = 'deltime';
  11. }

2、 控制器里软删除,返回影响的行数

 $res = Order::destroy(1);
    

执行删除后,就会更新delete_time字段,如果update_time字段也开启了自动完成,也会更新update_time字段。

3、如果开启了软删除,需要真正地删除数据,而不做软删除,用下面的方法


  
  1. //destory()第二个参数传递true
  2. $res = Order::destroy( 1, true);
  3. //delete()参数传递true
  4. $orderData = Order::get( 1);
  5. $orderData ->delete( true);

4、查询已软删除的数据

$res = Order::withTrashed(true)->find(1);

5、查询仅包含已软删除的数据

$res = Order::onlyTrashed()->select();

 


转载:https://blog.csdn.net/qq15577969/article/details/113705451
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场