YII2.0 AcriveRecord的简单使用
yii2 2017-02-07 13:34:46

参考文档:http://www.yiiframework.com/doc-2.0/yii-db-activequery.html

参考文档:http://www.yiichina.com/doc/guide/2.0/db-dao 

参考文档:https://getyii.com/topic/358

基础查询 / findBySql()

条件查询

增删改查

  1. 新增
  2. 删除
  3. 修改

事务处理(简单实例) 

使用sql执行,适用于跨db 

保存之前 / 更新之前 / 插入之前 / 更新以后 / 插入以后

根据条件,查找指定的字段

使用with 加关联条件 

yii2 使用find_in_set查询语句

yii2 查询单个字段成集合

yii2 查询sql时,字段被强制加反引号`导致SQL执行失败

yii2 使用in查询时,按照in里面的条件排序

yii2 使用find,update静态方法时,命名空间通过变量名传参使用方式

 

基础查询

PHP Code复制内容到剪贴板
  1. Customer::find()->one();    此方法返回一条数据;  
  2.   
  3. Customer::find()->all();    此方法返回所有数据;  
  4.   
  5. Customer::find()->count();    此方法返回记录的数量;  
  6.   
  7. Customer::find()->average();    此方法返回指定列的平均值;  
  8.   
  9. Customer::find()->min();    此方法返回指定列的最小值 ;  
  10.   
  11. Customer::find()->max();    此方法返回指定列的最大值 ;  
  12.   
  13. Customer::find()->scalar();    此方法返回值的第一行第一列的查询结果;  
  14.   
  15. Customer::find()->column();    此方法返回查询结果中的第一列的值;  
  16.   
  17. Customer::find()->exists();    此方法返回一个值指示是否包含查询结果的数据行;  
  18.   
  19. Customer::find()->batch(10);  每次取10条数据   
  20.   
  21. Customer::find()->each(10);  每次取10条数据,迭代查询   
  22.   
  23. //根据sql语句查询:查询name=test的客户  
  24. Customer::model()->findAllBySql("select * from customer where name = test");   
  25.   
  26. //根据主键查询:查询主键值为1的数据  
  27. Customer::model()->findByPk(1);   
  28.   
  29. //根据条件查询(该方法是根据条件查询一个集合,可以是多个条件,把条件放到数组里面)   
  30. Customer::model()->findAllByAttributes(['username'=>'admin']);   
  31.   
  32. //子查询  
  33. $subQuery = (new Query())->select('COUNT(*)')->from('customer');  
  34. // SELECT `id`, (SELECT COUNT(*) FROM `customer`) AS `count` FROM `customer`  
  35. $query = (new Query())->select(['id''count' => $subQuery])->from('customer');  
  36.   
  37. //关联查询:查询客户表(customer)关联订单表(orders),条件是status=1,客户id为1,从查询结果的第5条开始,查询10条数据  
  38. $data = (new Query())  
  39.     ->select('*')  
  40.     ->from('customer')  
  41.     ->join('LEFT JOIN','orders','customer.id = orders.customer_id')  
  42.     ->where(['status'=>'1','customer.id'=>'1'])  
  43.     ->offset(5)  
  44.     ->limit(10)  
  45.     ->all()  

 use yii\db\Query;

 

PHP Code复制内容到剪贴板
  1. <?php  
  2. $plans = ModPlan::find()  
  3.     ->from(["plan" => ModPlan::tableName()])    //设置别名  
  4.     //->select("plan.*,enroll.plan_id as en_plan_id,enroll.limited")  
  5.     ->where($conditions)  
  6.     ->leftJoin(Enroll::tableName()." AS enroll","enroll.plan_id=plan.plan_id")  
  7.     ->limit($perpage)  
  8.     ->offset($offset)  
  9.     ->indexBy('plan_id')  
  10.     ->orderBy('plan_bt desc');  
  11. //          ->asArray()  
  12. //          ->all();  
  13.   
  14. print_r($plans->createCommand()->getRawSql());  
  15.   
  16. echo '<hr>';  
  17.   
  18. // 省掉asArray 转换这一步  
  19. $plans = (new \yii\db\Query())  
  20.     ->select('*')  
  21.     ->from('plan as pl')  
  22.     ->join('LEFT JOIN','pl_enroll as en','en.plan_id = pl.plan_id')  
  23.     ->where(['pl.plan_id'=>'4'])  
  24.     ->offset(5)  
  25.     ->limit(10);  
  26. //->all();  
  27.   
  28.   
  29. print_r($plans->createCommand()->getRawSql());  
  30. //print_r($plans);  
  31. die;  

 

打印SQL语句:

PHP Code复制内容到剪贴板
  1. $model->find()->createCommand()->getRawSql();  

 

在生成的model中,查询指定ID的一条查询为:

PHP Code复制内容到剪贴板
  1. $model = $this->findModel($id);  

 

想要将它转换为数组就发现asArray()失效了,或者报错了,这时候可以用:(不推荐)

PHP Code复制内容到剪贴板
  1. $model = $this->findModel($id);  
  2. $model->attributes;  

 

findBySql()  

PHP Code复制内容到剪贴板
  1. $customers = Customer::findBySql('SELECT * FROM customer')->all();  

 

 

加入where查询

基础语句:

PHP Code复制内容到剪贴板
  1. $customers = Customer::find()->where($cond)->all();   
  2.   
  3. // $cond就是我们所谓的条件,条件的写法也根据查询数据的不同存在差异,那么如何用yii2的方式来写查询条件呢?  

 

简单条件: 

PHP Code复制内容到剪贴板
  1. // SQL: (type = 1) AND (status = 2).  
  2. $cond = ['type' => 1, 'status' => 2]   
  3.   
  4. // SQL:(id IN (1, 2, 3)) AND (status = 2)  
  5. $cond = ['id' => [1, 2, 3], 'status' => 2]   
  6.   
  7. //SQL:status IS NULL  
  8. $cond = ['status' => null]  

 

and 将不同的条件组合在一起,用法举例:

PHP Code复制内容到剪贴板
  1. //SQL:`id=1 AND id=2`  
  2. $cond = ['and''id=1''id=2']  
  3.   
  4. //SQL:`type=1 AND (id=1 OR id=2)`  
  5. $cond = ['and''type=1', ['or''id=1''id=2']]  
  6.   
  7. //SQL:`type=1 AND (id=1 OR id=2)` //此写法'='可以换成其他操作符,例:in like != >=等  
  8. $cond = [  
  9.     'and',  
  10.     ['=''type', 1],  
  11.     [  
  12.         'or',  
  13.         ['=''id''1'],  
  14.         ['=''id''2'],  
  15.     ]  
  16. ]  

 

or

PHP Code复制内容到剪贴板
  1. //SQL:`(type IN (7, 8, 9) OR (id IN (1, 2, 3)))`  
  2. $cond = ['or', ['type' => [7, 8, 9]], ['id' => [1, 2, 3]]  

 

not

PHP Code复制内容到剪贴板
  1. //SQL:`(type IN (7, 8, 9) OR (id IN (1, 2, 3)))`  
  2. $cond = ['or', ['type' => [7, 8, 9]], ['id' => [1, 2, 3]]  

 

between

PHP Code复制内容到剪贴板
  1. //SQL:`id BETWEEN 1 AND 10`  
  2. $cond = ['between''id', 1, 10]  

 

in 与 not in用法类似

PHP Code复制内容到剪贴板
  1. //SQL:`id IN (1, 2, 3)`  
  2. $cond = ['in''id', [1, 2, 3]] or $cond = ['id'=>[1, 2, 3]]  
  3.   
  4. //IN条件也适用于多字段  
  5. $cond = ['in', ['id''name'], [['id' => 1, 'name' => 'foo'], ['id' => 2, 'name' => 'bar']]]  
  6.   
  7. //也适用于内嵌sql语句  
  8. $cond = ['in''user_id', (new Query())->select('id')->from('users')->where(['active' => 1])]  

 

like

PHP Code复制内容到剪贴板
  1. //SQL:`name LIKE '%tester%'`  
  2. $cond = ['like''name''tester']  
  3.   
  4. //SQL:`name LIKE '%test%' AND name LIKE '%sample%'`  
  5. $cond = ['like''name', ['test''sample']]  
  6.   
  7. //SQL:`name LIKE '%tester'`  
  8. $cond = ['like''name''%tester', false]  

 

exists 与 not exists用法类似

PHP Code复制内容到剪贴板
  1. //SQL:EXISTS (SELECT "id" FROM "users" WHERE "active"=1)  
  2. $cond = ['exists', (new Query())->select('id')->from('users')->where(['active' => 1])]  

 

isnull

SQL Code复制内容到剪贴板
  1. $cond = ['IS','name',null];  

 

 

此外,您可以指定任意运算符如下

PHP Code复制内容到剪贴板
  1. //SQL:`id >= 10`  
  2. $cond = ['>=''id', 10]  
  3.   
  4. //SQL:`id != 10`  
  5. $cond = ['!=''id', 10]  

 

 删改查

 

新增

使用model::save()操作进行新增数据

PHP Code复制内容到剪贴板
  1. $usernew User;           
  2. $user->username =$username;    
  3. $user->password =$password;    
  4. $user->save()  

或:

rules规则参照

PHP Code复制内容到剪贴板
  1. <?php  
  2.   
  3. /** 
  4.  * model层 
  5.  * 一定要把字段定义在model层rouls方法中 
  6.  * 使用setAttributes的第二个参数$safeOnly,设置为false,表示不检测字段安全 
  7. $model->setAttributes(array('title'=>'小白','content'=>'lala'),false);  
  8.  */  
  9.   
  10. public function rules(){  
  11.     return [  
  12.         [['user_id''readed''modifie_user''published'], 'integer'],  
  13.         [['user_name''title''meta_rule'], 'string''max' => 32],  
  14.         [['abstract'], 'string''max' => 512],  
  15.         [['image''meta_title'], 'string''max' => 128],  
  16.         [['context'], 'string''max' => 8192],  
  17.         [['meta_keyword''meta_description'], 'string''max' => 256],  
  18.         [['meta_title','meta_keyword','meta_description','image'], 'default''value' => ''],  
  19.         [['title','context'], 'required']  
  20.     ];  
  21. }  
  22.   
  23. public function add($data){  
  24.     $this->setAttributes($data);  
  25.     $this->isNewRecord = true;  
  26.     $this->save();  
  27.     return $this->id;  
  28. }  
  29.   
  30.   
  31. //入库二维数组  
  32. public function addAll($data){  
  33.     $ids=array();  
  34.     foreach($data as $attributes)  
  35.     {  
  36.         $this->isNewRecord = true;  
  37.         $this->setAttributes($attributes);  
  38.         $this->save()&& array_push($ids,$this->id) && $this->id=0;  
  39.     };  
  40.     return $ids;  
  41. }  
  42.   
  43.   
  44. /** 
  45.  * 控制器 
  46.  */  
  47. public function actionAdd(){  
  48.     $model = new Model();  
  49.     $data = array(  
  50.         "title"=>"小白",  
  51.         "content"=>"lala"  
  52.     );  
  53.     $id = $model->add($data);  
  54.     echo $id;  
  55.   
  56. //    $data=array(  
  57. //        array(  
  58. //            "title"=>"小白",  
  59. //            "content"=>"lala"  
  60. //        ),  
  61. //        array(  
  62. //            "title"=>"小hong",  
  63. //            "content"=>"66"  
  64. //        )  
  65. //    );  
  66. //    $ids=$model->addAll($data);  
  67. //    var_dump($ids);  
  68. }  

 

updateAll()

For example, to change the status to be 1 for all customers whose status is 2

PHP Code复制内容到剪贴板
  1. Customer::updateAll(['status' => 1], 'status = 2');  

 

批量设置指定字段加1

PHP Code复制内容到剪贴板
  1. // 所有客户的age(年龄)字段加1:  
  2. Customer::updateAllCounters(['age' => 1]);  

 

用于数字类型,将值进行 累加 或者 累减

$count = 1, 就是加一

$count = -1, 就是减一

User::updateAllCounters(['sort' => $count], ['id' => 2]);

 

如果插入失败,打印错误日志:

PHP Code复制内容到剪贴板
  1. if ($model->validate()) {  
  2.     $model->save();  
  3. else {  
  4.     var_dump($model->errors);  
  5. }  

 

  新增失败,打印错误日志:

PHP Code复制内容到剪贴板
  1. <?php  
  2. $model->save();  
  3. if($model->hasErrors()) {  
  4.     print_r($model->errors);  
  5.     exit;  
  6.     throw new Exception($model->hasErrors());  
  7. }  

 

PHP Code复制内容到剪贴板
  1. <?php  
  2. $moduleModel->load(Yii::$app->request->post());  
  3. $moduleModel->id = $model->id;  
  4. $moduleModel->save();  
  5.   
  6. if($moduleModel->hasErrors()) {  
  7.     throw new Exception(current($moduleModel->getFirstErrors()));  
  8.     print_r($moduleModel->error);  
  9.     die;  
  10. }  

 

 

使用createCommand()进行新增数据

PHP Code复制内容到剪贴板
  1. Yii::$app->db->createCommand()->insert('user', [    
  2.     'name' => 'test',    
  3.     'age' => 30,    
  4. ])->execute();  

获取最后一次插入的ID: 

PHP Code复制内容到剪贴板
  1. $model->save();  
  2. //得到上次插入的Insert id  
  3. $id = $model->attributes['id'];  
  4.   
  5. $id = Yii::$app->db->getLastInsertId();  

 

 

批量插入数据

PHP Code复制内容到剪贴板
  1. Yii::$app->db->createCommand()->batchInsert('user', ['name''age'], [    
  2.     ['test01', 30],    
  3.     ['test02', 20],    
  4.     ['test03', 25],    
  5. ])->execute();  

 

第一种方法

PHP Code复制内容到剪贴板
  1. $model = new User();  
  2. foreach($data as $attributes)  
  3. {  
  4.      $_model = clone $model;  
  5.      $_model->setAttributes($attributes);  
  6.      $_model->save();  
  7. }  

第二种

PHP Code复制内容到剪贴板
  1. $model = new User();  
  2. foreach($data as $attributes)  
  3. {  
  4.       $model->isNewRecord = true;  
  5.       $model->setAttributes($attributes);  
  6.       $model->save() && $model->id=0;  
  7. }  

 

 

 

修改

使用model::save()进行修改

PHP Code复制内容到剪贴板
  1. $user = User::find()->where(['name'=>'test'])->one(); //获取name等于test的模型  
  2. $user->age = 40; //修改age属性值  
  3. $user->save();   //保存  

 

直接修改:修改用户test的年龄为40

PHP Code复制内容到剪贴板
  1. $result = User::model()->updateAll(['age'=>40],['name'=>'test']);  

 

使用createCommand()修改

PHP Code复制内容到剪贴板
  1. Yii::$app->db->createCommand()->update('user', ['age' => 40], 'name = test')->execute();  

 

 

 

 

删除

使用model::delete()进行删除

PHP Code复制内容到剪贴板
  1. $user = User::find()->where(['name'=>'test'])->one();   
  2. $user->delete();  

 

直接删除:删除年龄为30的所有用户

PHP Code复制内容到剪贴板
  1. $result = User::deleteAll(['age'=>'30']);  

 

根据主键删除:删除主键值为1的用户

PHP Code复制内容到剪贴板
  1. $result = User::deleteByPk(1);  

 

使用createCommand()删除

PHP Code复制内容到剪贴板
  1. Yii::$app->db->createCommand()->delete('user''age = 30')->execute();  

 

 

PHP Code复制内容到剪贴板
  1. one(): 根据查询结果返回查询的第一条记录。  
  2. all(): 根据查询结果返回所有记录。  
  3. count(): 返回记录的数量。  
  4. sum(): 返回指定列的总数。  
  5. average(): 返回指定列的平均值。  
  6. min(): 返回指定列的最小值。  
  7. max(): 返回指定列的最大值。  
  8. scalar(): 返回查询结果的第一行中的第一列的值。  
  9. column(): 返回查询结果中的第一列的值。  
  10. exists(): 返回一个值,该值指示查询结果是否有数据。  
  11. where(): 添加查询条件  
  12. with(): 该查询应执行的关系列表。  
  13. indexBy(): 根据索引的列的名称查询结果。  
  14. asArray(): 以数组的形式返回每条记录。  

 

应用实例:

PHP Code复制内容到剪贴板
  1. Customer::find()->one();    此方法返回一条数据;  
  2. Customer::find()->all();    此方法返回所有数据;  
  3. Customer::find()->count();    此方法返回记录的数量;  
  4. Customer::find()->average();    此方法返回指定列的平均值;  
  5. Customer::find()->min();    此方法返回指定列的最小值 ;  
  6. Customer::find()->max();    此方法返回指定列的最大值 ;  
  7. Customer::find()->scalar();    此方法返回值的第一行第一列的查询结果;  
  8. Customer::find()->column();    此方法返回查询结果中的第一列的值;  
  9. Customer::find()->exists();    此方法返回一个值指示是否包含查询结果的数据行;  

 

PHP Code复制内容到剪贴板
  1. Customer::find()->asArray()->one();    以数组形式返回一条数据;  
  2. Customer::find()->asArray()->all();    以数组形式返回所有数据;  

 

PHP Code复制内容到剪贴板
  1. Customer::find()->where($condition)->asArray()->one();    根据条件以数组形式返回一条数据;  
  2. Customer::find()->where($condition)->asArray()->all();    根据条件以数组形式返回所有数据;  

 

PHP Code复制内容到剪贴板
  1. Customer::find()->where($condition)->asArray()->orderBy('id DESC')->all();    根据条件以数组形式返回所有数据,并根据ID倒序;  

 

2.关联查询:

PHP Code复制内容到剪贴板
  1. ActiveRecord::hasOne():返回对应关系的单条记录  
  2. ActiveRecord::hasMany():返回对应关系的多条记录  

 

hasone新版更新,classname() 改为 class

如:

PHP Code复制内容到剪贴板
  1. public function getUser(){  
  2.     if($this->aid){  
  3.         return $this->hasOne(PersonnelManage::class,['id'=>'aid']);  
  4.     }  
  5. }  

 

 

应用实例:

PHP Code复制内容到剪贴板
  1. //客户表Model:CustomerModel   
  2. //订单表Model:OrdersModel  
  3. //国家表Model:CountrysModel  
  4. //首先要建立表与表之间的关系   
  5. //在CustomerModel中添加与订单的关系  
  6.         
  7. Class CustomerModel extends yiidbActiveRecord  
  8. {  
  9.     ...  
  10.       
  11.     public function getOrders()  
  12.     {  
  13.         //客户和订单是一对多的关系所以用hasMany  
  14.         //此处OrdersModel在CustomerModel顶部别忘了加对应的命名空间  
  15.         //id对应的是OrdersModel的id字段,order_id对应CustomerModel的order_id字段  
  16.         return $this->hasMany(OrdersModel::className(), ['id'=>'order_id']);  
  17.     }  
  18.        
  19.     public function getCountry()  
  20.     {  
  21.         //客户和国家是一对一的关系所以用hasOne  
  22.         return $this->hasOne(CountrysModel::className(), ['id'=>'Country_id']);  
  23.     }  
  24.     ....  
  25. }  
  26.         
  27. // 查询客户与他们的订单和国家  
  28. CustomerModel::find()->with('orders''country')->all();  
  29. // 查询客户与他们的订单和订单的发货地址  
  30. CustomerModel::find()->with('orders.address')->all();  
  31. // 查询客户与他们的国家和状态为1的订单  
  32. CustomerModel::find()->with([  
  33.     'orders' => function ($query) {  
  34.         $query->andWhere('status = 1');  
  35.         },  
  36.         'country',  
  37. ])->all();  

注:with中的orders对应getOrders

 

left join 的用法:

SELECT `user`.* FROM `xx_enewsuser` `user` LEFT JOIN `xx_enewsuser_profile` `profile` ON user.id = profile.user_id WHERE `profile`.`school_id`=1

PHP Code复制内容到剪贴板
  1. $users = User::find()->alias("user")->leftJoin(Profile::tableName() . " as profile""user.id = profile.user_id")->where(["profile.school_id" => $school_id])->all();  

 

 

 

hasmany加条件:

 

我们还可以在Customer里面定义多个关联。如返回总数大于100的订单。

PHP Code复制内容到剪贴板
  1. class Customer extends \yii\db\ActiveRecord  
  2. {  
  3.     public function getBigOrders($threshold = 100)  
  4.     {  
  5.         return $this->hasMany(Order::className(), ['customer_id' => 'id'])  
  6.             ->where('subtotal > :threshold', [':threshold' => $threshold])  
  7.             ->orderBy('id');  
  8.     }  
  9. }  

 

关联的两种访问方式

如上面的,如果使用

PHP Code复制内容到剪贴板
  1. $customer->bigOrders  

将会得到大于100的所有的订单。如果要返回大于200的订单可以这样写

PHP Code复制内容到剪贴板
  1. $orders = $customer->getBigOrders(200)->all();  

 

从上面可以看出访问一个关联的时候有两种方法

如果以函数的方式调用,会返回一个 ActiveQuery 对象($customer->getOrders()->all())

如果以属性的方式调用,会直接返回模型的结果($customer->orders)

 

给with加过滤条件

PHP Code复制内容到剪贴板
  1. // 查询100个客户的,每个客户的总合大于100的订单  
  2. // 下面的代码会执行sql语句:   
  3. // SELECT * FROM customer LIMIT 100  
  4. // SELECT * FROM order WHERE customer_id IN (1,2,...) AND subtotal>100  
  5. $customers = Customer::find()->limit(100)->with([  
  6.     'orders' => function($query) {  
  7.         $query->andWhere('subtotal>100');  
  8.     },  
  9. ])->all();  

 

PHP Code复制内容到剪贴板
  1. $model = User::find()->where(['id' => $id])->with([  
  2.     "profile" => function($query){  
  3.         $query->select("signature,gender,card_no,phone,address,department_id,job_id");  
  4.     },  
  5.     "profile.department" => function($query){  
  6.         $query->select("id,title,leader,sort");  
  7.     },  
  8.     "profile.job"  
  9. ])->one();  

 

 

 

延迟加载和即时加载(又称惰性加载与贪婪加载)

PHP Code复制内容到剪贴板
  1. $customer = Customer::findOne(1);  
  2. // 延迟加载: SELECT * FROM order WHERE customer_id=1 AND subtotal>100  
  3. $orders = $customer->getOrders()->where('subtotal>100')->all();  
  4.   
  5. // 即时加载: SELECT * FROM customer LIMIT 100  
  6. //          SELECT * FROM order WHERE customer_id IN (1,2,...) AND subtotal>100  
  7. $customers = Customer::find()->limit(100)->with([  
  8.     'orders' => function($query) {  
  9.         $query->andWhere('subtotal>100');  
  10.     },  
  11. ])->all();  

 

 

 

 

常见问题:

1.在查询时加了->select();如下,要加上order_id,即关联的字段(比如:order_id)比如要在select中,否则会报错:undefined index order_id

PHP Code复制内容到剪贴板
  1. // 查询客户与他们的订单和国家  
  2. CustomerModel::find()->select('order_id')->with('orders''country')->all();  

 

findOne()和findAll():

PHP Code复制内容到剪贴板
  1. // 查询key值为10的客户  
  2. $customer = Customer::findOne(10);  
  3. $customer = Customer::find()->where(['id' => 10])->one();  

 

PHP Code复制内容到剪贴板
  1. // 查询年龄为30,状态值为1的客户  
  2. $customer = Customer::findOne(['age' => 30, 'status' => 1]);  
  3. $customer = Customer::find()->where(['age' => 30, 'status' => 1])->one();  

 

PHP Code复制内容到剪贴板
  1. // 查询key值为10的所有客户  
  2. $customers = Customer::findAll(10);  
  3. $customers = Customer::find()->where(['id' => 10])->all();  

 

PHP Code复制内容到剪贴板
  1. // 查询key值为10,11,12的客户  
  2. $customers = Customer::findAll([10, 11, 12]);  
  3. $customers = Customer::find()->where(['id' => [10, 11, 12]])->all();  

 

PHP Code复制内容到剪贴板
  1. // 查询年龄为30,状态值为1的所有客户  
  2. $customers = Customer::findAll(['age' => 30, 'status' => 1]);  
  3. $customers = Customer::find()->where(['age' => 30, 'status' => 1])->all();  

 

根据条件,查找指定的字段: 

PHP Code复制内容到剪贴板
  1. // 根据当前ID 查找parent字段值  
  2. $pid = Menu::findOne(['id'=>$mid])->getAttribute("parent");  

 

 

PHP Code复制内容到剪贴板
  1. return static::find()->select('title')->where(['id' => $this->pid])->scalar();  

 

事务处理,简单实例:

PHP Code复制内容到剪贴板
  1. $transaction = Yii::$app->db->beginTransaction();  
  2. try{  
  3.     //删除$model中的数据  
  4.     $res = $model->deleteAll($cond);  
  5.     if(!$res)  
  6.         throw new \Exception('操作失败!');  
  7.       
  8.     //删除$model对应的$relation中的数据  
  9.     $rt = $relation->deleteAll(['polymeric_id'=>$cond['id']]);  
  10.     if(!$rt)  
  11.         throw new \Exception('操作失败!');  
  12.       
  13.     //以上执行都成功,则对数据库进行实际执行  
  14.     $transaction->commit();   
  15.     return Helper::arrayReturn(['status'=>true]);  
  16. }catch (\Exception $e){  
  17.     //如果抛出错误则进入catch,先callback,然后捕获错误,返回错误  
  18.     $transaction->rollBack();  
  19.     return Helper::arrayReturn(['status'=>false,'msg'=>$e->getMessage()]);  
  20. }  

 

使用sql执行,适用于跨db

PHP Code复制内容到剪贴板
  1. $sql = "SELECT * FROM lime_tokens_".$survey_id." WHERE survey_id = ".$survey_id;  
  2.   
  3. $participants = \Yii::$app->db_survey->createCommand($sql)->queryAll();  
  4.   
  5. return $participants;  

 

PHP Code复制内容到剪贴板
  1. // 删除数据表信息(自增不从1开始)  
  2. \Yii::$app    
  3.     ->db    
  4.     ->createCommand()    
  5.     ->delete($tablename)    
  6.     ->execute();   
  7.   
  8. // 清空数据表(自增从1开始)  
  9. Yii::$app->db->createCommand()->truncateTable($tablename)->execute();  

 

PHP Code复制内容到剪贴板
  1. // 指定表名,是否存在于数据库中:  
  2. $table_name = 'lime_tokens_' . $sid;  
  3. $juge = \Yii::$app->db_survey->createCommand("show tables")->queryAll();  
  4. $cun = $this->deep_in_array($table_name$juge);  
  5. if (!$cun) {  
  6.     return $all_partners;  
  7. };  
  8.   
  9. // 显示数据库中指定表  
  10. $tablename = "lime_tokens_".$survey_id;  
  11. $ta = \Yii::$app->db_survey->createCommand("SHOW TABLES LIKE '" . $tablename . "'")->queryAll();      

 

PHP Code复制内容到剪贴板
  1. //判断二维数组是否存在值  
  2.     public  function deep_in_array($value$array) {     
  3.             foreach($array as $item) {     
  4.                 if(!is_array($item)) {     
  5.                     if ($item == $value) {    
  6.                         return true;    
  7.                     } else {    
  8.                         continue;     
  9.                     }    
  10.                 }     
  11.                      
  12.                 if(in_array($value$item)) {    
  13.                     return true;        
  14.                 } else if($this->deep_in_array($value$item)) {    
  15.                     return true;        
  16.                 }    
  17.             }     
  18.             return false;     
  19.         }  

 

 

 

PHP Code复制内容到剪贴板
  1. $sql = 'SELECT count(*) FROM '.UserLinkProject::tableName()." where project_id=".$projectId;  
  2.         $participants = \Yii::$app->db->createCommand($sql)->queryScalar();  

 

 

 

表前缀

PHP Code复制内容到剪贴板
  1. $id = \Yii::$app->db->createCommand('SELECT `id` FROM {{%menu}} WHERE `name`="插件" AND `parent` IS NULL')->queryScalar();  

 

PHP Code复制内容到剪贴板
  1. $sql     = "SELECT * FROM   tab WHERE id = :id";  
  2. $db      = \Yii::$app->db;  
  3. $command = $db->createCommand($sql, [':id'=>$id]);//方法内部对第二个参数进行PDO参数化,不会导致注入漏洞  
  4. $result  = $command->queryAll();  
  5. var_dump($result);  

 

yii2 使用find,update静态方法时,命名空间通过变量名传参使用方式

使用findOne

PHP Code复制内容到剪贴板
  1. $model = call_user_func([$this->entity, 'findOne'], $this->entity_id);  
  2. return $model;  

 

使用updateAll

PHP Code复制内容到剪贴板
  1. // Enewsworkflowitem::updateAll(["is_qf"=>0],["id"=>$entity_id]);  
  2.   
  3. // Enewsworkflowitem通过变量传参  
  4. $model = call_user_func_array([$entity,"updateAll"],[["is_qf"=>0],["id"=>$entity_id]]);  
  5. return $model;  

 

 

参考示例说明:

PHP Code复制内容到剪贴板
  1. <?php  
  2. function funa($b,$c)  
  3. {  
  4.     echo $b;  
  5.     echo $c;  
  6. }  
  7. call_user_func('funa'"111","222");  
  8. call_user_func('funa'"333","444");  
  9. //显示 111 222 333 444  
  10. //这个用法有点像javascript中的call方法  
  11.   
  12.   
  13.   
  14. //第二种是调用类内部的函数  
  15. class a {  
  16.     function b()  
  17.     {  
  18.         $args = func_get_args();  
  19.         $num = func_num_args();  
  20.         print_r($args);  
  21.         echo $num;  
  22.     }  
  23. }  
  24. call_user_func(array("a""b"),"111","222");  
  25.   
  26.   
  27. // 看看call_user_func_array函数,它的用法和call_user_func函数比较像,只是参数传入的是数组  
  28. function a($b$c)  
  29. {  
  30.     echo $b;  
  31.     echo $c;  
  32. }  
  33. call_user_func_array('a'array("111""222"));  
  34. //显示 111 222  
  35.   
  36.   
  37. // call_user_func_array函数也可以调用类内部的方法的  
  38. Class ClassA  
  39. {  
  40.     function bc($b$c) {  
  41.         $bc = $b + $c;  
  42.         echo $bc;  
  43.     }  
  44.   
  45. }  
  46. call_user_func_array(array(‘ClassA','bc'), array(“111″, “222″));  
  47. //显示 333  

 

 

 

使用with 加关联条件 

PHP Code复制内容到剪贴板
  1. var $condition = 0;//评论数对比条件  
  2. $user= user::find()->with([  
  3.     'articles' => function ($queryuse($condition) {  
  4.         $query->where(['>','comment',$condition]);  
  5.     }  
  6. ])->all();  

 

多表关联查询,加过滤条件

PHP Code复制内容到剪贴板
  1. return $this->owner->hasMany(Tag::className(), ['id' => 'tag_id'])  
  2.             ->viaTable('{{%article_tag}}', ['article_id' => 'id'], function ($query){  
  3.                 $query->onCondition(['is_zt' => 1]);  
  4.             });  

 

PHP Code复制内容到剪贴板
  1. return $this->owner->hasMany(Tag::className(), ['id' => 'tag_id'])  
  2.             ->viaTable('{{%article_tag}}', ['article_id' => 'id'])->andWhere(['is_zt'=>0]);  

 

 

通过关联表查询

主表:cut 

标签表:label

关联表:map

 

cut表:

lable表:

 map关联表:

cutModel 中添加方法:

获取该信息关联的多个label

PHP Code复制内容到剪贴板
  1. public function getLabel(){  
  2.     // label的id 等于 关联表的 label_id  
  3.     // CutMap是关联表,一个cut对应多个label,关联表的cut_id等于 cut表的id  
  4.     return $this->hasMany(CutLabel::className(), ['id' => 'label_id'])  
  5.         ->viaTable(CutMap::tableName(), ['cut_id' => 'id']);  
  6. }  

 

可以加限制条件

PHP Code复制内容到剪贴板
  1. public function getLabel(){  
  2.     // label的id 等于 关联表的 label_id  
  3.     // CutMap是关联表,一个cut对应多个label,关联表的cut_id等于 cut表的id  
  4.     return $this->hasMany(CutLabel::className(), ['id' => 'label_id'])->andWhere(['status'=>1])  
  5.         ->viaTable(CutMap::tableName(), ['cut_id' => 'id']);  
  6. }  

 

 

视图中使用:

第一种:

PHP Code复制内容到剪贴板
  1. $res = Cut::find()->all();  
  2. foreach ($res as $k => $v){  
  3.   
  4.     echo "<pre>";  
  5.         print_r(ArrayHelper::toArray($v));  
  6.   
  7.         print_r(ArrayHelper::toArray($v->label));  
  8.     echo "</pre>";  
  9. }  

 

第二种:

PHP Code复制内容到剪贴板
  1. $res = Cut::find()->with("label")->all();  
  2. foreach ($res as $k => $v){  
  3.   
  4.     echo "<pre>";  
  5.         print_r(ArrayHelper::toArray($v));  
  6.   
  7.         print_r(ArrayHelper::toArray($v->label));  
  8.     echo "</pre>";  
  9. }  

 

有以下sql运行:

SQL Code复制内容到剪贴板
  1. SELECT * FROM `yy_cut`;  
  2. SELECT * FROM `yy_cut_map` WHERE `cut_id`=1;  
  3. SELECT * FROM `yy_cut_label` WHERE `id` IN ('1''2');  

 

 

 

 

 yii2 使用find_in_set查询语句

PHP Code复制内容到剪贴板
  1.         $role = request()->post("role",null);  
  2.   
  3.         $query = AppMenu::find();  
  4.         if($role){  
  5.             $query  
  6.                 ->where(new Expression('FIND_IN_SET(:roe, roe)'))  
  7.                 ->addParams([':roe' => $role]);  
  8.         }  
  9.   
  10. p($query->createCommand()->getRawSql());  
  11.   
  12. // SELECT * FROM `xx_app_menu` WHERE FIND_IN_SET('leader', roe)  

 

yii2 查询指定字段,结果为数组

PHP Code复制内容到剪贴板
  1. $memberIds = ProjectMember::find()->select("user_id")->where(["project_id"=>$model->id])->column();  

结果:

Array
(
    [0] => 1
    [1] => 2

)

如果用->asArray()->all()的话,会返回:

Array
(
    [0] => Array
        (
            [user_id] => 1
        )

    [1] => Array
        (
            [user_id] => 2
        )

) 

 

yii2 查询sql时,字段被强制加反引号`导致SQL执行失败 

PHP Code复制内容到剪贴板
  1. $query = (new Query())  
  2.             ->select("user_id,true_name,nickname,money,gender,phone,mobile,birthday,referrer_user_id,created_at,FROM_UNIXTIME(created_at,'%Y-%m-%d %H:%I:%S') as created")  
  3.             ->from(Profile::tableName())  
  4.             ->orderBy("created_at desc");  

 

<pre>SELECT `user_id`, `true_name`, `nickname`, `money`, `gender`, `phone`, `mobile`, `birthday`, `referrer_user_id`, `created_at`, FROM_UNIXTIME(created_at, `'%Y-%m-%d %H:%I:%S')` AS `created` FROM `ningwang_enewsuser_profile` ORDER BY `created_at` DESC</pre>

WX20200705-220852@2x.png 

 

改成以下new Expression即可:

PHP Code复制内容到剪贴板
  1. $field = "user_id,true_name,nickname,money,gender,phone,mobile,birthday,referrer_user_id,created_at,FROM_UNIXTIME(created_at,'%Y-%m-%d %H:%I:%S') as created";  
  2. $query = (new Query())  
  3.     ->select(new Expression($field))  
  4.     ->from(Profile::tableName())  
  5.     ->orderBy("created_at desc");  

 

yii2 使用in查询时,按照in里面的条件排序 

完整的sql是:

SQL Code复制内容到剪贴板
  1. SELECT * FROM `block_document` WHERE `id` IN ('9''1''2''21''3''4'ORDER BY FIELD (id, 9,1,2,21,3,4)  

 

PHP Code复制内容到剪贴板
  1. // 最新评价  
  2.             $documentIdArray = Comment::find()->select("entity_id")->where(["entity"=>\common\modules\document\models\Document::className()])->groupBy("entity_id")->orderBy("created_at desc")->column();  
  3.             $documentIds = implode(',' , $documentIdArray);  
  4.             $query->andFilterWhere(["in","id",$documentIdArray])  
  5.             ->orderBy([new \yii\db\Expression("FIELD (id, $documentIds)")]);  

注意一下orderBy里面的数据格式,只能是字符串,以逗号隔开

 

查询指定用户参与的全部项目下的,所有用户id,过滤掉相同用户id:

SQL Code复制内容到剪贴板
  1. SELECT   
  2.     DISTINCT user_id  
  3. FROM  
  4.     block_project_user  
  5. WHERE  
  6.     project_id IN (  
  7.         SELECT  
  8.             DISTINCT project_id  
  9.         FROM  
  10.             block_project_user  
  11.         WHERE  
  12.             user_id = 28   
  13.     )  

 

PHP Code复制内容到剪贴板
  1. // 获取当前用户参与的所有项目下的所有用户id  
  2. $userIds = (new Query())  
  3.     ->select('user_id')  
  4.     ->distinct('user_id')  
  5.     ->from(ProjectUser::tableName())  
  6.     ->where(['in''project_id',  
  7.         (new Query())  
  8.             ->select('project_id')  
  9.             ->distinct('project_id')  
  10.             ->from(ProjectUser::tableName())  
  11.             ->where(['in''user_id'$user_id])  
  12.             ->column()  
  13.     ])  
  14.     ->column();  
  15. $query->andWhere(["user_id"=>$userIds]);  

 

WX20200714-180447@2x.png 

 

本文来自于:http://www.yoyo88.cn/study/yii2/75.html

Powered by yoyo苏ICP备15045725号