# CURD操作
[上一页](# "上一页")[下一页](# "下一页")
ThinkPHP提供了灵活和方便的数据操作方法,对数据库操作的四个基本操作(CURD):创建、更新、读取和删除的实现是最基本的,也是必须掌握的,在这基础之上才能熟悉更多实用的数据操作方法。CURD操作通常是可以和连贯操作配合完成的。下面来分析下各自的用法:
(下面的CURD操作我们均以M方法创建模型实例来说明,因为不涉及到具体的业务逻辑)
### 创建(Create)
在ThinkPHP中使用add方法新增数据到数据库(而并不是create方法)。
<table border="0" cellspacing="1" cellpadding="0"><tr><th colspan="2">add 写入(新增)数据到数据库 </th> </tr><tr><td>用法 </td> <td>add($data='',$options=array(),$replace=false)</td> </tr><tr><td>参数 </td> <td><p>data(可选):要新增的数据,支持数组和对象,如果留空取当前数据对象 </p><br/><p>options(可选):操作表达式,通常由连贯操作完成,默认为空数组 </p><br/><p>replace(可选):是否允许写入时更新,默认为false(个别数据库支持)</p> </td> </tr><tr><td>回调接口 </td> <td><p>写入前 _before_insert(&$data,$options)</p><br/><p>写入成功 _after_insert($data,$options)</p></td> </tr><tr><td>返回值 </td> <td><p>如果数据非法或者查询错误则返回false</p><br/><p>如果是自增主键 则返回主键值,否则返回1</p></td> </tr><tr><td>相关方法 </td> <td>通常和data、create方法配合使用 </td> </tr></table>
使用示例如下:`$User = M("User"); // 实例化User对象
$data['name'] = 'ThinkPHP';
$data['email'] = 'ThinkPHP@gmail.com';
$User->add($data);`或者使用data方法连贯操作`$User->data($data)->add();`如果在add之前已经创建数据对象的话(例如使用了create或者data方法),add方法就不需要再传入数据了。
使用create方法的例子:`$User = M("User"); // 实例化User对象
// 根据表单提交的POST数据创建数据对象
$User->create();
$User->add(); // 根据条件保存修改的数据`如果你的主键是自动增长类型,并且如果插入数据成功的话,Add方法的返回值就是最新插入的主键值,可以直接获取。
从2.1版开始恢复了批量插入数据的addAll方法(仅针对Mysql数据库),如:`$User->addAll($data)`同时在数据插入时允许更新操作:`add($data='',$options=array(),$replace=false)`其中add方法增加$replace参数(是否添加数据时允许覆盖),true表示覆盖,默认为false
### 读取(Read)
在ThinkPHP中读取数据的方式很多,通常分为读取数据和读取数据集。
读取数据集使用select方法(新版已经废除原来的findall方法):
<table border="0" cellspacing="1" cellpadding="0"><tr><th colspan="2">select 查询数据集 </th> </tr><tr><td>用法</td> <td>select($options=array())</td> </tr><tr><td>参数</td> <td>options(可选):为数组的时候表示操作表达式,通常由连贯操作完成;如果是数字或者字符串,表示主键值。默认为空数组。</td> </tr><tr><td>回调接口</td> <td>查询成功 _after_select(&$resultSet,$options)</td> </tr><tr><td>返回值</td> <td><p>查询错误返回false</p><br/><p>查询结果为空返回null</p><br/><p>查询成功返回查询的结果集(二维索引数组)</p></td> </tr><tr><td>相关方法</td> <td>通常配合连贯操作where、field、order、limit、join等一起使用</td> </tr></table>
使用示例:`$User = M("User"); // 实例化User对象
// 查找status值为1的用户数据 以创建时间排序 返回10条数据
$list = $User->where('status=1')->order('create_time')->limit(10)->select();`Select方法配合连贯操作方法可以完成复杂的数据查询。而最复杂的连贯方法应该是where方法的使用,因为这部分涉及的内容较多,我们会在查询语言部分就如何进行组装查询条件进行详细的使用说明。基本的查询暂时不涉及关联查询部分,而是统一采用关联模型来进行数据操作,这一部分请参考关联模型部分。读取数据使用find方法:
<table border="0" cellspacing="1" cellpadding="0"><tr><th colspan="2">find 查询数据 </th> </tr><tr><td>用法</td> <td>find($options=array())</td> </tr><tr><td>参数</td> <td>options(可选):为数组的时候表示操作表达式,通常由连贯操作完成;为数字或者字符串的时候表示主键值。默认为空数组。</td> </tr><tr><td>回调接口</td> <td>查询后 _after_find(&$result,$options)</td> </tr><tr><td>返回值</td> <td><p>如果查询错误返回false</p><br/><p>如果查询结果为空返回null</p><br/><p>如果查询成功返回查询的结果(索引数组)</p></td> </tr><tr><td>相关方法</td> <td>通常配合连贯操作where、field、order、join等一起使用</td> </tr></table>
读取数据的操作其实和数据集的类似,select可用的所有连贯操作方法也都可以用于find方法,区别在于find方法最多只会返回一条记录,因此limit方法对于find查询操作是无效的。
下面是一些查询的例子:`$User = M("User"); // 实例化User对象
// 查找status值为1name值为think的用户数据
$User->where('status=1 AND name="think"')->find();`即使满足条件的数据不止一条,find方法也只会返回第一条记录。如果要读取某个字段的值,可以使用getField方法
<table border="0" cellspacing="1" cellpadding="0"><tr><th colspan="2">getField 查询某个字段的值 </th> </tr><tr><td>用法</td> <td>getField($field,$sepa=null)</td> </tr><tr><td>参数</td> <td><p>field(必须):要获取的字段字符串(多个用逗号分隔)</p><br/><p>sepa(可选):字段数据间隔符号,如果是 NULL返回数组为数组。默认为null。</p></td> </tr><tr><td>回调接口</td> <td>查询后 _after_find(&$result,$options)</td> </tr><tr><td>返回值</td> <td><p>如果查询结果为空返回null</p><br/><p>如果field是一个字段则返回该字段的值</p><br/><p>如果field是多个字段,返回数组。数组的索引是第一个字段的值,sepa为null则返回二维数组。</p></td> </tr><tr><td>相关方法</td> <td>通常配合连贯操作where、limit、order等一起使用</td> </tr></table>
示例如下:`$User = M("User"); // 实例化User对象
// 获取ID为3的用户的昵称
$nickname = $User->where('id=3')->getField('nickname');`当只有一个字段的时候,默认返回一个值。
如果需要返回数组,可以用:`$this->getField('id',true); // 获取id数组`如果传入多个字段的话,默认返回一个关联数组:`$User = M("User"); // 实例化User对象
// 获取所有用户的ID和昵称列表
$list = $User->getField('id,nickname');`返回的list是一个数组,键名是用户的id, 键值是用户的昵称nickname。
如果传入多个字段的名称,例如:`$list = $User->getField('id,nickname,email');`返回的是一个二维数组,类似select方法的返回结果,区别的是这个二维数组的键名是用户的id(准确的说是getField方法的第一个字段名)。
如果我们传入一个字符串分隔符:`$list = $User->getField('id,nickname,email',':');`那么返回的结果就是一个数组,键名是用户id,键值是 nickname:email的输出字符串。
getField方法的sepa参数还可以支持限制数量,例如:`$this->getField('id,name',5); // 限制返回5条记录
$this->getField('id',3); // 获取id数组 限制3条记录`可以配合使用order方法使用。
### 更新(Update)
在ThinkPHP中使用save方法更新数据库,并且也支持连贯操作的使用。
<table border="0" cellspacing="1" cellpadding="0"><tr><th colspan="2">save 更新数据到数据库 </th> </tr><tr><td>用法</td> <td width="450">save($data='',$options=array())</td> </tr><tr><td>参数</td> <td><p>data:要保存的数据,如果为空,则取当前的数据对象。</p><br/><p>options:为数组的时候表示操作表达式,通常由连贯操作完成;为数字或者字符串的时候表示主键值。默认为空数组。</p></td> </tr><tr><td>回调接口</td> <td><p>更新前_before_update(&$data,$options)</p><br/><p>更新成功后 _after_update($data,$options)</p></td> </tr><tr><td>返回值</td> <td><p>如果查询错误或者数据非法返回false</p><br/><p>如果更新成功返回影响的记录数</p></td> </tr><tr><td>相关方法</td> <td>通常配合连贯操作where、field、order等一起使用</td> </tr></table>
`$User = M("User"); // 实例化User对象
// 要修改的数据对象属性赋值
$data['name'] = 'ThinkPHP';
$data['email'] = 'ThinkPHP@gmail.com';
$User->where('id=5')->save($data); // 根据条件保存修改的数据`为了保证数据库的安全,避免出错更新整个数据表,如果没有任何更新条件,数据对象本身也不包含主键字段的话,save方法不会更新任何数据库的记录。
因此下面的代码不会更改数据库的任何记录`$User->save($data); `除非使用下面的方式:`$User = M("User"); // 实例化User对象
// 要修改的数据对象属性赋值
$data['id'] = 5;
$data['name'] = 'ThinkPHP';
$data['email'] = 'ThinkPHP@gmail.com';
$User->save($data); // 根据条件保存修改的数据`如果id是数据表的主键的话,系统自动会把主键的值作为更新条件来更新其他字段的值。
还有一种方法是通过create或者data方法创建要更新的数据对象,然后进行保存操作,这样save方法的参数可以不需要传入。`$User = M("User"); // 实例化User对象
// 要修改的数据对象属性赋值
$data['name'] = 'ThinkPHP';
$data['email'] = 'ThinkPHP@gmail.com';
$User->where('id=5')->data($data)->save(); // 根据条件保存修改的数据`使用create方法的例子:`$User = M("User"); // 实例化User对象
// 根据表单提交的POST数据创建数据对象
$User->create();
$User->save(); // 根据条件保存修改的数据`上面的情况,表单中必须包含一个以主键为名称的隐藏域,才能完成保存操作。
如果只是更新个别字段的值,可以使用setField方法。
<table border="0" cellspacing="1" cellpadding="0"><tr><th colspan="2">setField 更新某个字段的值 </th> </tr><tr><td>用法</td> <td width="450">setField($field,$value='')</td> </tr><tr><td>参数</td> <td>options(可选):为数组的时候表示操作表达式,通常由连贯操作完成;为数字或者字符串的时候表示主键值。默认为空数组。</td> </tr><tr><td>返回值</td> <td><p>如果查询错误返回false</p><br/><p>如果更新成功返回影响的记录数</p></td> </tr><tr><td>相关方法</td> <td>必须配合连贯操作where一起使用</td> </tr></table>
使用示例:`$User = M("User"); // 实例化User对象
// 更改用户的name值
$User-> where('id=5')->setField('name','ThinkPHP');`setField方法支持同时更新多个字段,只需要传入数组即可,例如:`$User = M("User"); // 实例化User对象
// 更改用户的name和email的值
$data = array('name'=>'ThinkPHP','email'=>'ThinkPHP@gmail.com');
$User-> where('id=5')->setField($data);`而对于统计字段(通常指的是数字类型)的更新,系统还提供了setInc和setDec方法。
<table border="0" cellspacing="1" cellpadding="0"><tr><th colspan="2">setInc /setDec 字段增长/字段减少 </th> </tr><tr><td>用法</td> <td><p>setInc($field,$step=1)字段值增长</p><br/><p>setDec($field,$step=1)字段值减少</p></td> </tr><tr><td>参数</td> <td><p>field:要更新的字段名。</p><br/><p>step:增长或者减少的数值,默认为1。</p></td> </tr><tr><td>回调接口</td> <td><p>如果查询错误返回false</p><br/><p>如果更新成功返回影响的记录数</p></td> </tr><tr><td>返回值</td> <td><p>如果查询错误返回false</p><br/><p>如果更新成功返回影响的记录数</p></td> </tr><tr><td>相关方法</td> <td>必须配合连贯操作where一起使用</td> </tr></table>
`$User = M("User"); // 实例化User对象
$User->where('id=5')->setInc('score',3); // 用户的积分加3
$User->where('id=5')->setInc('score'); // 用户的积分加1
$User->where('id=5')->setDec('score',5); // 用户的积分减5
$User->where('id=5')->setDec('score'); // 用户的积分减1`
### 删除(Delete)
在ThinkPHP中使用delete方法删除数据库中的记录。
<table border="0" cellspacing="1" cellpadding="0"><tr><td>用法</td> <td width="450">delete($options=array())</td> </tr><tr><td>参数</td> <td>options:为数组的时候表示操作表达式,通常由连贯操作完成,如果没有传入任何删除条件,则取当前数据对象的主键作为条件;为数字或者字符串的时候表示主键值。默认为空数组。</td> </tr><tr><td>回调接口</td> <td>删除成功后 _after_delete($data,$options)</td> </tr><tr><td>返回值</td> <td><p>如果查询错误返回false</p><br/><p>如果删除成功返回影响的记录数</p></td> </tr><tr><td>相关方法</td> <td>通常配合连贯操作where、field、order等一起使用</td> </tr></table>
示例如下:`$User = M("User"); // 实例化User对象
$User->where('id=5')->delete(); // 删除id为5的用户数据
$User->where('status=0')->delete(); // 删除所有状态为0的用户数据`delete方法可以用于删除单个或者多个数据,主要取决于删除条件,也就是where方法的参数,也可以用order和limit方法来限制要删除的个数,例如:`// 删除所有状态为0的5 个用户数据 按照创建时间排序
$User->where('status=0')->order('create_time')->limit('5')->delete(); `
[上一页](# "上一页")[下一页](# "下一页")
- 序言
- 1. 入门
- 1.1 简介
- 1.2 基础概念
- 1.3 获取ThinkPHP
- 1.4 环境要求
- 1.5 许可协议
- 1.6 目录结构
- 1.7 命名规范
- 1.8 MVC分层
- 1.9 CBD架构
- 1.10 特性概述
- 1.11 系统流程
- 1.12 开发流程
- 2. 入口
- 2.1 入口文件
- 2.2 项目目录
- 2.3 部署目录
- 2.4 项目编译
- 2.5 调试模式
- 3. 配置
- 3.1 配置格式
- 3.2 惯例配置
- 3.3 项目配置
- 3.4 调试配置
- 3.5 分组配置
- 3.6 读取配置
- 3.7 动态配置
- 3.8 扩展配置
- 4. 函数和类库
- 4.1 函数库
- 4.2 类库
- 5. 控制器
- 5.1 URL模式
- 5.2 模块和操作
- 5.3 定义控制器
- 5.4 空操作
- 5.5 空模块
- 5.6 模块分组
- 5.7 URL伪静态
- 5.8 URL路由
- 5.9 URL重写
- 5.10 URL生成
- 5.11 URL大小写
- 5.12 前置和后置操作
- 5.13 跨模块调用
- 5.14 页面跳转
- 5.15 重定向
- 5.16 获取系统变量
- 5.17 判断请求类型
- 5.18 获取URL参数
- 5.19 AJAX返回
- 5.20 Action参数绑定
- 5.21 多层控制器支持
- 6. 模型
- 6.1 模型定义
- 6.2 模型实例化
- 6.3 字段定义
- 6.4 数据主键
- 6.5 属性访问
- 6.6 跨库操作
- 6.7 连接数据库
- 6.8 切换数据库
- 6.9 分布式数据库
- 6.10 创建数据
- 6.11 字段映射
- 6.12 连贯操作
- 6.13 CURD操作
- 6.14 ActiveRecord
- 6.15 自动验证
- 6.16 命名范围
- 6.17 自动完成
- 6.18 查询语言
- 6.19 查询锁定
- 6.20 字段排除
- 6.21 事务支持
- 6.22 高级模型
- 6.23 视图模型
- 6.24 关联模型
- 6.25 Mongo模型
- 6.26 动态模型
- 6.27 虚拟模型
- 6.28 多层模型支持
- 7. 视图
- 7.1 模板定义
- 7.2 模板赋值
- 7.3 模板输出
- 7.4 模板替换
- 7.5 获取内容
- 7.6 模板引擎
- 7.7 布局模板
- 8. 模板引擎
- 8.1 变量输出
- 8.2 系统变量
- 8.3 使用函数
- 8.4 默认值输出
- 8.5 使用运算符
- 8.6 内置标签
- 8.7 包含文件
- 8.8 导入文件
- 8.9 Volist标签
- 8.10 Foreach标签
- 8.11 For标签
- 8.12 Switch标签
- 8.13 比较标签
- 8.14 三元运算
- 8.15 范围判断标签
- 8.16 Present标签
- 8.17 Empty标签
- 8.18 Defined标签
- 8.19 Define标签
- 8.20 Assign标签
- 8.21 IF标签
- 8.22 标签嵌套
- 8.23 使用PHP代码
- 8.24 模板布局
- 8.25 模板继承
- 8.26 原样输出
- 8.27 模板注释
- 8.28 引入标签库
- 8.29 修改定界符
- 8.30 避免JS混淆
- 9. 日志
- 9.1 日志级别
- 9.2 记录方式
- 9.3 手动记录
- 10. 错误
- 10.1 异常处理
- 10.2 异常模板
- 10.3 异常显示
- 11. 调试
- 11.1 运行状态
- 11.2 页面Trace
- 11.3 调试方法
- 12. 缓存
- 12.1 缓存方式
- 12.2 动态缓存
- 12.3 缓存队列
- 12.4 快捷缓存
- 12.5 快速缓存
- 12.6 查询缓存
- 12.7 SQL解析缓存
- 12.8 静态缓存
- 13. 扩展
- 13.1 行为扩展
- 13.2 类库扩展
- 13.3 控制器扩展
- 13.4 模型扩展
- 13.5 驱动扩展
- 13.6 Widget扩展
- 13.7 模式扩展
- 13.8 引擎扩展
- 14. 安全
- 14.1 表单令牌
- 14.2 字段类型验证
- 14.3 防止SQL注入
- 14.4 输入过滤
- 14.5 上传安全
- 14.6 防止XSS攻击
- 14.7 其他安全建议
- 14.8 目录安全文件
- 14.9 保护模板文件
- 15. 性能
- 15.1 关闭调试模式
- 15.2 开启缓存
- 15.3 合并字段缓存
- 15.4 优化SQL
- 15.5 替换入口
- 15.6 前端优化
- 16. 部署
- 16.1 PATH_INFO支持
- 16.2 隐藏index.php
- 16.3 二级域名部署
- 16.4 定制错误页面
- 16.5 设置时区
- 17. SAE支持
- 17.1 SAE介绍
- 17.2 获取SAE
- 17.3 SAE开发
- 18. REST支持
- 18.1 REST介绍
- 18.2 REST模式
- 18.3 REST配置
- 18.4 REST路由
- 18.5 REST方法
- 19. 杂项
- 19.1 Session支持
- 19.2 Cookie支持
- 19.3 日期和时间
- 19.4 WML开发
- 19.5 多语言
- 19.6 数据分页
- 19.7 文件上传
- 19.8 验证码
- 19.9 图片添加水印
- 19.10 IP获取和定位
- 20. 附录
- 20.1 常量参考
- 20.2 配置参考
- 20.3 关于升级
- 20.4 大事记
- 鸣谢
- 关于