十二、表达式查询
- 表达式是
SQL
语句的条件 - 表达式不分大小写
- 表达式写在
where
里中间参数
表达式 | 含义 | 查询方法 |
---|---|---|
= | 等于 | |
<> | 不等于 | |
> | 大于 | |
>= | 大于等于 | |
< | 小于 | |
<= | 小于等于 | |
[not] like | 模糊查询 | whereLike /whereNotLike |
[not] between | (不在)区间查询 | whereBetween /whereNotBetween |
[not] in | (不在)IN 查询 | whereIn /whereNotIn |
[not] null | 查询字段是否(不)是 NULL | whereNull /whereNotNull |
高级查询:https://www.kancloud.cn/manual/thinkphp6_0/1037566
1、表达式查询
where
方法在链式操作方法里面是最常用的方法,可以完成包括普通查询、表达式查询、快捷查询、区间查询、组合查询在内的条件查询操作
# 等于(=) 默认不写就是等于
// 查询status等于1的博客文章
// $select = Db::table('boke')->where('status',1)->select();
$select = Db::table('boke')->where('status','=',1)->select();
print_r($select);
# 不等于(<>)
// 先将id为6的文章status改为0
Db::name('boke')->save(['id'=>6,'status'=>0]);
// 查询status不等于1的文章列表
$select = Db::name('boke')
->where('status','<>',1)
->select();
echo "<pre>";
print_r($select);
# 大于(>)
// 查询id大于8的文章列表
$select = Db::table('boke')->where('id','>','8')->select();
print_r($select);
# 大于等于(>=)
$select = Db::table('boke')->where('id','>=','3')->select();
print_r($select);
# 小于(<)
$select = Db::table('boke')->where('id','<','5')->select();
print_r($select);
# 小于等于(<=)
$select = Db::table('boke')->where('id','<=','5')->select();
print_r($select);
# 多where条件
// id大于3且小于6的记录 4 5
$select = Db::table('boke')
->where('id','>','3')
->where('id','<','6')
->select();
print_r($select);
# LIKE 模糊查询 %代表一个或多个字符 *代表一个字符
// 查询标题中含有‘课程’的记录
$select = Db::table('boke')->where('title','like','%课程%')->select();
print_r($select);
# NOT LIKE 不包含玉女心经的记录
$select = Db::table('boke')->where('title','not like','%玉女心经%')->select();
print_r($select);
# BETWEEN 在~之间的记录
// 查询id为6到10的记录
$select = Db::table('boke')->where('id','between','6,10')->select();
print_r($select);
# NOT BETWEEN 不在~之间的记录
// 查询id为6到10以外的所有记录
$select = Db::table('boke')->where('id','not between',[6,10])->select();
print_r($select);
# IN 查询id为6,7,10的记录
$select = Db::table('boke')->where('id','in','4,7,10')->select();
print_r($select);
# NOT IN 查询id不为为6,7,10的所有记录
$select = Db::table('boke')->where('id','not in',[4,7,10])->select();
print_r($select);
# NULL 注意:空字符不为null
$select = Db::table('boke')->where('img',null)->select();
print_r($select);
# NOT NULL
$select = Db::table('boke')->where('img','not null')->select();
print_r($select);
2、快捷查询方法
功能和上述表达式查询一致,只是将其中查询表达式换成了对应的查询关键字
# LIKE
$select = Db::table('boke')->whereLike('title','%玉女心经%')->select();
print_r($select);
# NOT LIKE
$select = Db::table('boke')->whereNotLike('title','%玉女心经%')->select();
print_r($select);
# BETWEEN
$select = Db::table('boke')->whereBetween('id','6,10')->select();
print_r($select);
# NOT BETWEEN
$select = Db::table('boke')->whereNotBetween('id',[6,10])->select();
print_r($select);
# IN
$select = Db::table('boke')->whereIn('id',[6,10])->select();
print_r($select);
# NOT IN
$select = Db::table('boke')->whereNotIn('id',[6,10])->select();
print_r($select);
# NULL
$select = Db::table('boke')->whereNull('img')->select();
print_r($select);
# NOT NULL
$select = Db::table('boke')->whereNotNull('img')->select();
print_r($select);
十三、whereOr
// whereOr 两个条件满足其中一个即可
// 查询id=7或6的记录,这两条记录都会被查询出来
$select = Db::table('boke')->where('id','=',7)->whereOr('id','=',6)->select();
print_r($select);
// id<3或id>13
$select = Db::table('boke')->where('id','<',3)->whereOr('id','>',13)->select();
print_r($select);
// id<3或num>100
$select = Db::table('boke')->where('id','not in',[4,7,10])->whereOr('num','>',100)->select();
print_r($select);
// id>13或标题中包含玉女心经
$select = Db::table('boke')->where('id','>',13)->whereOr('title','like','%玉女心经%')->select();
print_r($select);
十四、数组条件
// and 都要满足
// id小于7并且cat为2
$select = Db::table('boke')->where([
['id','<',7],
['cat','in',[2,4]]
])->select();
print_r($select);
// or 满足其一即可
$select = Db::table('boke')->whereOr([
['id','<',7],
['id','>',13]
])->select();
print_r($select);
十五、聚合查询
- 聚合方法查询后:没有数据,返回 0,聚合查询可以配合查询条件
方法 | 功能 |
---|---|
count | 统计数量,参数是要统计的字段名(可选) |
max | 获取最大值,参数是要统计的字段名(必须) |
min | 获取最小值,参数是要统计的字段名(必须) |
avg | 获取平均值,参数是要统计的字段名(必须) |
sum | 获取总数,参数是要统计的字段名(必须) |
// 统计数量,参数是要统计的字段名(可选)
$select = Db::table('boke')->count();
print_r($select);
// 获取最大值,参数是要统计的字段名(必须)
$select = Db::table('boke')->max('num');
print_r($select);
// 获取最小值,参数是要统计的字段名(必须)
$select = Db::table('boke')->min('num');
print_r($select);
// 获取平均值,参数是要统计的字段名(必须)
$select = Db::table('boke')->avg('num');
print_r($select);
// 获取总数,参数是要统计的字段名(必须)
$select = Db::table('boke')->sum('num');
print_r($select);
十六、博客实战
namespace app\controller;
use app\BaseController;
use think\facade\Db;
use think\facade\View;
use think\facade\Request;
class Index extends BaseController
{
public function index(){
$cat = Db::table('cat')->select();
$p = input('get.p',1);
$c = input('get.c',0);
$t = input('get.t','');
/*if($c != 0){
$count = Db::table('boke')
->where('status',1)->where('cat',$c)
->count();
$select = Db::table('boke')
->where('status',1)->where('cat',$c)
->page($p,$num)->order('date desc')
->select()->toArray();
}else if(!empty($t)){
$count = Db::table('boke')
->where('status',1)->where('title',$t)
->count();
$select = Db::table('boke')
->where('status',1)->where('title','like','%'.$t.'%')
->page($p,$num)->order('date desc')
->select()->toArray();
}else{
$count = Db::table('boke')
->where('status',1)->count();
$select = Db::table('boke')
->where('status',1)->page($p,$num)
->order('date desc')->select()->toArray();
}*/
// 利用数组条件简化之前的三次重复查询操作
$where[] = ['status','=',1];
if($c != 0){
$where[] = ['cat','=',$c];
}else if(!empty($t)){
$where[] = ['title','like','%'.$t.'%'];
}
/*$where = [
['status','=',1],
['cat','=',$c],
['title','like','%'.$t.'%']
];*/
$count = Db::table('boke')->where($where)->count();
$select = Db::table('boke')->where($where)
->page($p,10)->order('date desc')
->select()->toArray();
View::assign([
'p' => $p,
'c' => $c,
't' => $t,
'cat' => $cat,
'select' => $select,
'count' => ceil($count/10)
]);
return View::fetch('index');
}
}
十七、其他链式操作
https://www.kancloud.cn/manual/thinkphp6_0/1037538
连贯操作 | 作用 | 支持的参数类型 |
---|---|---|
alias | 用于给当前数据表定义别名 | 字符串 |
strict | 用于设置是否严格检测字段名是否存在 | 布尔值 |
group | 用于对查询的 group 支持 | 字符串 |
having | 用于对查询的 having 支持 | 字符串 |
join* |
用于对查询的 join 支持 | 字符串和数组 |
union* |
用于对查询的 union 支持 | 字符串、数组和对象 |
distinct | 用于查询的 distinct 支持 | 布尔值 |
lock | 用于数据库的锁机制 | 布尔值 |
cache | 用于查询缓存 | 支持多个参数 |
comment | 用于 SQL 注释 | 字符串 |
force | 用于数据集的强制索引 | 字符串 |
partition | 用于设置分区信息 | 数组 字符串 |
failException | 用于设置没有查询到数据是否抛出异常 | 布尔值 |
sequence | 用于设置自增序列名 | 字符串 |
replace | 用于设置使用 REPLACE 方式写入 | 布尔值 |
extra | 用于设置额外查询规则 | 字符串 |
duplicate | 用于设置 DUPLCATE 信息 | 数组 字符串 |
procedure | 用于设置当前查询是否为存储过程查询 | 布尔值 |
master | 用于设置主服务器读取数据 | 布尔值 |
view* |
用于视图查询 | 字符串、数组 |
join连表查询 文章表和分类表
// 主要select返回的是对象,需要转换为数组才可以修改
$select = Db::table('boke')
->where('status',1)
->order('date desc')
->select()
->toArray();
// 根据文章表中的分类id查询出分类名称
foreach ($select as &$value) {
$catname = Db::table('cat')
->field('name')
->where('id',$value['cat'])
->find();
$value['catname'] = $catname['name'];
}
$select = Db::table('boke a')
->where('a.status','=',1)
->field('a.*,c.name')
->join(['cat'=>'c'],'a.cat=c.id')
->select();
print_r($select);
$select = Db::table('boke')
->alias('a')
->field('a.*,c.name catname')
->where('a.status','=',1)
->order('a.id desc')
->join(['cat'=>'c'],'a.cat=c.id')
->select();
print_r($select);
十八、原生 MySQL
执行
Db
类支持原生SQL
查询操作,主要包括下面两个方法:
https://www.kancloud.cn/manual/thinkphp6_0/1037570
query
方法:查询
$select = Db::query("select * from boke");
print_r($select);
$select = Db::query('SELECT * FROM boke WHERE `id` < 5 and `id`>=3');
print_r($select);
// 参数绑定
$select = Db::query('SELECT * FROM boke WHERE `id` < :id', ['id' => 5]);
print_r($select);
Db::query("select * from boke where id=? AND status=?", [8, 1]);
// 命名绑定
Db::execute("update boke set title=:title where id=:id", ['title' => 'thinkphp', 'id' => 1]);
execute
方法:添加和修改
$execute = Db::execute("INSERT INTO `cat` (`id`, `name`, `sort`, `status`) VALUES (null, 'Vue', '0', '1');");
print_r($execute);
$execute = Db::execute("updata `boke` set status where id=1");
getLastsql
调试执行的SQL
语句
$select = Db::table('boke')->field('id,title')->where('status',1)->order('id desc')->select();
print_r($select);
// 打印上一次执行的SQL语句
echo Db::getLastSql();
// SELECT `id`,`title` FROM `boke` WHERE `status` = 1 ORDER BY `id` DESC
fetchSql
调试执行的SQL
语句,而不执行
$select = Db::table('boke')->fetchSql()->field('id,title')->where('status',1)->order('id desc')->select();
// 不执行,直接输入SQL原生语句
echo $select;
// SELECT `id`,`title` FROM `boke` WHERE `status` = 1 ORDER BY `id` DESC
十九、数据集
只有find单条查询返回的是数组,其余select查询均返回对象,可以通过结果集进一步操作,我们如果要修改查询出的数据,需要通过toArray()转换为数组才可以修改,其余操作无需转换也可以当做数组循环渲染。
编号 | 方法 | 描述 |
---|---|---|
1 | isEmpty | 是否为空 |
2 | toArray | 转换为数组 |
3 | all | 所有数据 |
4 | merge | 合并其它数据 |
5 | diff | 比较数组,返回差集 |
6 | flip | 交换数据中的键和值 |
7 | intersect | 比较数组,返回交集 |
8 | keys | 返回数据中的所有键名 |
9 | pop | 删除数据中的最后一个元素 |
10 | shift | 删除数据中的第一个元素 |
11 | unshift | 在数据开头插入一个元素 |
12 | push | 在结尾插入一个元素 |
13 | reduce | 通过使用用户自定义函数,以字符串返回数组 |
14 | reverse | 数据倒序重排 |
15 | chunk | 数据分隔为多个数据块 |
16 | each | 给数据的每个元素执行回调 |
17 | filter | 用回调函数过滤数据中的元素 |
18 | column | 返回数据中的指定列 |
19 | sort | 对数据排序 |
20 | order | 指定字段排序 |
21 | shuffle | 将数据打乱 |
22 | slice | 截取数据中的一部分 |
23 | map | 用回调函数处理数组中的元素 |
24 | where | 根据字段条件过滤数组中的元素 |
25 | whereLike | Like 查询过滤元素 |
26 | whereNotLike | Not Like 过滤元素 |
27 | whereIn | IN 查询过滤数组中的元素 |
28 | whereNotIn | Not IN 查询过滤数组中的元素 |
29 | whereBetween | Between 查询过滤数组中的元素 |
30 | whereNotBetween | Not Between 查询过滤数组中的元素 |
$select = Db::table('boke')->where('id','>=',13)->select()->toArray();
print_r($select);
$select = Db::table('boke')->where('id','>=',100)->select();
// 原生的empty只能判断数组,不转换数组的话,空对象无法用这个判断。
// 未查询出数据,空对象中有一个空数组
if(empty($select)){
echo '未查询到数据';
}else{
echo '查询到数据';
}
if($select->isEmpty()){
echo '未查询到数据';
}else{
print_r($select->toArray());
}
// 将取出的数据进行打乱 比如随机文章
print_r($select->shuffle()->toArray());
二十、事务操作
为什么要有事务呢,举个例子来说,你的账户有 100 元,现在想给朋友转账 100 元。其中就会包含两个很重要的操作,你的账户减 100 元,朋友账户多 100 元。由于转账过程中出现失败是很常见的,假设操作不包含在事务内,你的账户减钱操作成功,朋友账户加钱操作失败。就会出现,你的账户扣钱,对方没有收到钱的情况。
再比如,在发起转账操作时,由于系统需要进行像查询余额,计算,更新余额的操作,如果在等待时间内,又发起了转账操作,但目前更新余额的操作还没有成功,就会出现你的 100 元,可以给别人转账多次的情况,这对于银行来说是肯定不允许的。
简单的来说,事务就是允许有反悔的机会,一旦某个环节出现错误,可以恢复原始的状态。
对于一个事务来说通常要满足四个特性,也就是通常所说的 ACID:
- Atomicity - 保证在一个工作单元(就是一组操作)中所有的操作都执行成功,否则的话当前这个事务就会失败,之前的操作都被会回滚。
- Consistency - 保证一个事务被成功提交后,数据库的状态是从一致性状态变成另一个一致性状态。比如 A 给 B 转 100 元,只会出现 A 账户减 100,B 账户加 100 或者转账失败的情况,不会出现其他的状态。
- Isolation - 保证每个事务中的操作时是独立的,对于其他事务没有影响。
- Durability - 对于已经提交的事务,即使在数据库损坏的情况下,也不会造成数据的丢失和损坏。
更多介绍:https://www.cnblogs.com/michael9/p/11958199.html
- 开启事务(start transaction)
- 执行sql操作(普通sql操作)
- 提交/回滚(commit/rollback)
- 设置保存点 savepoint 保存点名称
回滚到具体的保存点 rollback to 保存点名称
InnoDB
引擎支持事务处理,MyISAM
不支持事务处理
// 启动事务 (如果下面的代码出错了,就返回到这里。)
Db::startTrans();
// 插入分类表。
$id = Db::table('cat')->insertGetId(['name'=>'Bootstrap']);
if(empty($id)){
// 回滚事务,如果失败,就返回原点,返回原点的方法:rollback
Db::rollback();
}
echo $id;
// 由于id已经存在插入数据会失败
// 所以前面的插入的分类数据也不会被插入
$boke = Db::table('boke')->insert([
'id' => 1,
'title' => '插入失败',
'img' => '',
'content' => '',
]);
if(empty($boke)){
// 回滚事务,如果失败,就返回原点,返回原点的方法:rollback
Db::rollback();
}
// 都成功了。那就没问题了。
// 必须提交事务:commit
// 提交事务
Db::commit();
transaction
方法操作数据库事务,当闭包中的代码发生异常会自动回滚
Db::transaction(function () {
$id = Db::table('cat')->insertGetId(['name'=>'Bootstrap']);
echo $id;
$boke = Db::table('boke')->insert([
'title' => '',
'img' => '',
'content' => '',
'date' => '212'
]);
echo $boke;
});
二十一、模版分页
https://www.kancloud.cn/manual/thinkphp6_0/1037638
https://my.oschina.net/u/3470006/blog/3112782
paginate
内置了分页实现,要给数据添加分页输出功能变得非常简单raw
不使用(默认)转义render
获取分页显示total
获取总数量
namespace app\controller;
use app\BaseController;
use think\facade\Db;
use think\facade\View;
use think\facade\Request;
class Index extends BaseController
{
public function index(){
$cat = Db::table('cat')->select();
$c = input('get.c',0);
$t = input('get.t','');
$where[] = ['status','=',1];
if($c != 0){
$where[] = ['cat','=',$c];
}else if(!empty($t)){
$where[] = ['title','like','%'.$t.'%'];
}
$select = Db::table('boke')->where($where)->paginate(10);
$page = $select->render();
$total = $select->total();
View::assign([
'c' => $c,
't' => $t,
'cat' => $cat,
'select' => $select,
'page' => $page
]);
return View::fetch('index');
}
}
view 视图
// 这两种方式都可以渲染分页列表
// 第一种是用模版函数直接渲染传递过来的数据 {$select|raw}
// 第二种是控制器中通过render方法获取的分页html代码 $page = $select->render();
<ul class="pagination">
{$select|raw}
{$page|raw}
</ul>
编号 | 方法 | 描述 |
---|---|---|
1 | list_rows | 是否为空 |
2 | page | 当前页 |
2 | path | url 路径 |
2 | query | url 额外参数 |
2 | fragment | url 锚点 |
2 | var_page | 分页变量 |
<?php
namespace app\controller;
use app\BaseController;
use think\facade\View;
use think\facade\App;
use think\facade\Db;
class Index extends BaseController
{
public function index()
{
// 获取分类ID
$c = input('get.c',0);
// 获取搜索内容
$t = input('get.t',null);
// 每页显示条数
$num = 6;
// 查询出分类列表
$cat = Db::name('cat')->where('status',1)->order('sort desc')->select();
// 查询前四条热门文章列表
$hot = Db::table('boke')->field('id,title')->limit(4)->order('num','asc')->select();
$where[] = ['a.status','=',1];
if($c != 0){
$where[] = ['a.cat','=',$c];
}else if(!empty($t)){
$where[] = ['a.title','like','%'.$t.'%'];
}
$count = Db::table('boke a')->where($where)->count();
$select = Db::table('boke a')
->field('a.*,c.name catname')
->where($where)
->order('a.date desc')
->join(['cat'=>'c'],'a.cat=c.id')
->paginate([
'list_rows' => $num,
'query' => request()->param()
// 'query' => [
// 'c' => $c,
// 't' => $t,
// 'page' => input('get.page')
// ]
]);
View::assign([
'c' => $c,
't' => $t,
'cat' => $cat,
'select' => $select,
'hot' => $hot
]);
return View::fetch('index');
}
}
<div class="page">
<nav>
<ul class="pagination">
{$select|raw}
</ul>
</nav>
</div>
二十二、模型Model
- 请确保你已经在数据库配置文件中配置了数据库连接信息
- 模型会自动对应数据表,模型类的命名规则是除去表前缀的数据表名称,采用驼峰法命名,并且*首字母大写
- 模型自动对应的数据表名称都是遵循小写+下划线规范,如果你的表名有大写的情况,必须通过设置模型的 table 属性。
1、创建模型
模型名 | 数据库前缀 |
---|---|
Boke | zs_boke |
Cat | zs_cat |
BokeComment | zs_boke_comment |
CREATE TABLE `zs_boke_comment` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '评论ID',
`boke_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '博客id',
`comment` text NOT NULL COMMENT '评论',
`add_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '时间',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
表前缀设置:config/database.php
文件里 prefix
为zs_
表前缀
- 第一步:创建一个跟控制器平级的目录,目录名:
model
第二步:在
model
创建Boke.php
文件创建
model
文件:app/Model/Boke.php
namespace app\model;
use think\Model;
class Boke extends Model{
public function get_data(){
// Db::table('zs_boke')===Db::name('boke')===Boke::===static::
$select = Boke::where('id','<',7)->select();
return $select;
}
}
// 如果不设置表前缀配置,需要驼峰命名模型名称
/*class ZsBoke extends Model{
public function get_data(){
// Db::table('zs_boke')===ZsBoke::===static::
$select = ZsBoke::->select(6);
return $select;
}
}*/
2、controller
调用 model
namespace app\controller;
use app\model\Boke;
class Index{
public function index(){
$db = new Boke();
$index = $db->get_data();
print_r($index);
}
}
3、model
调用 model
- 创建
model
文件:app/Model/Cat.php
namespace app\model;
use think\Model;
class Cat extends Model{
public function get_data(){
$select = Cat::select();
return $select->toArray();
}
}
namespace app\model;
use think\Model;
use app\model\Cat;
class Boke extends Model{
public function get_data(){
$cat = new Cat();
$select = $cat->get_data();
return $select;
}
}
4、模型操作
https://www.kancloud.cn/manual/thinkphp6_0/1037585
在模型中除了可以调用数据库类的方法之外(换句话说,数据库的所有查询构造器方法模型中都可以支持),可以定义自己的方法,所以也可以把模型看成是数据库的增强版
- 模型文件里的自定义方法,不要和 thinkphp 方法一样名称
- 模型里的
Boke::
也可以用static::
关键词 - 链式操作,都可以在模型里使用
1、find
查询数据
find 获取单条数据,返回的是当前模型的对象实例
namespace app\model;
use think\Model;
class Cat extends Model{
public function find(){
$find = Cat::find(2);
$find = static::where('id',2)->find();
return $find;
}
}
2、select
查询数据
select 获取多条数据,返回的是当前模型的对象实例
public function select(){
$select = Boke::select();
$select = Boke::select(6);
$select = static::where('id','<',7)->select();
return $select;
}
4、数据转换
toArray
方法将当前的模型实例输出为数组
public function select(){
$select = Boke::select();
$select = static::select(6);
$select = static::where('id','<',7)->select();
return $select->toArray();
}
5、增加数据
create
静态方法添加数据,返回的是当前模型的对象实例
public function create(){
$create = Cat::create([
'name' => 'bootstrap',
'sort' => 0,
'status' => 1
]);
echo $create->id; // 可以直接获取自增id
return $create;
}
新增数据的最佳实践原则:使用create方法新增数据,使用saveAll批量新增数据。
6、修改数据
update
静态方法修改数据,返回的是当前模型的对象实例save
在取出数据后,更改字段更新数据。这种方式是最佳的更新方式
namespace app\model;
use think\Model;
class Cat extends Model{
public function update(){
# 更新方式1
$update = Cat::update(
['name'=>'响应式'],
['id'=>7]
);
return $update;
# 更新方式2
$user = Cat::find(7);
$user->name = '响应式';
$save = $user->save();
return $save;
}
}
7、删除数据
delete
静态方法删除数据,返回的是当前模型的对象实例destroy
根据主键删除
public function delete(){
# 删除方法1
$delete = Cat::where('id',3)->delete();
# 删除方法2
$delete = Cat::destroy(4);
return $delete;
}
TP模型如果只能增删查改,不如在 Controller
执行了。TP模型很多特点,下面为介绍模型设置
二十三、模型设置
- 为了和数据库更好的适配,模型可以提前设置对应的数据库属性,一个文件配置一个数据表
- https://www.kancloud.cn/manual/thinkphp6_0/1037580
属性 | 描述 |
---|---|
name | 模型名(相当于不带数据表前后缀的表名,默认为当前模型类名) |
table | 数据表名(默认自动获取) |
pk | 主键名(默认为 id ) |
schema | 模型对应数据表字段及类型 |
type | 模型需要自动转换的字段及类型 |
disuse | 数据表废弃字段(数组) |
1、name
和table
- 当你的数据表没有前缀的时候,name 和 table 属性的定义是没有区别的,定义任何一个即可
namespace app\model;
use think\Model;
class Boke extends Model{
protected $name = 'Boke';
protected $table = 'zs_boke';
// 默认当前模型查询的是类名称对应的表
// 也可以通过name指定其他表
protected $name = 'Cat';
protected $table = 'zs_cat';
public function get_data(){
$select = Boke::select();
return $select->toArray();
}
}
2、pk
改变主键名称
默认主键为
id
,如果你没有使用id
作为主键名,需要在模型中设置属性:更改
id
字段名为bid
namespace app\model;
use think\Model;
class Boke extends Model{
protected $name = 'Boke';
protected $pk = 'bid';
public function get_data($id=1){
$find = Boke::find($id);
return $find->toArray();
}
}
3、schema
设置模型对应数据表字段及类型
模型字段:https://www.kancloud.cn/manual/thinkphp6_0/1037581
- 默认会自动获取(包括字段类型),但自动获取会导致增加一次查询
schema
属性一旦定义,就必须定义完整的数据表字段类型- 类型根据 php 数据类型定义,如果是 json 类型直接定义为 json 即可
namespace app\model;
use think\Model;
class Boke extends Model{
protected $name = 'Boke';
protected $pk = 'bid';
protected $schema = [
'bid' => 'int',
'title' => 'string',
'img' => 'string',
'content' => 'string',
'date' => 'date',
'cat' => 'int',
'num' => 'int',
'hot' => 'int',
'status' => 'int'
];
# 对某个字段定义需要自动转换的类型,可以使用type属性
protected $type = [
'date' => 'int'
];
public function get_data(){
$select = Boke::select();
return $select->toArray();
}
}
4、disuse
数据表废弃字段(数组)
如果因为历史遗留问题 ,你的数据表存在很多的废弃字段,你可以在模型里面定义这些不再使用的字段。
namespace app\model;
use think\Model;
class Boke extends Model{
protected $name = 'Boke';
protected $pk = 'bid';
protected $schema = [
'bid' => 'int',
'title' => 'string',
'img' => 'string',
'content' => 'string',
'date' => 'date',
'cat' => 'int',
'num' => 'int'
];
// 统一设置不需要查询的字段名称,后续所有操作将忽略其中字段
protected $disuse = [
'hot',
'status'
];
public function get_data(){
$select = Boke::select();
return $select->toArray();
}
}
在查询和写入的时候会忽略定义的status
和hot
废弃字段。
5、其他属性(不常用)
属性 | 描述 |
---|---|
suffix | 数据表后缀(默认为空) |
connection | 数据库连接(默认读取数据库配置) |
query | 模型使用的查询类名称 |
field | 模型允许写入的字段列表(数组) |
strict | 是否严格区分字段大小写(默认为 true ) |
readonly | 字段只读 |
json | 设置字段为 JSON 数据 |
jsonType | 设置 JSON 字段的类型 |
jsonAssoc | 设置 JSON 数据返回数组 |
autoWriteTimestamp | 自动写入创建和更新的时间戳字段(默认关闭) |
createTime | 创建时间戳字段 |
updateTime | 更新时间戳字段 |
deleteTime | 用于定义你的软删除标记字段 |
defaultSoftDelete | 定义软删除字段的默认值 |
二十四、模型功能
1、获取器
- 获取器的作用是对模型实例的(原始)数据做出自动处理
- 命名规则:
get
+ 字段名 +Attr
- 字段名是数据表字段的驼峰转换
namespace app\model;
use think\Model;
class Boke extends Model{
protected $name = 'Boke';
protected $pk = 'bid';
protected $schema = [
'bid' => 'int',
'title' => 'string',
'img' => 'string',
'content' => 'string',
'date' => 'date',
'cat' => 'int',
'num' => 'int',
'hot' => 'int',
'status' => 'int'
];
public function get_data(){
$select = Boke::select();
return $select->toArray();
}
public function getStatusAttr($v){
// echo $v; Status字段的内容
$status = [
1=>'开启',
0=>'关闭'
];
return $status[$v];
}
public function getHotAttr($v){
$hot = [
1=>'热门',
0=>'非热门'
];
return $hot[$v];
}
}
对查询出的数据统一处理
2、修改器
- 修改器的主要作用是对模型设置的数据对象值进行处理
- 命名规则:
set
+ 字段名 +Attr
namespace app\model;
use think\Model;
class Boke extends Model{
protected $name = 'Boke';
protected $pk = 'bid';
protected $schema = [
'bid' => 'int',
'title' => 'string',
'img' => 'string',
'content' => 'string',
'date' => 'date',
'cat' => 'int',
'num' => 'int',
'hot' => 'int',
'status' => 'int'
];
public function get_data(){
$select = Boke::select();
return $select->toArray();
}
public function getStatusAttr($v){
// echo $v; Status字段的内容
$status = [
1=>'开启',
0=>'关闭'
];
return $status[$v];
}
public function getHotAttr($v){
$hot = [
1=>'热门',
0=>'非热门'
];
return $hot[$v];
}
// 添加的时候
public function add_data($data=[]){
$data = [
'title' => '新文章',
'img' => '',
'content' => '',
'date' => '2021-06-01',
'cat' => 2,
'num' => 0,
'hot' => 0,
'status' => 1
];
$create = Boke::create($data);
return $create;
}
// 修改的时候
public function edit_data(){
$boke = Boke::find(16);
$boke['title'] = '新修改';
$update = $boke->save();
// $update = Boke::where(['bid'=>16])->update(['title'=>'新修改']);
return $update;
}
// 添加和修改的时候,对其标题字段内容统一处理
public function setTitleAttr($v,$all){
// $all 全部参数
// serialize产生一个可存储的值的表示 s:9:"新文章";
return serialize($v);
// 插入和修改标题的时候,将其内容转换为整型
return (int)$v;
// 将标题在前面加上前缀
return '前缀'.$v;
}
}
对插入或修改的数据进行统一格式化处理,检测插入的字段数据是否符合标准等操作。
3、搜索器
- 搜索器的作用是用于封装字段(或者搜索标识)的查询条件表达式
- 命名规则:
search
+ 字段名 +Attr
- 搜索器仅在调用
withSearch
方法的时候触发
namespace app\model;
use think\Model;
class Boke extends Model{
protected $name = 'Boke';
protected $pk = 'bid';
protected $schema = [
'bid' => 'int',
'title' => 'string',
'img' => 'string',
'content' => 'string',
'date' => 'date',
'cat' => 'int',
'num' => 'int',
'hot' => 'int',
'status' => 'int'
];
// -------------获取器
public function get_data(){
$select = Boke::select();
return $select->toArray();
}
public function getStatusAttr($v){
// echo $v; Status字段的内容
$status = [
1=>'开启',
0=>'关闭'
];
return $status[$v];
}
public function getHotAttr($v){
$hot = [
1=>'热门',
0=>'非热门'
];
return $hot[$v];
}
// -----------------修改器
// 添加的时候
public function add_data($data=[]){
$data = [
'title' => '新文章',
'img' => '',
'content' => '',
'date' => '2021-06-01',
'cat' => 2,
'num' => 0,
'hot' => 0,
'status' => 1
];
$create = Boke::create($data);
return $create;
}
// 修改的时候
public function edit_data(){
$boke = Boke::find(6);
$boke['title'] = '新修改';
$update = $boke->save();
// $update = Boke::where(['bid'=>16])->update(['title'=>'新修改']);
return $update;
}
// 添加和修改的时候,对其标题字段内容统一处理
public function setTitleAttr($v,$all){
// $all 全部参数
// serialize产生一个可存储的值的表示 s:9:"新文章";
return serialize($v);
// 插入和修改标题的时候,将其内容转换为整型
return (int)$v;
// 将标题在前面加上前缀
return '前缀'.$v;
}
// --------------搜索器
public function s_data(){
$select = Boke::where(['title'=>'新'])->select();
return $select->toArray();
// withSearch方法触发搜索器,将自动查询标题中含有新的所有文章信息
$select = Boke::withSearch(['title'],[
'title' => '新'
])->select();
return $select->toArray();
}
public function searchTitleAttr($query,$v){
// $query查询出的对象 $v 查询的字段内容
$query->where('title','like', '%'.$v.'%');
}
}
对查询某个字段时,统一处理该字段查询条件
4、检查数据
- 如果要判断数据集是否为空,不能直接使用
empty
判断 - 必须使用数据集对象的
isEmpty
方法判断
namespace app\model;
use think\Model;
class Boke extends Model{
protected $name = 'Boke';
protected $pk = 'bid';
protected $schema = [
'bid' => 'int',
'title' => 'string',
'img' => 'string',
'content' => 'string',
'date' => 'date',
'cat' => 'int',
'num' => 'int',
'hot' => 'int',
'status' => 'int'
];
public function get_data(){
$select = Boke::where('title','1')->select();
if(empty($select)){
echo '空';
}else{
echo "不为空";
}
if($select->isEmpty()){
echo 'kong';
}
}
}
s:9:"新文章";
return serialize($v);
// 插入和修改标题的时候,将其内容转换为整型
return (int)$v;
// 将标题在前面加上前缀
return '前缀'.$v;
}
// --------------搜索器
public function s_data(){
$select = Boke::where(['title'=>'新'])->select();
return $select->toArray();
// withSearch方法触发搜索器,将自动查询标题中含有新的所有文章信息
$select = Boke::withSearch(['title'],[
'title' => '新'
])->select();
return $select->toArray();
}
public function searchTitleAttr($query,$v){
// $query查询出的对象 $v 查询的字段内容
$query->where('title','like', '%'.$v.'%');
}
}
对查询某个字段时,统一处理该字段查询条件
4、检查数据
- 如果要判断数据集是否为空,不能直接使用
empty
判断 - 必须使用数据集对象的
isEmpty
方法判断
namespace app\model;
use think\Model;
class Boke extends Model{
protected $name = 'Boke';
protected $pk = 'bid';
protected $schema = [
'bid' => 'int',
'title' => 'string',
'img' => 'string',
'content' => 'string',
'date' => 'date',
'cat' => 'int',
'num' => 'int',
'hot' => 'int',
'status' => 'int'
];
public function get_data(){
$select = Boke::where('title','1')->select();
if(empty($select)){
echo '空';
}else{
echo "不为空";
}
if($select->isEmpty()){
echo 'kong';
}
}
}