学习教程来源于:
php中文网 ThinkPHP5 视频教程
ThinkPHP5.0完全开发手册

连接器与查询构造器

TP5采用的是惰性连接,故而仅在查询时才会连接到数据库

TP5的数据库操作对底层进行优化设计,对各种操作进行高级封装。既可以直接使用连接器进行高效的原生查询,也可以使用封装好的查询构造器进行直观便捷的查询,为模型操作打下基础。

创建数据库连接(静态与动态方式)

静态连接:应用/模块中的数据库配置文件database.php
动态连接:入口类Db.php中的connect(参数:数组/字符串)方法

参数名 默认值 说明
type mysql 数据库类型
hostname 127.0.0.1 服务器地址
database 数据库名称
username 数据库用户名
passward 数据库密码
hostport 3306 数据库连接端口
charset utf8 数据库默认编码
prefix 数据库表的前缀
debug TRUE 数据库调试模式

①动态设置

public function demo()
{$config = ['type' => 'mysql','hostname' => 'localhost','username' => 'root','password' => 'root','database' =>'tp5',];//1.获取数据库的链接实例/对象$link = Db::connect($config);//2.用连接实例调用查询类的查询方法$result = $link->table('staff')->select();//3.输出查询结果dump($result);
}

②动态配置连接字符串

mysql://root:1234@localhost:3306/thinkphp#usf8

数据库类型://用户名:密码@数据库地址:数据库端口/数据库名称#字符集

public function demo()
{//1.获取数据库的链接实例/对象 $config = 'mysql://root:root@localhost:3306/tp5#utf8';$link = Db::connect($config);//2.用连接实例调用查询类的查询方法$result = $link->table('staff')->select();//3.输出查询结果dump($result);
}

简化代码如下:

public function demo()
{$result = Db::table('staff')->select();dump($result);
}

!!!db()助手函数不支持惰性连接

数据库的原生查询实现原理:query和execute方法

Connection类:
①query(sql语句字符串,[参数绑定]):读操作—>select
②execute(sql语句字符串,[参数绑定]):写操作—>insert/update/delete

支持在原生查询的时候使用参数绑定,包括问号占位符或者命名占位符,参数绑定可以防止sql注入:

Db::query("select * from think_user where id=? AND status=?",[8,1]);
// 命名绑定
Db::execute("update think_user set name=:name where status=:status",['name'=>'thinkphp','status'=>1]);

Connection类实例通过入口类Db静态自动调用,不用显示写出

public function demo()
{//1.查询操作:查询工资大于4000远的员工信息用命名占位符进行参数绑定$sql = "select name,salary,dept from staff where salary > :salary";$result = Db::query($sql,['salary'=>4000]);//数组中的第一个元素和第一个问号对应dump($result);//2.更新操作:将Id=3的记录,salary增加1000$sql = "update staff set salary = salary+1000 where id=:id";$result = Db::execute($sql,['id'=>3]);dump($result);//返回受影响非记录条数//3.插入操作:默认添加到表的尾部的$sql = "insert into staff (name,sex,salary) values (:name,:sex,:salary)";$result = Db::execute($sql,['name'=>'郭襄','sex'=>0,'salary'=>3500]);dump($result);//4.删除操作:id=4的记录删除$sql = "delete from staff where id=:id";$result = Db::execute($sql,['id'=>4]);dump($result);}
查询构造器(抽象访问层)

①链式操作的功能是快速生成查询条件
②链式操作中的所有的方法都来自于query查询类
③链式操作的返回值就是当前的查询对象

生成查询条件的三种方法:表达式/数组/闭包(推荐)

2个方法:
①where():AND条件
②whereOr():OR条件

三种格式:
①where(‘字段名’,‘表达式’,‘查询条件’)

public function index()
{dump(Db::table('staff')->field(['name','salary'])->where('id','>',2)->select());
}

②where([‘字段名’=>[‘表达式’,‘查询条件’],…])

public function index()
{dump(Db::table('staff')->field(['name','salary'])->where(['id'=>['>',2],'salary'=>['>',3000]])->select());
}

③where(function($query){//链式查询语句;})

推荐方式:闭包的好处在于可以实现复杂的条件调用,且可以使用外部传入的变量

public function index(){dump(Db::table('staff')->field(['name','salary'])->where(function ($query){$query->where('id','>',1)->where('salary','>',4000);})->select());}
public function index(){$salary = 4000;// dump(//   Db::table('staff')//   ->field(['name','salary'])//   ->where(function ($query) use ($salary){//       $query->where('id','>',1)//             ->where('salary','>',$salary);//   })//   ->select()// );dump(Db::select(function ($query) use ($salary) {$query->table('staff')->field(['name','salary'])->where(['id'=>['>',2],'salary'=>['>',$salary]]);}));}
select与find

参考:TP5 完全开发手册

查询一个数据使用find

// table方法必须指定完整的数据表名
Db::table('think_user')->where('id',1)->find();

find 方法查询结果不存在,返回 null

查询数据集使用select

Db::table('think_user')->where('status',1)->select();

select 方法查询结果不存在,返回空数组

数据库的新增与更新操作

1.新增
insert(['字段'=>'值']) 插入单条记录
insertAll(['二维数组']) 同时插入多条记录

2.更新
update(['字段'=>'值']) 根据条件更新一条或多条记录
setInc/setDec('字段','步长') 如果字段类型是数字型,且每次更新时有规律的,则可以使用这种方式

延迟更新

setInc/setDec支持延时更新,如果需要延时更新则传入第三个参数
下例中延时10秒,给score字段增加1

Db::table('think_user')->where('id', 1)->setInc('score', 1, 10);

setInc/setDec方法返回影响数据的条数

3.读取
find(主键) 单条读取,以一维数组的形式返回
select(主键) 返回多条满足条件的记录,可以以二维数组的方式返回

4.删除
delete(主键) 根据条件进行删除
delete(true) 无条件删除,清空数据表(危险操作)

delete删除方法不支持闭包

数据库的查询与删除操作:find/select/value/column/delete

1.value获取某个字段的值

public function index()
{//value('字段','默认值')$result = Db::table('staff')->where('id',1)->value('name');dump($result);
}

2.column输出一列数据

public function index()
{//value('字段','默认值')$result = Db::table('staff')->where('id','>',1)->column('name','id');//column的第一个参数为值,第二个参数为键名dump($result);
}

3.delete删除数据

public function index()
{//value('字段','默认值')$result = Db::table('staff')->delete(7);return $result?'成功删除了'.$result.'条记录' : '删除失败';
}
模型的基本概念与基类Model介绍

模型是对实体的抽象描述,快速直观的展示出实体的特征。

TP5中的模型是指数据表(粗略理解)。

模型类中的属性与方法:
1.模型类中的属性和方法需要在基类Model中查看
2.Model.php类位于public/library/think/Model.php
3.该类是一个抽象类,不能被实例化,必须由子类继承并实现内部的全部抽象方法

模型的创建与使用:实例化与静态创建

模型与数据表的对应关系:
模型的属性与数据表的字段一一对应,数据表中的一行信息对应模型的一个实例。而模型的方法则定义了对当前数据表的一些操作。

①区别于联系

区别:
1.分工不同:Db类负责数据表的访问,模型专注于业务逻辑的处理
2.返回值不同:Db访问返回数组,模型操作返回对象

联系:
模型最终仍需调用Db类完成数据表的查询操作。
模型可以看做是一种更高级别的抽象,最终的底层仍然需要依靠Db类完成数据表的增删改查操作。

②创建模型

1.手工创建:
在应用或模块下创建模型目录model,并在该目录下创建与数据表同名的类文件:如User.php对应user.dbf表。(首字母大写)
2.命令创建:
在当前项目目录下,用命令:php think make:model 模块名/模型名,会自动创建指定位置和命名空间的空模型,并自动与数据表绑定;
3.模型创建完成后,会自动获取当前数据表名称$table,表中所有字段信息$field,主键$pk和数据库配置信息$connection.同时会自动继承基类Model中所有属性和方法,protected类型在本模型中使用,public类型还可以在控制器使用,静态方法大多直接用在控制器,进行CURD操作。

③控制器中调用模型

一、实例化调用:
1.用new生成模型对象
2.用模型对象处理相关业务

<?php
namespace app\index\controller;
use app\index\model\Staff;class Index extends \think\Controller
{public function index(){//1.实例化创建模型对象$staff = new Staff();$result = $staff -> where('id',3)->find();dump($result->getData('name'));}
}

二、静态调用:
1.通过静态查询直接将一个空模型转为数据模型
2.再调用相关方法完成增删改查操作

<?php
namespace app\index\controller;
use think\Db;
use app\index\model\Staff;class Index extends \think\Controller
{public function index(){//2.静态创建模型对象dump(Staff::get(3)->getData('sex'));}}

三、不推荐使用助手函数model()和添加模型类后缀

④模型数据访问方式

1.控制器访问(外部)->用模型对象:$model

2.模型访问(内部)->用伪对象变量:$this

模型的CURD操作

Cread/Update/Read/Delete

1.模型向数据表中添加数据:save()/saveAll()/update()
方法 说明 调用方法 返回值
save($data=[]) 添加单条 实例化 影响记录数
saveAll($data=[]) 批量添加 实例化 模型对象数组
create($data=[]) 单条添加 静态 模型对象

①数据创建过程可以触发很多操作,非Db类操作可比
②静态调用的实质其实仍是实例化调用,只是将CURD方法进行静态封装
saveAll()方法实际上是通过多次执行insert语句完成,很少用到
④理论上讲,通过模型向表中添加数据,尽可能都采用静态方式

<?php
namespace app\index\controller;
use think\Db;//导入数据库类
use app\index\model\Staff;//导入模型的命名空间class Index extends \think\Controller
{public function index(){//1.实例化模型,创建模型对象$staff = new Staff();//2.创建数据,采用的对象方式$staff->name = '韦小宝';$staff->sex = 1;$staff->salary = 9000;//3.执行数据添加操作$result = $staff->save();return $result ? '成功添加了'.$result.'条记录' : '添加失败';}
}
<?php
namespace app\index\controller;
use think\Db;//导入数据库类
use app\index\model\Staff;//导入模型的命名空间class Index extends \think\Controller
{public function index(){//1.实例化模型,创建模型对象$staff = new Staff();//2.创建数据,采用的对象方式$data = [['name'=>'陈近南','salary'=>40000],['name'=>'吴三桂','salary'=>60000],['name'=>'陈圆圆','salary'=>8000],];//3.执行数据添加操作$result = $staff->saveAll($data);dump($result);}
}
<?php
namespace app\index\controller;
use think\Db;//导入数据库类
use app\index\model\Staff;//导入模型的命名空间class Index extends \think\Controller
{public function index(){$result = Staff::create(['name'=>'林平之','sex'=>'1','salary'=>300]);dump($result->getData());}}
2.模型的更新操作:save()/saveAll()/update()
方法 说明 调用方法 返回值
save($data=[],$where=[]) 单条更新 实例化 影响记录数
saveAll($data=[].true) 批量更新 实例化 模型对象数组
update($data=[],$where=[],$field=[]) 单条更新 静态 模型对象

1.不允许无条件更新,必须设置更新条件
2.可以将更新条件,如主键写在更新数据中,方法可以自动识别
3.更新条件可以使用闭包,完成更复杂的业务逻辑

<?php
namespace app\index\controller;
use think\Db;
use app\index\model\Staff;class Index extends \think\Controller
{public function index(){$staff = new Staff();$data = ['Id'=>8,'name'=>'岳不群','sex'=>1];$staff->isUpdate(true)->save($data);dump($staff->getData());}
}
<?php
namespace app\index\controller;
use think\Db;
use app\index\model\Staff;class Index extends \think\Controller
{public function index(){$staff = new Staff();$data = ['name'=>'张无忌','sex'=>1,];$where = ['Id'=>13,];$staff->save($data,$where);dump($staff->getData());}
}
<?php
namespace app\index\controller;
use think\Db;
use app\index\model\Staff;class Index extends \think\Controller
{public function index(){$staff = new Staff();$data = [['Id'=>14,'name'=>'张无忌','sex'=>1],['Id'=>15,'name'=>'赵敏','sex'=>0],['Id'=>16,'name'=>'小昭','sex'=>1],];$staff->isUpdate(true)->saveAll($data);dump($staff->getData());}
}
<?php
namespace app\index\controller;
use think\Db;
use app\index\model\Staff;class Index extends \think\Controller
{public function index(){//update(更新数据,更新条件,允许更新的字段)$data = ['name'=>'韦一笑','sex'=>1,'salary'=>5600];$where = ['id'=>24];$field = ['name','sex'];$result = Staff::update($data,$where,$field);dump($result->getData());}
}
<?php
namespace app\index\controller;
use think\Db;
use app\index\model\Staff;class Index extends \think\Controller
{public function index(){//update(更新数据,更新条件,允许更新的字段)$data = ['name'=>'韦一笑','sex'=>1,'salary'=>5600];//更新条件使用闭包写法//闭包支持外部传入的变量$where = function ($query){$query->where('Id',25);};$field = ['name','sex'];$result = Staff::update($data,$where,$field);dump($result->getData());}
}
3.模型的查询操作:find()/select()/get()/all()

ORM模型(对象关系映射)

方法 调用方式 返回值
find($where)get($where) 实例化/静态 模型对象
select($where)all($where) 实例化/静态 模型对象数组

1.原则来说,查询都应该采用静态查询方法
2.尽可能采用get()all()方法代替find()selec()
3.牢记一条原则:一个模型对象实例应该唯一对应数据表的一条记录

<?php
namespace app\index\controller;
use think\Db;
use app\index\model\Staff;class Index extends \think\Controller
{public function index(){//模型实例化方式调用find()和get()方法//find和get方法都只返回满足条件的第一条记录$staff = new Staff;$where = function ($query){$query -> field(['name','salary'])-> where('id','=',3);};$result = $staff->find($where);//$result = $staff->get($where);dump($result->getData());}
}
<?php
namespace app\index\controller;
use think\Db;
use app\index\model\Staff;class Index extends \think\Controller
{public function index(){//模型实例化方式调用select()和all()方法$staff = new Staff;$where = function ($query){$query -> field(['name','salary'])-> where('salary','>',10000);};$result = $staff->select($where);//$result = $staff->all($where);foreach ($result as $value) {dump($value->getData());}}
}
<?php
namespace app\index\controller;
use think\Db;
use app\index\model\Staff;class Index extends \think\Controller
{public function index(){//模型实例化方式调用select()和all()方法$staff = new Staff;$where = function ($query){$query -> field(['name','salary'])-> where('salary','>',10000);};$result = $staff->all($where);foreach ($result as $key => $value) {// dump($value->getData());echo '记录编号:'.($key+1).' | 姓名:'.$value->name.' | 工资:'.$value->salary.'<br/>';}}
}
<?php
namespace app\index\controller;
use think\Db;
use app\index\model\Staff;class Index extends \think\Controller
{public function index(){//用模型类静态调用find和get方法$where = function ($query){$query->field(['name','salary'])->where('id','=',2);};// $result = Staff::find($where);$result = Staff::get($where);dump($result->getData());}
}
<?php
namespace app\index\controller;
use think\Db;
use app\index\model\Staff;class Index extends \think\Controller
{public function index(){//用模型类静态调用select和all方法$where = function ($query){$query->field(['name','salary'])->where('id','>',2);};// $result = Staff::select($where);$result = Staff::all($where);foreach ($result as $value) {dump($value->getData());}}
}
4.模型的删除操作:delete()和destroy()
方法 调用方式 返回值
delete() 实例化 受影响的记录数量
destroy(条件/闭包) 静态 受影响记录数量

1.delete()不要传任何参数,他只删除当前模型对象对应的记录
2.destroy()中的删除条件,推荐采用闭包方式
3.推荐用软删除替代该方法,即用更新的方式来实现删除操作

<?php
namespace app\index\controller;
use think\Db;
use app\index\model\Staff;class Index extends \think\Controller
{public function index(){$where = function ($query){$query->where('id','>',12)->where('sex','=',1)->whereOr('salary','>',4000);};$value = Staff::destroy($where);dump($value);}
}
5.模型读取器与修改器:getAttr()和setAttr()

①模型的读取器
触发条件:当用模型对象读取表中字段值的时候
应用场景:日期时间字段、集合或枚举数据、数字状态与文本转换、字段拼接
设置位置:在模型中设置,访问属性通常为protected,不允许外部直接访问
方法名称:get属性名称Attr($name,$data=[])

get FieldName Attr($name,$data=[])
驼峰命名法,对应表中字段:field_name

模型的读取器工作原理图

②模型的修改器
触发条件:当用模型对象向数据表中新增记录或更新字段值的时候
应用场景:日期时间字段、集合或枚举数据、数字状态与文本转换、字段拼接
设置位置:在模型中设置,访问属性通常为protected,不允许外部直接访问
方法名称:set属性名称Attr($name,$data=[])

set FieldName Attr($name)
驼峰命名法,对应表中字段:field_name

模型的修改器工作原理图

<?php
namespace app\index\model;
use think\Model;class Staff extends Model
{//$data中保存的是当前面模型的所有数据protected function getHireDateAttr($hiredate,$data){return $data['name'].'的入职时间是:'.date('Y-m-d',$hiredate);}protected function setHireDateAttr($hiredate){return strtotime($hiredate);}
}
?>
6.模型数据类型转换:$type属性设置技巧

字符串类型是默认的读取类型

<?php
protected $type = ['name'         => 'array',      //以json格式写入,取出自动编码为array'age'       => 'integer',        //该字段写入和输出的时候都会字段转换为整型'salary'     => 'float',      //该字段写入和输出的时候都会自动转换为浮点型'dept'          => 'serialize',  //自动序列化写入,读取的时候自动反序列化'home'         => 'json',           //json_encode写入,读取时json_decode处理'hiredate'  => 'timestamp',  //用strtotime转为时间戳写入,读出按$dateFormat格式输出'birthday'    => 'datetime'        //读写都是按$dateFormat格式处理
];
?>
7.模型自动完成设置:$insert/$update/$auto属性配置技巧

一、自动时间戳
1.模型中开启:protected $autoEriteTimestamp=true
2.在表中手工创建二个字段:create_time,update_time
3.用户自行新增和更新操作时,会自动将新增与更新时间写入表中
4.默认以时间戳格式写入,可以配置为:datatime格式

二、自动完成
1.$insert=['字段'=>'值',...]; //新增时自动插入到表中的
2.$update=['字段'=>'值',...]; //更新时自动更新字段值
3.$auto=['字段'=>'值',...]; //新增或更新时自动填入或更新字段值
通常要与类型自动转换属性:$type=['字段'=>'类型',...]相配合

<?php
namespace app\index\model;
use think\Model;class Staff extends Model
{// 是否需要自动写入时间戳 如果设置为字符串 则表示时间字段的类型protected $autoWriteTimestamp=true;// 创建时间字段protected $createTime = 'create_time';// 更新时间字段protected $updateTime = 'update_time';// 保存自动完成列表protected $auto = ['salary'=>4500,'hiredate'=>'2019-09-16',];// 新增自动完成列表protected $insert = [// 'sex'=>1,'dept',  //部门名称,根据员工性别sex字段的值确定'hiredate'=>'2019-09-16',];// 更新自动完成列表protected $update = ['dept'=>'测试部',];protected $type = ['hiredate'=>'timestamp',];protected function setDeptAttr($dept,$data){if ($data['sex']) {return $this->dept = '开发部';}else{return $this->dept = '客服部';}}
}
?>

ThinkPHP5.0教程学习06:TP5 数据库与模型操作相关推荐

  1. php环境搭建sqlserver,ThinkPHP5.0/5.1对接SQLServer数据库(宝塔环境)

    SQLServer实际上是mssql,想要使用thinkphp的Db对象操作数据库前必须要在服务器上安装对应的扩展. 宝塔面板的PHP安装路径为/www/server/php/ 且支持多个PHP版本共 ...

  2. 【opencv4.3.0教程】06之基础结构3之Scalar_结构详解

    目录 一.前言 二.温故知新--Rect_ 1.定义与成员变量 2.构造函数 3.常用方法 三.Scalar_ 1.定义 1.构造函数 2.基本操作 3.使用时的数据类型 2.常用方法 1.加法及加赋 ...

  3. think PHP5.0小程序,微信小程序ofo小黄车+thinkphp5.0打造全栈应用

    链接 简介 本项目是采用PHP语言,THINKPHP5.0框架开发的全栈应用系统.在开发这个项目时,微信还没有OFO微信小程序,又不想下载APP去使用,只能在支付宝上面使用OFO,偶然间发现某人写了一 ...

  4. mysql数据库python基础知识_python学习之Mysql数据库编程基础知识介绍

    在Python网络爬虫中,通常是通过TXT纯文本方式存储,其实也是可以存储在数据库中的:同时在WAMP(Windows.Apache.MySQL.PHP或Python)开发网站中,也可以通过Pytho ...

  5. php开源微商系统,Thinkphp5.0开发的一款新微商新零售系统整站源码(带安装教程)...

    [温馨提示]源码包解压密码:www.youhutong.com 资源描述 Thinkphp5.0开发的一款新微商新零售系统整站源码 源码介绍: 这是一款thinkphp开发的新零售的派单工具平台 平台 ...

  6. SQL数据库教程-学习笔记2

    SQL数据库教程-学习笔记2 文章目录 SQL数据库教程-学习笔记2 三.DML语言的学习 1.插入语句:insert into 2.修改语句:update 3.删除语句:delete 4.练习题 四 ...

  7. Fabric2.0部署学习进阶教程系列博文

    Fabric2.0部署学习系列文章目录 1.<在本机上安装VMWare详细图文过程> https://blog.csdn.net/weixin_44750512/article/detai ...

  8. Yii Framework2.0开发教程(5)数据库mysql性能

    继续<Yii Framework2.0开发教程(3)数据库mysql入门> 首先给予一定的尊重yii2数据库支持引进 Yii 基于 PHP's PDO一个成熟的数据库访问层的建立.它提供了 ...

  9. php 5.0打印数据库,thinkphp5.0数据库操作

    ThinkPHP数据库处理: 1.MySQL的数据库连接 首先配置database.php文件 使用{dump(config('database));}来查看数据库的配置项 使用 {$res = Db ...

最新文章

  1. mysql5.5设置字符编码
  2. 《Android虚拟机》----虚拟机概述
  3. 字符串处理(POJ1782)
  4. Building Seam 2.0 Application with NetBeans 6.1
  5. c++中友元函数详解
  6. 剖析数组名、函数名(不是指针常量,更不是指针)
  7. TortoiseSVN版本管理的注意点
  8. android 软件测试文档,Android软件测试文档规范【参考】.doc
  9. 高校学生学籍系统C++amp;mysql
  10. 在freemarker文件中,html标签获取后台的值
  11. C#播放流媒体的几种方法
  12. mysql数据库的使用与理解( 基于ubuntu 14.0.4 LTS 64位)
  13. R语言基于mgcv包进行广义可加模型及交互作用演示(2)
  14. 如何制作微信抖音小游戏
  15. 梦想CAD软件(控件)图层介绍
  16. ae批量修改字体_AE脚本-批量文字替换图层样式属性编辑脚本Aescripts pt_TextEdit 2.41 + 使用教程...
  17. SourceInsight 软件乱码问题
  18. Moho Pro - Mac 上一款专业的二维动画制作软件,强大的功能让你尽情发挥创意
  19. 《茶馆》再开张 这出戏濮存昕、冯远征演了20年
  20. 无法部署应用目录 [D:\Tomcat\apache-tomcat-9.0.44\webapps\ROOT]java.lang.IllegalStateException: 启动子级时出错

热门文章

  1. C语言单引号和双引号
  2. 一个月体验,终于懂了程序员为什么喜欢用MacBook!
  3. 【计算机网络——制作双绞线】
  4. DAEMON Tools Lite 虚拟光驱,安装iso文件,提示需要管理员权限的问题解决
  5. 忽然看到自己十年前发的关于转计算机专业的帖子
  6. python爬取b站搜索结果_Python爬虫实例:爬取猫眼电影——破解字体反爬,Python爬虫实例:爬取B站《工作细胞》短评——异步加载信息的爬取,Python爬虫实例:爬取豆瓣Top250...
  7. Android 如何访问网络
  8. 计算机二级c语言编译,全国计算机等级考试教程-二级C语言.pdf
  9. vue里使用quill
  10. 新玺配资:外围市场大跌 A股很难不受影响