大可网

您现在的位置是:首页>文章详情

文章详情

关于QeePHP常用操作大全

2022-07-27 1097热度
摘要:每一个 AR(ActiveRecord 的简称)对象对应一条数据库记录 (1) 查询 read 每一个模型都提供了 find() 静态方法, 这个方法本质上并不查询数据,而是返回一个 QDB_Select 对象, 利用这个设计,我们可以采用连贯接口写出漂亮的查询代码: find() 方法的参数和 QDB_Select::where() 方法相同,支持下列参数格式: find(查询条件, 查询参数1,...

每一个 AR(ActiveRecord 的简称)对象对应一条数据库记录

打印SQL:

1、 dump(self::_getLastSql());die();

2、QDB::getConn()->getSql()

(1) 查询 read
每一个模型都提供了 find() 静态方法, 这个方法本质上并不查询数据,而是返回一个 QDB_Select 对象, 利用这个设计,我们可以采用连贯接口写出漂亮的查询代码:
find() 方法的参数和 QDB_Select::where() 方法相同,支持下列参数格式:
find(查询条件, 查询参数1, 查询参数2, ...)
查询条件通常使用字符串形式。字符串中的问号(?)将被视为参数占位符。按照占位符出现的顺序,提供给 find() 方法的后续参数将被填入查询条件中。
举例说明:
//返回第一条记录, 返回对象
$user = Demo_User::find()->getOne();
$user = Demo_User::find()->one()->query();
//返回5条记录, 返回对象
$user = Demo_User::find()->get(5);
//返回所有的记录, 返回对象
$user = Demo_User::find()->getAll();
$user = Demo_User::find()->all()->query();
//返回用户ID为2的记录, 返回数组
$user = Demo_User::find("id = ?", 2)->asArray()->getOne();
或者
$user = Demo_User::find("id = ?", 2)->getOne()->toArray();
//排序显示5条记录,返回数组
$user = Demo_User::find()->order("id desc")->get(5)->toArray();
//查询指定的字段,返回数组
$user = Demo_User::find()->setColumns('username, email')->asArray()->getOne();
//组合条件查询
$user = Demo_User::find("id = ? and username = ?", 2, "test2")->asArray()->getOne();
//QeePHP 还支持使用数组做查询条件,使用数组时,数组的键名将被视为查询条件中的字段名,而键值则是查询参数。多个字段和参数会用 AND 操作进行连接。同样,参数值也会进行自动转义,确保安全。比起使用字符串,数组做为查询条件缺乏灵活性。但是个别情况下会更方便一点,开发者可以酌情选择。
$where = array(
"id" => 3,
"username"=>"test3",
);
$user = Demo_User::find($where)->asArray()->getOne();
//组合多个查询条件
如果查询条件非常复杂,而我们又不方便使用字符串做查询条件,那么可以通过 find() 方法返回的 QDB_Select 对象来组装复杂查询,或者使用 QDB_Cond 对象来封装复杂的查询条件。
QDB_Select 对象提供了 where()、orWhere() 方法,可以让我们通过连贯接口添加多个查询条件:
Post::find('level_ix > ?', $level_ix)
->where('confirm = ?', true)
->where('author_id = ?', $author_id)
->getAll();
或者将 find() 方法返回的 QDB_Select 对象保存起来:
$select = Post::find();
$select->where(...);
$select->where(...);
$posts = $select->getAll();
//使用 QDB_Cond 构造复杂查询条件
如果需要动态构造查询条件,使用 QDB_Cond 有时是个更好的选择,
每一个 QDB_Cond 对象封装一组查询条件。由于 QDB_Cond 是可以无限嵌套的,所以理论上可以构造任意复杂度的查询条件。
user_id > 1000 AND is_valid = 1
使用 QDB_Cond 构造上述查询条件很简单:
$cond = new QDB_Cond('user_id > ?', $user_id);
$cond->andCond('is_valid = ?', true);
当然也可以使用连贯接口形式:
$cond = QDB_Cond::create('user_id > ?', $user_id)->andCond('is_valid = ?', true);
还可以构造嵌套的查询条件:
$cond = QDB_Cond::create('user_id > 200')->orCond(QDB_Cond::create('level_ix = 3 AND is_valid = 1'));
//等同于 user_id > 200 OR (level_ix = 3 AND is_valid = 1)
最后将 QDB_Cond 对象传递给 find() 或 where() 等方法就行了:
Post::find($cond)->getAll();
//限定查询结果
要限定查询结果的数量,可以有几种方法:
//执行查询,并限定最多返回 10 个结果
$posts = Post::find(...)->get(10);
//同等效果的其他方式
$posts = Post::find(...)->get10();
$posts = Post::find(...)->top(10)->get();
$posts = Post::find(...)->limit(0, 10)->get();
//执行查询,从第 21 个符合条件的结果开始,返回最多 10 个结果
$posts = Post::find(...)->get10start21();
$posts = Post::find(...)->limit(20, 10)->get();
同样,get10start21() 也是魔法方法调用,第一个数字表示返回结果的数量,第二个数字则是起始位置。
如果希望通过变量指定查询结果数,那么应该使用 top() 等方法。不过一定要注意 limit() 的第一个参数是以 0 为基数的,也就是说假如要从第 21 个结果开始返回,那么 limit() 方法的第一个参数应该是 20。
//联表查询多个字段:
特别说明:joinLeft的第2个参数也是查询指定的字段,如果用了这个参数,则setColumns方法就不要用了;反之这个参数必须为空,建议使用setColumns方法来增加灵活性
$columns = array("borrow.*", "user.user_id as userid");
self::find()->alia('s')->joinLeft('user', '', 'borrow.`user_id` = user.`user_id`')
->setColumns($columns)
->limitPage(QContext::instance()->page, $limit)
->order('id desc');
(2) 写操作:create
方式1:
$post = new Post();
$post->title = 'post title';
$post->body = 'post body';
$post->save();
方式2:
$post = new Post(array(
'title' => 'post title',
'body' => 'post body',
));
$post->save();
上述两种方式的区别仅在于书写方式不同,其他没有区别。
(3) 更新操作:update
方式1:
$post = Post::find('post_id = ?', $post_id)->query();
$post->title = 'new post title';
$post->body = 'new post body';
$post->save();
第一种方式首先从数据库查询已有的记录,然后修改属性值,再保存。
方式2:
$post = new Post(array(
'title' => 'post title',
'body' => 'post body',
));
$post->changePropForce('post_id', $post_id);
$post->save();
第二种方式直接构造一个新对象,并修改属性值, 再强制将 AR 对象的 post_id 属性指定为特定值,从而实现对已有记录的更新
第二种方式减少了一次数据库查询,效率较高, 但问题在于如果 AR 对象的更新引发了事件操作,那么在事件处理函数中被处理的 AR 对象就是不完整的。
比如 AR 对象的 before_save 事件需要根据 AR 对象的 updated 属性值(对象最近一次保存到数据库的时间)来更新缓存文件。由于第二种方式我们没有从数据库查出已有对象,所以对象的 updated 属性就是空值。这会直接导致 before_save 事件中的代码出错。
所以除非确定不会产生问题,否则尽量不要使用第二种方式来更新对象。
Userinfo::meta()->updateWhere(['is_back'=>0],['uid' => $this->_user->uid]);
(4) 删除操作:delete
方式1:
$photo = Photo::find('photo_id = ?', $photo_id)->query();
$photo->destroy();
方式2:
Photo::meta()->destroyWhere('photo_id = ?', $photo_id);
方式3:
Photo::meta()->deleteWhere('photo_id = ?', $photo_id);
方式1-2是等价的,都是先查询出对象,再调用 destroy() 方法。这种方式的好处是可以在对象的事件处理函数中完成一些额外工作,例如清理缓存,或者删除 AR 对象对应的文件(例如 Photo 对象对应的照片文件)。
方式3是直接删除符合条件的数据库记录,不需要先查询,性能更好,但是无法触发事件处理函数。
Controller层获取post get 数据方法:
$this->_context->get()
$this->_context->post()
$this->_context->get("id")
$this->_context->post("name")
.....
Model层获取post get 数据方法类似(只是需要先单例化上下文对象):
QContext::instance->get()
QContext::instance->post()
QContext::instance->get("id")
QContext::instance->post("name")

相关文章

文章评论

暂无任何评论,请君畅言