Active Record 模型是一种设计模式,用面向对象的方式抽象地访问数据库的模式。
在插入记录的时候,使用new关键字创建AR 模型对象;
在查询、更新、删除的时候,都是用find()方法创建对象。 为了更好地理解save()方法,我们查看一下vendoryiisoftyyiwdbBaseActiveRecord.php代码
代码语言:javascript复制 public function save($runValidation = true, $attributeNames = null)
{
if ($this->getIsNewRecord()) {
return $this->insert($runValidation, $attributeNames);
}
return $this->update($runValidation, $attributeNames) !== false;
}
当使用“new”关键字创建ActiveRecord 实例对象时则“$this->getIsNewRecord()”返回true,执行插入操作,否则执行更新操作。 随机小技巧
当表单提交操作时,如出现“Unable to verfy your data submission”错误,是被Yii2框架的CSRF验证拦截了。我们可以在控制器中把成员属性"public $enableCsrfValidation = false;"禁用。
属性 | 类别 | 描述 |
---|---|---|
alias | string | 表别名 |
distinct | boolean | 是否只选赞不相同的数据行 |
groupBy | string | 如何进行分组查询结果 |
having | string | 作为GROUP-BY子句的条件 |
indexBy | string | 作为查询结果数组的索引 |
join | string | 如何加入其他的表 |
limit | integer | 要返回最多记录数 |
offset | integer | 要返回从0开始的偏移量 |
orderBy | string | 如何对结果进行排序 |
paranms | array | 以参数占位符为索引的查询参数列表 |
select | mixed | 被选中的列 |
with | mixed | 相关联的查询标准 |
列举一段代码来说明:
代码语言:javascript复制<?php
namespace appcontrollers;
use appmodelsArticle;
use yiidbActiveQuery;
use yiiwebController;
class ArticleController extends Controller
{
public function actionQuery()
{
$rows = new ActiveQuery(Article::tableName());
$rows->select = ['id', 'title'];
$rows->where = 'cid=:cid';
$rows->params = [':cid' => 1];
$article = $rows->one();
return $this->render('article', ['list' => $article]);
}
}
在实际应用查询构建类 构建查询语句时,更多的使用ActiveQuery类的成员方法。
ActiveQuery成员方法简介
方法名 | 返回值类型 | 描述 |
---|---|---|
select() | yiidbQuery | 指定SQL语句当中的SELECT子句 |
from() | yiidbQuery | 指定SQL语句当中的FROM子句 |
where() | yiidbQuery | 指定SQL语句当中的WHERE子句 |
groupBy() | yiidbQuery | 指定SQL语句当中的GROUPBY子句 |
having() | yiidbQuery | 指定SQL语句当中的HAVING子句 |
join() | yiidbQuery | 指定SQL语句当中的JOIN子句 |
limit() | yiidbQuery | 指定SQL语句当中的LIMIT子句 |
offset() | yiidbQuery | 指定SQL语句当中的OFFSET子句 |
orderBy() | yiidbQuery | 指定SQL语句当中的ORDERBY子句 |
union() | yiidbQuery | 指定SQL语句当中的UNION子句 |
ActiveQuery常用返回结果集的成员方法
方法名 | 返回值类型 | 描述 |
---|---|---|
all() | array | 执行查询语句,并且以数组形式返回所有查询结果集 |
one() | yiidbActiveRecord array null | 执行程序语句,返回一条程序结果集 |
column() | array | 执行查询语句,返回结果集的第一列 |
scalar() | string null false | 返回结果集的第一行第一列的标量值 |
exists() | boolean | 判断结果集是存在 |
count() | integer string | 返回SQL语句COUNT查询的结果 |
Query 类的where()成员方法简介 “where()”方法用法比较复杂,我们详细去说明一下。
where()成员方法属于yiidbActiveQuery的父类yiidbQuery。
成员方法where(),public Query where($condition, $params = [])
$condition | string array yiidbExpression | 用来指定SQL语句当中的WJHERE子句 |
---|---|---|
$params | yiidbQuery | 当前Query实例对象 |
{return} | yiidbQuery | 当前Query实例对象 |
下面介绍常用的写法:
在定义非常简单的查询条件的时候,字符串格式是最适合的。
代码语言:javascript复制//查询栏目ID为7的文章表的记录
$news = Article::find()
->where('cid=7')
->one();
数组格式最适合指定多个“and”串联。
代码语言:javascript复制//SELECT * FROM `ds_article` WHERE (`cid`=6) AND (`title`='家用电器')
$news = Article::find()
->where(['cid' => 6, 'title' => '家用电器'])
->one();
操作符格式允许指定类程序风格的任意条件语句
and: 操作数会被“and”关键字串联起来。
代码语言:javascript复制例如['and','id=1','id'=2']将会生成id=1 AND id = 1, 如果操作是一个数组,它也会转化字符串。例如,['and', 'type=1',['or','id=1','id=2']]将会生成type=1 AND (id=1 OR id=2)
between: 第一个操作数为字段名称,第二格和第三个操作数代表的是这个字段的取值范围。
代码语言:javascript复制例如: ['between','id',1,10]将会生成id BETWEEN 1 AND 10
in: 第一操作数为字段名称或者数据库表达式。第二个操作数既可以是一个数组,也可以是一个Query对象。如第二个操作数是一个数组,那么它代表的是取值范围。如果第二个操作数是Query对象,那么这个子查询的结果将会作为取值范围。
代码语言:javascript复制例如:['in','id',[1,2,3]] 将生成id IN(1,2,3)
like: 第一个操作数应为一个字段名或数据库表达式,第二个操作数可以是字符串或数组,代表第一个操作数需要模糊查询的值。
代码语言:javascript复制例如: ['like','name','tester']会生成 name LIKE "%tester%"
如果单位制是一个数组,那么将会生成应“and” 串连起来的多个“like”语句。
例如: ['like','name',['test','sample']] 将会生成name LIKE "%test%" AND name LIKE "%smple%"
or like: 用法和like 操作符类似,区别在于当第二个操作数为数组时,会使用OR 来串联多个“like” 条件语句。 not like: 用法和“like” 操作符类似,区别在于会使用“NOT LIKE”来生成条件语句。 or not like: 用法和“not like” 操作符类似,区别在于会使用OR 来串联多个“not like” 条件语句。 exists:该操作数必须是代表子查询yiidbQuery的一个实例,会构建一个EXISTS表达式。 not exists:该操作数必须是代表子查询yiidbQuery的一个实例,会构建一个NOT EXISTS表达式。 >或 <=:第一个操作数必须为字段的名称,第二个操作数则应该为一个值。
代码语言:javascript复制 例如: ['>','age',10] 将会生成 age > 10
关联查询 场景:order表中的主键id 对应 order_log表中的 order_id,现在查询order表关联order_log中id=121的数据。 hasMany() 一对多 、 hasOne() 一对一
代码语言:javascript复制<?php
namespace appmodels;
use yiidbActiveRecord;
class Order extends ActiveRecord
{
public static function tableName()
{
return "{{order}}";
}
public function getOrderLog()
{
// return self::find()->leftJoin('order_log','order_log.order_id=order.id')->asArray()->all();
return $this->hasMany(OrderLog::className(),['order_id' => 'id']);
}
public function getList()
{
return self::find()->where('id = 121')->with('orderLog')->asArray()->all();
}
}
控制器中调用:
echo "<pre>";
print_r((new Order())->list);
Array
(
[0] => Array
(
[id] => 121
[is_del] => 0
[send_time] => 1555904215
[is_cancel] => 0
[is_send] => 1
[is_token] => 1
[token_time] => 1566358763
[orderLog] => Array
(
[0] => Array
(
[id] => 1
[order_id] => 121
[log_msg] => 系统自动收货
[log_ip] => 127.0.0.1
[log_role] => 系统
[log_user] => 服务器
[log_order_state] => 0
[log_time] => 1566358763
)
)
)
)