TP5日记(4)

模型(Model)

Posted by Heber on December 29, 2017

命名规范

model的命名规范:一般model的名字和去掉前缀之后的表名是对应的,例如 表名为imooc_user->模型名User.php 表名imooc_user_info->模型名UserInfo.php

使用方法

第一种,使用命名空间,直接使用User::

<?php
namespace app\index\controller;
use think\Controller;
use app\index\model\User;

class Index extends Controller{
    public function index(){
    	$res = User::get(1);
    	return $res;
    }
}

第二种,使用助手函数model来使用模型,无需使用命名空间。

    	$user = model('User');
    	$res = $user::get(3);
    	return $res;

使用模型来查询数据

第一种,我们使用上面用到的User::get()来查询,括号里应该填上某个主键的值来作为条件。也可以使用function作为参数。

取出id=1的数据
    	$res = User::get(1);
    	dump($res);
或者以function作为参数
		$res = User::get(function ($query){
					$query->where("id","eq","1")
						  ->field("id");
			});
		dump($res);

第二种,User::find(),后面可跟链式操作

取出name=heber的数据
    	$res = User::where("name","eq","heber")
    				->field("id,name")
    				->find();
    	return $res;

第三种,User::all(),用法类似User::get(),是它的多输出版。

取出id<6的数据
		$res = User::all(function ($query){
					$query->where("id","LT","6")
						  ->field("id");
			});
		foreach ($res as $key => $value) {
			$res = $value->toarray();
			dump($res);
		}

第四种,User::select(),用法类似User::get(),是它的多输出版。

取出id>5的数据
    	$res = User::where("id",">","5")
    				->field("id,name")
    				->select();
		foreach ($res as $key => $value) {
			$res = $value->toarray();
			dump($res);
		}

第五种,User::value(),会取出单个字段的一行值。

取出name=heberid
    	$res = User::where("name","eq","heber")
    				->value('id');
    	return $res;

第六种,User::column(),会取出多个字段的多行值。

取出id<6name,且以id作为下标
    	$res = User::where("id","LT","6")
    				->column('name','id');
			dump($res);
		}

使用模型来插入数据

第一种,User::create()

imooc_user表里插入数据
    	$res = User::create([
    		'name' => 'test',
    		'num' => 1,
    	]);
    	dump($res->name);
如果此时插入了一个表中不存在的字段,则需将User::create()的第二个参数设为true,否则会报错,提示字段不存在。
    	$res = User::create([
    		'name' => 'test',
    		'num' => 1,
    		'age' => 18,
    	],true);
    	dump($res->name);
如果想要控制插入的字段有哪些,则需将User::create()的第二个参数设为一个数组,数组中包含想要插入数据库的字段。
    	$res = User::create([
    		'name' => 'test',
    		'num' => 1,
    		'age' => 18,
    	],['name']);
    	dump($res->name);

第二种,save(),还有,它的第二个参数可以是主键,这样就可用于更新数据库。

它需要先实例化对象,才能使用
    	$UserObj = new User;
    	$res = $UserObj->save([
    		'name' => 'test',
    		'num' => 1,
    	]);
    	dump($res);
如果有某些字段表中不存在,则使用fieldAllow方法。同样可使用‘true’和数组。
    	$UserObj = new User;
    	$res = $UserObj->allowField(true)->save([
    		'name' => 'test',
    		'num' => 1,
    		'age' => 18,
    	]);
    	dump($res);

第三种,saveAll()方法,插入多条数据,参数为二维数组。若数组中有已经存在的主键,则也可用于更新数据。

如果有某些字段表中不存在,则使用fieldAllow方法。同样可使用‘true’和数组。
    	$UserObj = new User;
    	$res = $UserObj->saveAll([
    		['name' => 'test','num' => '3'],
    		['name' => 'value','num' => '1'],
    		['name' => 'kitch','num' => '4'],
    	]);
    	dump($res);

使用模型来更新数据

第一种,User::update(),如果更新的参数里有主键,则无需额外输入条件,如果没有,则需在第二个参数填入条件,条件可以是数组,也可以是function($query){},也可以使用where来传递条件。

imooc_user表里更新数据
    	$res = User::update([
    		'id' => '5',
    		'name' => 'test',
    		'num' => 1,
    	]);
    	dump($res);
imooc_user表里更新数据
    	$res = User::update([
    		'name' => 'test',
    		'num' => 1,
    	],'id' => '5');
    	dump($res);
imooc_user表里更新数据
    	$res = User::update([
    		'name' => 'test',
    		'num' => 1,
    	],function($query){
    		   $query->where('id','GT','5');
    	});
    	dump($res);
imooc_user表里更新数据
    	$res = User::where('id','GT','5')
    				->update([
							'name' => 'test',
    						'num' => 1,
    					]);
    	dump($res);

使用模型来删除数据

第一种,User::destroy(),条件可以是主键的值或者数组,也可以是function($query){}。

删除id=1的数据
    	$res = User::destroy(1);
    	dump($res);
删除id=1的数据
    	$res = User::destroy(['id' => '1']);
    	dump($res);
删除id<5的数据
    	$res = User::destroy(function($query){
    			$query->where('id','LT','5');
    		});
    	dump($res);

第二种,实例化User对象,然后使用delete()

删除id=9的数据
		$userModel = User::get(9);
    	$res = $userModel->delete();
    	dump($res);

第三种,搭配where使用delete

删除id<13的数据
    	$res = User::where('id','LT','13')
    			->delete();
    	dump($res);

模型聚合操作

最大值 User::max(); 最小值 User::min(); 和 User::sum(); 平均值 User::avg(); 计数 User::count(); 都可以搭配where使用

模型获取器

假设我们在数据库中存有字段sex,它的取值是0,1,2,其中0代表未知,1代表男,2代表女,如果我们想在输出的时候输出’男’‘女’‘未知’,则需要进行一次转换。在User.php中写入一个函数,函数名为get+字段名+Attr。这样,在控制器中输出sex时,会自动转化为汉字。它有第二个参数$data,用来接收进行操作时的所有数据,自行查手册。

public function getSexAttr($val){
	switch ($val){
		case '1':
			return "男";
			break;
		case '2':
			return "女";
			break;
		case '0':
			return "未知";
			break;
	}
}

模型修改器

假设我们要往数据库存入经过MD5加密的密码,但是我们又不想每次都要输入md5操作,那么我们可以再模型文件User.php中新建方法,方法名为set+字段名+Attr

	public function setPasswordAttr($val){
		return md5($val);
	}

自动完成

假设我们想要每次更新或者插入时自动插入某些字段(例如时间之类的),则可以使用自动完成,同样在User.php这个模型文件中使用

<?php
namespace app\index\model;
use think\Model;

class User extends Model{
	对插入和更新都有效,time为表中希望自动插入的字段名,以下同理
	protected $auto = ['time'];
	只在插入操作时触发
	protected $insert = ['time_insert'];
	只在更新操作时触发
	protected $update = ['time_update'];

	public function getSexAttr($val){
		switch ($val){
			case '1':
				return "男";
				break;
			case '2':
				return "女";
				break;
			case '0':
				return "未知";
				break;
		}
	}

	public function setPasswordAttr($val){
		return md5($val);
	}

	public function setTimeAttr($val){
		return time();
	}

	public function setTimeInsertAttr($val){
		return time();
	}

	public function setTimeUpdateAttr($val){
		return time();
	}
}

模型时间戳

当表中有create_time和update_time时,可以使用自动插入来节约时间。 第一种方法,可以再config文件中打开自动添加时间戳的方法。但我们通常不使用,因为配置文件不灵活。 第二种方法,在模型文件User.php中使用下列代码

<?php
namespace app\index\model;
use think\Model;

class User extends Model{
	protected $autoWriteTimestamp = true;
}

此时如果往数据表插入或更新数据,就会对表中的create_time和update_time自动插入当前Unix时间戳。如果你希望表中的字段名为其他,则使用下列代码,则会往create_in和update_in插入。

<?php
namespace app\index\model;
use think\Model;

class User extends Model{
	protected $autoWriteTimestamp = true;
	protected $createTime = "create_in";
	protected $updateTime = "update_in";
}

如果想关闭其中一个,则可令其值为false

<?php
namespace app\index\model;
use think\Model;

class User extends Model{
	protected $autoWriteTimestamp = true;
	protected $createTime = false;
	protected $updateTime = "update_in";
}

软删除

即对数据表内容的一种特殊删除方式,如果你对电脑有点了解的话,会知道电脑的删除是”假“的,它只是把你想删除的文件标记为删除,如果有新文件进来的话,可以直接覆盖在已被标记为删除状态的文件的磁盘位置。这也算为什么我们能使用文件找回的原因。软删除也是这个道理,如果你开启了软删除,在删除某条数据时,数据库会修改条数据的某个字段(默认是delete_time,也可以改变,参考上面),这样,你虽然能看到这条数据的存在,但是常规方法取不出来,看下面代码

这是User.php文件的内容
<?php
namespace app\index\model;
use think\Model;
use SoftDelete;

class User extends Model{
	protected $autoWriteTimestamp = true;
	protected $createTime = false;
	protected $updateTime = "update_in";
}

如果你确实想取出已经被删除的数据,可以再通常的查询方法前加上withTrashed,这样就可以取到已被软删除的数据了

$res = User::withTrashed(true)->get();

还可以使用onlyTrashed来只取出已被软删除的数据,多条需要使用selec()

$res = User::onlyTrashed(true)->select();

那如果我们在开启了软删除的情况下想进行真正的删除时,也需要特殊的方式。注意,已经被软删除的数据不能直接被真正删除。

$res = User::destroy(1,true);