thinkphp5 数据库和模型
1、Db和模型的存在只是ThinkPHP5.0架构设计中的职责和定位不同,Db负责的只是数据(表)访问,模型负责的是业务数据和业务逻辑。
2、Db和模型最明显的一个区别就是Db查询返回的数据类型为数组(对于一个没有业务逻辑的数据而言,数组已经足够),而模型的查询返回类型的是模型对象实例。
3、总而言之,想要掌握模型,必须明白和理解下面几个原则:
模型和数据库层的定位和职责不同;
不要因为性能而放弃使用模型,那是得不偿失的;
用面向对象的方式来使用和设计模型;
模型的数据底层操作仍然是数据库抽象访问层,而且是自动的
4、模型定义有几个要素:
通常会继承think\Model(或者子类),虚拟模型除外;
一个模型并不总是对应一个数据表(可能会有多个),虽然默认如此;
模型名和数据表名也不是直接对应关系;
尽管一个空模型和使用Db类无异,但意义不同;
5、模型定义阶段要达成的目的:
定义数据表(默认就是模型类名)
定义数据表主键(默认会自动获取)
定义数据库连接(默认使用数据库配置)
定义数据处理逻辑(包括属性和方法)
定义业务逻辑(方法)
6、下面的定义是不需要或者不支持的:
数据表字段(不需要,会自动获取,并支持缓存机制)
数据表前缀(不支持,模型不关心前缀)
7、大多数情况下,数据表和数据库连接是不需要定义的,数据处理逻辑和业务逻辑才是模型定义的重点
8、在新版框架的架构设计规范中,我们建议数据表的命名不使用前缀设计,表前缀其实已经是一种过时的设计了,很多时候跨库的设计比表前缀的设计来的更灵活和实用,而且前缀设计(尤其是在混合用的情况下)带来的一些困惑和问题却是很多新手最大的苦恼,所以何必自寻烦恼(如果你一定要采用前缀设计,那么请用name方法替代table方法,并且在数据库配置文件中配置prefix参数,我也不拦着你,哭的时候别找我^_^)
9、关于模型的连接对象和查询对象,要清楚下面这些事实:
模型可以单独设置数据库连接;
模型的数据库连接是惰性的(因为连接本身就是惰性);
如果使用统一的数据库配置,模型使用的连接对象是相同的;
模型使用的查询对象是独立的;
模型可以使用自定义的查询对象;
10、模型类实现了ArrayAccess接口,因此一样可以使用数组方式操作对象
11、因为模型基本上是内部处理业务逻辑,所以会出现内部调用的时候
以name属性为例,获取模型数据的方式有下列三种:
场景 方法
外部获取模型数据 $model->name
内部获取模型数据 $this->getAttr('name')
内部获取(原始)模型数据 $this->getData('name')
getData和getAttr方法的区别前者是原始数据,后者是经过读取器处理的数据,如果没有定义数据读取器的话,两个方法的结果是相同的。
对应的设置模型数据的方式也有三种:
场景 方法
外部设置模型数据 $model->name='thinkphp'
内部设置模型数据(经过修改器) $this->setAttr('name','thinkphp')
内部设置模型数据 $this->data('name','thinkphp')
data和setAttr方法的区别前者是赋值最终数据,后者赋值的数据还会经过修改器处理,如果没有定义修改器的话,两个方法的结果是相同的。
12、CURL
模型的CURD操作最终调用的还是Db类的操作,区别在于使用了ActiveRecord模式和单独做了一层封装而已
除了模型自己的方法操作外,还可以调用Db类的所有查询方法,也就是说Db类的CURD操作方法都可以在模型类中被调用。
//创建
//动态
$user = new User;
$user->name = 'thinkphp';
$user->email = 'thinkphp@qq.com';
$user->save();
// 获取用户的主键数据
echo $user->id;
//静态
$user = User::create([
'name' => 'thinkphp',
'email' => 'thinkphp@qq.com',
]);
echo $user->id;
//读取
$user = User::get(1);
echo $user->id;
// 查询用户数据集
$users = User::all([1, 2, 3]);
$users = User::where('id', '>', 1)
->limit(5)
->select();
// 遍历读取用户数据
foreach ($users as $user) {
echo $user->id;
echo $user->name;
}
//更新
//动态 返回影响的记录数
$user = User::get(1);
$user->save([
'name' => 'topthink',
'email' => 'topthink@qq.com',
]);
//静态 返回模型对象实例
User::update([
'name' => 'topthink',
'email' => 'topthink@qq.com',
], ['id' => 1]);
//删除
$user = User::get(1);
$user->delete();
//静态实现
User::destroy(1);
现在我们已经掌握了模型的基本CURD操作,我们来总结下方法区别:
用法 Db类 模型(动态) 模型(静态)
创建 insert save create
更新 update save update
读取单个 find find get
读取多个 select select all
删除 delete delete destroy
然后要注意几个注意事项:
模型类可以直接调用Db类的所有方法;
模型类和Db类的查询返回类型是完全不同的,即便是调用同一个方法查询;
模型类封装的静态方法本质上还是调用的动态方法,只是为了方便不同的需求场景;
模型对象的查询操作尽量使用静态方法调用;
13、查询构造器
查询构造器的用法在模型类中没有变化,并且还做了一些增强来支持模型的CURD封装方法。
所有的链式方法都可以直接被模型类静态调用,而且一样不分先后次序,你只要掌握了数据库的查询构造器用法,就能掌握模型的查询用法,而且模型类不需要调用table方法来指定数据表名称,因为模型已经有自己的对应数据表规则,从这一点来说,模型的查询操作应该比Db类的查询操作用法简单
模型可以直接调用Db类(确切的说是查询类)的方法,无论是静态还是动态调用,也就是说你可以把模型类当成Db类一样使用(虽然用法一样,但其实区别很大,可能查询条件、查询结果和返回类型都不同)
14、数据集
// 设置数据集返回类型 database.php中
'resultset_type' => 'collection',
// 设置模型的数据集返回类型 模型中
protected $resultSetType = 'collection';
数据集的优势:
数据更对象化;
关联操作更方便;
数据集本身可以单独定义独立的业务方法;
15、业务逻辑
业务逻辑应当封装到具体模型中,并由控制器来调用;
thinkphp5 数据库和模型的更多相关文章
- mysql数据库导出模型到powerdesigner,PDM图形窗口中显示数据列的中文注释
1,mysql数据库导出模型到powerdesigner 2,CRL+Shift+X 3,复制以下内容,执行 '******************************************** ...
- 《Entity Framework 6 Recipes》翻译系列 (4) -----第二章 实体数据建模基础之从已存在的数据库创建模型
不知道对EF感兴趣的并不多,还是我翻译有问题(如果是,恳请你指正),通过前几篇的反馈,阅读这个系列的人不多.不要这事到最后成了吃不讨好的事就麻烦了,废话就到这里,直奔主题. 2-2 从已存在的数据库创 ...
- EF实体框架-从数据库更新模型 一部分表的外键(导航属性)无法显示
从数据库更新模型 要想让数据库表之间的外键关系 显示到实体模型的导航属性中去. 表的外键 对应另一张表的字段要是主键,唯一键显示不出来
- "ApplicationDbContext"(泛指之类的数据库上下文模型)上下文的模型已在数据库创建后发生更改。请考虑使用 Code First 迁移更新数据库。
一,在我使用自动生成数据库的时候,当你改变了数据库就会出现下面问题 "ApplicationDbContext"(泛指之类的数据库上下文模型)上下文的模型已在数据库创建后发生更改. ...
- 数据库 E-R模型
数据库 E-R模型被定义被两种模型 "实体模型" AND "关系模型" 1.1 实体模型 如图:这是一个"项目表" Project ...
- Django教程:[33]从数据库生成模型
在使用django做网站的时候,有时候我们的数据库来自一个已有的数据库,如何整合这个数据库呢? django提供了方便的方法来整合已有数据库,下面我们看看具体的方法: 1.先来设置数据库:在网站文件夹 ...
- 文献综述九:Oracle数据库性能模型的研究
一.基本信息 标题:Oracle数据库性能模型的研究 时间:2018 出版源:数字技术与应用 文件分类:对框架的研究 二.研究背景 帮助运维人员分析数据库性能,发现问题,指导调优. 三.具体内容 文献 ...
- DataUml Design 教程7 - 数据库生成模型
DataUml Design支持数据库生成模型,并支持外键关系,能够根据外键自动生成类与类之间的关系. 目前DataUML Design支持MS Server.MY SQL.Oracle和Access ...
- Django学习day7——简单的使用数据库和模型
Django支持的数据库 PostgreSQL SQLite 3 MySQL Oracle 其中SQLite 3不需要安装,因为SQLite使用文件系统上的独立文件来存储数据 这里我们用SQLite ...
随机推荐
- kraken-ejs创建一个项目【学习札记】
Keep in Touch. 保持联络. Who’s calling? 是哪一位? You did right. 你做得对. You set me up! 你出卖我! kraken-express-e ...
- 解决vue-router嵌套路由(子路由)在history模式下刷新无法渲染页面的问题
一. 异常描述: 本来使用的是vue-router的hash模式,但是hash模式下url需要带“#”符号,不仅看起来不舒服,而且有些场景下是会破坏路由中的"#"(微信分享页面就会 ...
- PTA 7-2 符号配对(栈模拟)
请编写程序检查C语言源程序中下列符号是否配对:/*与*/.(与).[与].{与}. 输入格式: 输入为一个C语言源程序.当读到某一行中只有一个句点.和一个回车的时候,标志着输入结束.程序中需要检查配对 ...
- pycharm中conda环境部署
问题 pycharm中部署了conda base环境,项目中 import sklearn 报错,缺少DLL模块 . 但是在Anaconda Prompt中 import sklearn 则成功. 发 ...
- c++笔试题贪吃蛇问题
贪吃蛇 现在有一个N*M(N,M=100)的方形矩形,在这个矩形的每一个方格上都放有一个随机值,一条可爱的小蛇从矩形的 左上角开始出发,每次移动都只能移动一格,向右或向下,而每到达一格贪吃的小蛇都会吧 ...
- swift - self的弱引用
1. weak var weakSelf = self 2. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) {[weak se ...
- 42-字符串到json 的错误 com.alibaba.fastjson.JSONObject cannot be cast to java.lang.String
json: {"updated_at":1551780617,"attr":{"uptime_h":3,"uptime_m&quo ...
- POPUP_TO_CONFIRM的使用方法
CALL FUNCTION 'POPUP_TO_CONFIRM' EXPORTING TEXT_QUESTION = '是否要打印凭证!' ...
- ABP框架使用Mysql数据库
参考文档:https://github.com/ABPFrameWorkGroup/AbpDocument2Chinese/blob/master/Markdown/Abp/9.4ABP%E5%9F% ...
- 谷歌开发的draco格式文件将obj文件压缩成drc文件后将大大减小文件大小(threejs加载有mtl文件的drc文件)
问题描述:当前threejs是92版本 但是当前版本还没有能够直接加载带贴图文件的drc格式的loader: 解决办法:先加载mtl文件将obj文件分解(按照mtl文件内材质贴图信息进行分解)再将分解 ...