[[one()]] // 根据查询结果返回查询的第一条记录。
[[all()]] // 根据查询结果返回所有记录。
[[count()]] // 返回记录的数量。
[[sum()]] // 返回指定列的总数。
[[average()]] // 返回指定列的平均值。
[[min()]] // 返回指定列的最小值。
[[max()]] // 返回指定列的最大值。
[[scalar()]] // 返回查询结果的第一行中的第一列的值。
[[column()]] // 返回查询结果中的第一列的值。
[[exists()]] // 返回一个值,该值指示查询结果是否有数据。
[[where()]] // 添加查询条件
[[with()]] // 该查询应执行的关系列表。
[[indexBy()]] // 根据索引的列的名称查询结果。
[[asArray()]] // 以数组的形式返回每条记录。
Customer::find()->one(); // 此方法返回一条数据
Customer::find()->all(); // 此方法返回所有数据
Customer::find()->count(); // 此方法返回记录的数量
Customer::find()->average();// 此方法返回指定列的平均值
Customer::find()->min(); // 此方法返回指定列的最小值
Customer::find()->max(); // 此方法返回指定列的最大值
Customer::find()->scalar(); // 此方法返回值的第一行第一列的查询结果
Customer::find()->column(); // 此方法返回查询结果中的第一列的值
Customer::find()->exists(); // 此方法返回一个值指示是否包含查询结果的数据行
Customer::find()->asArray()->one(); // 以数组形式返回一条数据
Customer::find()->asArray()->all(); // 以数组形式返回所有数据
Customer::find()->where($condition)->asArray()->one(); // 根据条件以数组形式返回一条数据
Customer::find()->where($condition)->asArray()->all(); // 根据条件以数组形式返回所有数据
Customer::find()->where($condition)->asArray()->orderBy('id DESC')->all(); // 根据条件以数组形式返回所有数据,并根据ID倒序
[[ActiveRecord::hasOne()]] //返回对应关系的单条记录
[[ActiveRecord::hasMany()]] //返回对应关系的多条记录
应用场景:
/**
* 客户表Model:CustomerModel
* 订单表Model:OrdersModel
* 国家表Model:CountrysModel
* 首先要建立表与表之间的关系
* 在CustomerModel中添加与订单的关系
*/
Class CustomerModel extends ActiveRecord
{
/**
* 客户和订单是一对多的关系所以用hasMany
* 此处OrdersModel在CustomerModel顶部别忘了加对应的命名空间
* customer_id对应OrdersModel的customer_id字段
* id对应的是CustomerModel的id字段
*/
public function getOrders()
{
return $this->hasMany(OrdersModel::className(), ['customer_id'=>'id']);
}
/**
* 可以定义多个orders的关联数据,返回价格大于100的订单
*/
public function getBigOrders($priceNum=100)
{
return $this->hasMany(OrdersModel::className(), ['customer_id'=>'id'])
->where('price_num>:threshold', [':threshold' => $threshold]);
}
/**
* 客户和国家是一对一的关系所以用hasOne
*/
public function getCountry()
{
return $this->hasOne(CountrysModel::className(), ['country_id'=>'id']);
}
}
/**
* 查询单表数据,调用相关数据,再重新查询SQL
* 上面的代码会生成如下sql语句
* SELECT * FROM customer
* SELECT * FROM country WHERE id=1;
* 如果下一次调用$customer->getCountry()时,不想使用被缓存的数据,可以使用unset($customer->country);来清除缓存,那么下次调用则会重新执行查询SQL。
*/
$customer = CustomerModel::find();
var_dump($customer->getCountry()); // 第一次使用,会进行SQL查询
var_dump($customer->getCountry()) // 第二次使用,因为被缓存了,直接调用。
var_dump($customer->orders); //如果以属性的方式调用,会直接返回模型的结果
var_dump($customer->bigOrders); //关联数据中价格大于100的订单,
var_dump($customer->getBigOrders(200)->all()); //关联数据中价格大于200的订单,如果以函数的方式调用,会返回一个 ActiveQuery 对象
// 在SQL中一次性级联查询,调用相关数据,都直接在查询出来的数据中直接获取
// 查询客户与他们的订单和国家
$customerList = CustomerModel::find()->with('orders', 'country')->all();
foreach($customerList as $customer){
// 调用时,则不会请求SQL查询,因为已经在上一个步骤查询并缓存好了。
var_dump($customer->orders);
var_dump($customer->country);
}
// 查询客户与他们的订单和订单的发货地址
CustomerModel::find()->with('orders.address')->all();
// 查询客户与他们的国家和状态为1的订单
CustomerModel::find()->with([
'orders' => function ($query) {
$query->andWhere('status = 1');
},
'country',
])->all();
// 1. 在查询时加了->select();如下,要加上order_id,即关联的字段(比如:order_id)比如要在select中,否则会报错:undefined index order_id
// 查询客户与他们的订单和国家
CustomerModel::find()->select('order_id,id,name')->with('orders')->all();
// 1. 查询一个客户大于100的订单,可使用ActiveQuery方式
//首先执行sql: SELECT * FROM customer WHERE id=1
$customer = Customer::findOne(1);
// 再执行查询订单的sql语句:SELECT * FROM order WHERE customer_id=1 AND subtotal>100
$orders = $customer->getOrders()->where('price_num>100')->all();
// 2. 查询100个客户的,每个客户的价格大于100的订单
// 下面的代码会执行sql语句:
// SELECT * FROM customer LIMIT 100
// SELECT * FROM order WHERE customer_id IN (1,2,...) AND subtotal>100
$customerList = Customer::find()->limit(100)->with([
'orders' => function($query) {
$query->andWhere('price_num>100');
},
])->all();
// 在SQL中一次性级联查询,调用相关数据,都直接在查询出来的数据中直接获取
// 查询客户与他们的订单和国家
$customerList = CustomerModel::find()->joinWith('orders')->all();
foreach($customerList as $customer){
//调用时,则不会请求SQL查询,因为已经在上一个步骤查询并缓存好了。
var_dump($customer->orders);
var_dump($customer->country);
}
with方式原理流程: 总共执行了2条SQL语句: A) 先执行主表SQL:SELECT * FROM order B) 再执行关联表SQL:SELECT * FROM user WHERE user_id IN (1,2,…) C) 再通过关联表SQL数据进行内存分配到各自的主表的每条数据上。
joinWith方式: 流程和with一样。只有A步骤不一样,A步骤的主表查询出使用的是关联SQL查询,如
SELECT * FROM order LEFT JOIN user ON order.user_id=[user.id](http://user.id)
// 查询key值为10的客户
$customer = Customer::findOne(10);
$customer = Customer::find()->where(['id' => 10])->one();
// 查询年龄为30,状态值为1的客户
$customer = Customer::findOne(['age' => 30, 'status' => 1]);
$customer = Customer::find()->where(['age' => 30, 'status' => 1])->one();
// 查询key值为10的所有客户
$customers = Customer::findAll(10);
$customers = Customer::find()->where(['id' => 10])->all();
// 查询key值为10,11,12的客户
$customers = Customer::findAll([10, 11, 12]);
$customers = Customer::find()->where(['id' => [10, 11, 12]])->all();
// 查询年龄为30,状态值为1的所有客户
$customers = Customer::findAll(['age' => 30, 'status' => 1]);
$customers = Customer::find()->where(['age' => 30, 'status' => 1])->all();
$customers = Customer::find()->where($cond)->all(); $cond写法举例:
// SQL: (type = 1) AND (status = 2).
$cond = ['type' => 1, 'status' => 2]
// SQL: (id IN (1, 2, 3)) AND (status = 2)
$cond = ['id' => [1, 2, 3], 'status' => 2]
// SQL: status IS NULL
$cond = ['status' => null]
// SQL: id=1 AND id=2
$cond = ['and', 'id=1', 'id=2']
// SQL: type=1 AND (id=1 OR id=2)
$cond = ['and', 'type=1', ['or', 'id=1', 'id=2']]
// SQL: (type IN (7, 8, 9) OR (id IN (1, 2, 3)))
$cond = ['or', ['type' => [7, 8, 9]], ['id' => [1, 2, 3]]
// SQL: NOT (attribute IS NULL)
$cond = ['not', ['attribute' => null]]
//SQL: id BETWEEN 1 AND 10
$cond = ['between', 'id', 1, 10]
// SQL: id IN (1, 2, 3)
$cond = ['in', 'id', [1, 2, 3]]
// IN 条件也适用于多字段
$cond = ['in', ['id', 'name'], [['id' => 1, 'name' => 'foo'], ['id' => 2, 'name' => 'bar']]]
// 也适用于内嵌sql语句
$cond = ['in', 'user_id', (new Query())->select('id')->from('users')->where(['active' => 1])]
// SQL: name LIKE '%tester%'
$cond = ['like', 'name', 'tester']
// SQL: name LIKE '%test%' AND name LIKE '%sample%'
$cond = ['like', 'name', ['test', 'sample']]
// SQL: name LIKE '%tester'
$cond = ['like', 'name', '%tester', false]
// SQL: EXISTS (SELECT "id" FROM "users" WHERE "active"=1)
$cond = ['exists', (new Query())->select('id')->from('users')->where(['active' => 1])]
此外,您可以指定任意运算符如下
// SQL: id >= 10
$cond = ['>=', 'id', 10]
// SQL: id != 10
$cond = ['!=', 'id', 10]
// WHERE admin_id >= 10 LIMIT 0,10
User::find()->select('*')->where(['>=', 'admin_id', 10])->offset(0)->limit(10)->all()
// SELECT `id`, (SELECT COUNT(*) FROM `user`) AS `count` FROM `post`
$subQuery = (new Query())->select('COUNT(*)')->from('user');
$query = (new Query())->select(['id', 'count' => $subQuery])->from('post');
// SELECT DISTINCT `user_id` ...
User::find()->select('user_id')->distinct();
// update();
// runValidation boolen 是否通过validate()校验字段 默认为true
// attributeNames array 需要更新的字段
$model->update($runValidation , $attributeNames);
// updateAll();
// update customer set status = 1 where status = 2
Customer::updateAll(['status' => 1], 'status = 2');
// update customer set status = 1 where status = 2 and uid = 1;
Customer::updateAll(['status' => 1], ['status'=> '2','uid'=>'1']);
$model = Customer::findOne($id);
$model->delete();
$model->deleteAll(['id'=>1]);
Yii::$app->db->createCommand()->batchInsert(
UserModel::tableName(),
['user_id','username'],
[
['1','test1'],
['2','test2'],
['3','test3']
]
)->execute();
普通事务,用于与 ajaxbtn 结合
public function saveWithTrans()
{
$transaction = Yii::$app->db->beginTransaction();
$errors = [];
try {
//1.事件一todo~~~
if(!$this->save()){
$errors = $this->errors;
throw new \Exception();
}
//2.事件二todo~~~
$arr = explode(',', $this->tag);
Tag::deleteAll(['in', 'name', $arr]);
//3.事件三todo~~~
foreach ($arr as $val){
$model = new Tag();
$model->id = CommonUtil::uuid();
$model->name = $val;
if(!$model->save()){
$errors = $model->errors;
throw new \Exception();
}
}
$transaction->commit();
} catch (\Exception $e) {
$transaction->rollBack();
}
return $errors;
}
// 调用方法
if (!empty($errors = $model->saveWithTrans())) {
jsonFail($errors);
}
jsonSuccess();
// 当调用该事务方法后,得到errors的返回值,如果返回值为空,则执行成功,不为空,则表示有错误,则可以将错误进行打印处理。
API事务,常用于API调用的时候,当然AJAXBTN也能用。
public function saveWithTrans()
{
$transaction = Yii::$app->db->beginTransaction();
$error = '';
try {
//1.事件一todo~~~
if(!$this->save()){
$error = firstError($this);
throw new \Exception();
}
//2.事件二todo~~~
$arr = explode(',', $this->tag);
Tag::deleteAll(['in', 'name', $arr]);
//3.事件三todo~~~
foreach ($arr as $val){
$model = new Tag();
$model->id = CommonUtil::uuid();
$model->name = $val;
if(!$model->save()){
$error = firstError($model);
throw new \Exception();
}
}
$transaction->commit();
} catch (\Exception $e) {
$transaction->rollBack();
}
return $error;
}
// 调用方法
if (!empty($error = $model->saveWithTrans())) {
jsonFail($error);
}
jsonSuccess();
// 当调用该事务方法后,得到error的返回值,如果返回值为空,则执行成功,不为空,则表示有错误,则可以将错误进行打印处理。
// UserModel
$query = UserModel::find()->where(['status'=>1]);
echo $query->createCommand()->getRawSql();
(完)