数据库+模型 - AR模型 ¶
作者:KK
发表日期:2016.12.16
介绍 ¶
AR模型其实是指yii\db\ActiveRecord这个类,它是由yii\base\Model派生出来的,作用是让我们方便地操作数据表里的数据
提示
Model是模型,与数据库无关
模型在不同的应用领域是分为不同级别的,其中ORM模型是我们很经常接触的一种
ActiveRecord是ORM模型的一种实现(ActiveRecord相关论述资料)
前提准备 - 建表 ¶
既然模型是为了方便操作数据表的话,咱们搞张test表来做测试吧
在配置好db组件的情况下先运行一次以下代码,它会创建一张test表:
$migrate = new \yii\db\Migration();
$migrate->createTable('test', [
'id' => $migrate->primaryKey(),
'name' => $migrate->string(10)->notNull()->comment('姓名'),
'age' => $migrate->boolean()->unsigned()->defaultValue(0)->notNull()->comment('年龄'), //mysql的话底层会将boolean转换成tinyint,sqlite的话就是boolean,所以如果用sqlite请改成smallint()或integer()
]);
建立模型 ¶
接下来我们手动创建一个AR模型来操作test表(其实官方提供了一个叫gii的工具,不过我希望大家印象更深刻,齐齐来动手!)
创建一个
app\models\Test
类,继承yii\db\ActiveRecord
定义一个名为tableName公共的静态方法,无参数,返回一个要操作的表名字符串
代码应该是这样的:
namespace app\models;
class Test extends \yii\db\ActiveRecord{
public static function tableName(){
return 'test';
}
}
部署测试代码 ¶
//插入
$test = new Test([
'name' => 'Jay',
'age' => 18,
]);
$test->save(); //数据库会多一条记录,底层是insert
echo $test->id; //入库后的id字段自增值
//查询
$test2 = Test::findOne($test->id); //假设上面插入后ID是1,用findOne方法查出来
print_r([$test2->name, $test2->age]); //就是刚才插入的那条记录
//更新
$test2->name = 'may';
$test2->save(); //底层会update,简单地说save的时候,一般new出来的就是新的,会insert, findOne出来的就是旧的,会update
echo (new \yii\db\Query())->from(Test::tableName())->where(['id' => $test->id])->one()['name']; //may
//删除
$test2->delete();
print_r(Test::findOne($test2->id)); //查询结果为false,因为数据库里删除了
findOne ¶
AR模型的findOne这个静态方法是用于查找数据并转换成模型实例返回,它的参数有两种表达方式:
数据ID,就是主键
条件数组,和yii\db\Query的where数组写法一样
相当于Query对象的one方法返回一条记录的数组一样,findOne就是返回一条记录的对象,由于是对象,是对象就能有方法,有方法就能方便地执行save、delete等,以及封装更多处理逻辑
字段赋值 ¶
如果数据表里有name字段,则可以直接操作模型的name属性,像上面$test2->name
这样
还可以用数组语法操作,比如$test['name'] = 'abc'; $test->save();
转成数组 ¶
Test::findOne这样查出来是个对象,可是返回给前端的要是个数组咋办,可以这样:
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
Yii::$app->response->data = $test->toArray();
用toArray能将数据库相关的字段转换成数组来返回
查询多条记录 ¶
将findOne改成findAll
即可,参数和findOne一模一样
它就相当于Query对象的all方法返回多条记录的数组一样,findAll就是返回多条记录的模型数组
示例代码:
foreach(Test::findAll(['status' => 1]) as $test){
print_r($test->name, $test->age);
}
无条件findAll就传个空数组吧,但不能不传参数
批量更新数据 ¶
用updateAll
方法:
Test::updateAll(['name' => 'abc'], ['id' => $ids]);
//UPDATE test SET name = abc WHERE id in ($ids)
第一个参数是要更新的字段和值
第二个参数就是条件,当然还是跟Query的where方法参数一样啦亲
不用AR模型实现更新数据的话,那就要这样来写代码了:
Yii::$app->db->createCommand()->update(Test::tableName(), $data, ['id' => $ids])
那至少,用AR模型写更新的代码会短一些,但当然AR不仅仅只是为了缩短代码的书写而存在……
实现更新 +1 之类的 ¶
要实现这样更新文章点击数量的话:(UPDATE xxxTable SET view_count = view_count + 1
)
用updateCounters
这个方法:
$article = Article::findOne(1);
$article->updateCounters(['view_count' => 1]);
key就是要累加的字段,value就是要累加的值,如果是'view_count' => 3
那自然就是SET view_count = view_count + 3
了
批量删除数据 ¶
一样的思想,就是deleteAll
方法:
Test::deleteAll(['id' => $ids]);
//DELETE FROM test WHERE id in($ids)
参数就是删除的条件