快捷查询助手
快捷查询助手是一项旨在简化数据查询及分页操作的功能。通过该功能,用户只需输入相关变量,系统便能自动组装数据搜索条件,从而快速获取所需数据。这一优化不仅提高了查询效率,还降低了查询操作的复杂度,使得用户能够更便捷地进行数据检索。
在实际应用中,快捷查询助手能够根据用户输入的关键词、时间范围、数据范围等变量,自动生成相应的查询语句,并自动应用到数据查询过程中。同时,该功能还支持分页显示,用户可以根据需要设置每页显示的数据量,以便更好地浏览和管理数据。
通过使用快捷查询助手,用户可以更加高效地获取所需数据,减少了手动编写查询语句的繁琐过程,提高了工作效率。同时,由于查询条件的自动生成,也减少了因手动输入错误而导致的查询结果不准确的问题,提高了数据查询的准确性和可靠性。
创建查询实例
创建快捷查询助手目前有两种方式,最为方便快捷的方式为模型创建法。
若在模型中需要使用到 QueryHelper
快捷查询助手,模型需要继承 \think\admin\Model
类;
若在控制器需要使用到 QueryHelper
快捷查询助手,控制器需要继承 \think\admin\Controller
类;
// 1. 控制器中,创建查询器(查询器支持链式操作)
// 控制器需要继承 \think\admin\Controller 类;
// 参数:$dbQuery 数据模型或者数据表名
// 参数:$input 为输入对象,如:post、get、request 或 数组
$query = $this->_query();
$query = $this->_query($dbQuery, $input);
// 2. 新版本中,模型也支持直接创建查询器
// 模型需要继承基础模型 \think\admin\Model
// 参数:$input 为输入对象,如:post、get、request 或 数组
// 参数:$callable 为回调用处理,回调参数1为对象本身`QueryHelper`对象
$query = MyModel::mQuery();
$query = MyModel::mQuery($data, function(QueryHelper $helper){});
$query = MyModel::mQuery('post', function(QueryHelper $helper){});
$query = MyModel::mQuery(null, function(QueryHelper $helper){
$helper->with("数据模型关联");
$helper->where("查询条件");
// $helper->like()->equal() ...
});
原生表格输出
调用 page
方法后,启用输出模板时会使用 HttpResponseException
响应直接输出机制,后续代码不会再操作。
对象快捷查询进行分页并输出,前端会有两个变量 $list
和 $pagehtml
,其中 $list
为当前数据列表数组,$pagehtml
为当前数据列表分页导航条。 前端 html -> table
可以通过使用 foreach
循环输出 Table
数据,生成原生 table
结构的标签代码。
// 快捷查询助手分页参数:
// 参数:$page bool 是否启用分页,默认分页
// 参数:$display bool 是否直接显示模板,默认显示模板
// 参数:$total int|false 分页模式,如果为数字则为列表统计数,false 自动统计,true 使用简化分页
// 参数:$limit int 每页数量,分页时每页数据记录数量
// 参数:$template string 模板名称,当启用显示模板时,会加载指定模板
$query->page($page, $display, $total, $limit, $template);
layTable 输出
新版本推荐使用 layui.table
组件显示表格数据,目前有针对 Layui
表格组件进行封装 layTable
插件,可动态填充页面高度,支持搜索表单绑定及混合模式调度。
<div class="think-box-shadow">
<table id="OplogData" data-url="{:sysuri()}" data-target-search="form.form-search"></table>
</div>
<script>
$(function () {
// 动态创建 layui.table 表格
$('#OplogData').layTable({
even: true, height: 'full',
sort: {field: 'id', type: 'desc'},
cols: [[
{checkbox: true},
{field: 'id', title: 'ID', width: 80, sort: true, align: 'center'},
{field: 'username', title: '操作账号', minWidth: 100, sort: true, align: 'center'},
{field: 'node', title: '操作节点', minWidth: 120},
{field: 'action', title: '操作行为', minWidth: 120},
{field: 'content', title: '操作描述', minWidth: 120},
{field: 'geoip', title: '访问地址', minWidth: 100},
{field: 'geoisp', title: '网络服务商', minWidth: 100},
{field: 'create_at', title: '操作时间', minWidth: 170, align: 'center', sort: true},
{toolbar: '#toolbar', title: '操作面板', align: 'center', fixed: 'right'}
]]
});
// 监听原 layui.table 的 tool 事件
$('#OplogData').trigger('tool', function (item) {
// 对应 layui.table 写法 layui.table.on('tool(OplogData)',function(){ })
if (item.event === 'EventName') {
// 判断 lay-event 名称处理
}
})
// 监听原 layui.table 的 toolbar 事件
$('#OplogData').trigger('toolbar', function (item) {
// 对应 layui.table 写法 layui.table.on('toolbar(OplogData)',function(){ })
})
// 以上为 layTable 兼容 layui.table 用法
// 更多事件绑定与 layui.table 的事件对应 https://layui.dev/docs/2.8/table/#table.on
// 原有 jQuery 写法需要使用 off + on 的方式实现 Element 对象查找
// 由于后台是单页程序,绑定事件需要先 off 再 on,否则容易重复绑定事件或无法触发事件
$('body').off('click', 'jQ选择器').of('click', 'jQ选择器', function () {
// 点击事件,可以用 this 读取 Element 对象属性内容
})
});
</script>
<script type="text/html" id="toolbar">
<!--{if auth('remove')}-->
<a data-action='{:url("remove")}' data-value="id#{{d.id}}" data-confirm="确认要删除这条记录吗?" class="layui-btn layui-btn-sm layui-btn-danger">删 除</a>
<!--{/if}-->
</script>
后端QueryHelper
实现表格数据自动处理,前置操作可以对html
模板进行操作,后置操作可以对数据进行过滤及关联操作。
调用layTable
方法后,默认为使用HttpResponseException
响应直接输出机制,后面的代码不会再执行。
// 新版本中 QueryHelper 对象支持 Layui 表格数据加载
$query->layTable(function(QueryHelper $query){
// 前置操作,处理 HTML 模型
},function(QueryHelper $query){
// 后置操作,处理表格数据
});
查询终态操作
特别注意: 下面操作的查询对象 QueryHelper
对象并不是 ThinkORM
的 Query
对象,如果获取结果操作,需要从 QueryHelper
中获取 ThinkORM
的 Query
对象。
// 从 QueryHelper 对象获取 ThinkORM 的 Query 对象
$db = $query->db();
// 对 QueryHelper 对象获取 ThinkORM 执行结果操作
$count = $query->db()->count(); // 记录统计
$total = $query->db()->sum('字段'); // 统计求和
$mysql = $query->db()->buildSql(); // 读取 SQL 语句
查询条件处理
另外对于 url
输入的变量也可以快速输入到查询器条件中,如:
// 1. 控制器中创建查询器
$query = $this->_query('表名');
// 2. 使用模型创建查询器, MyModel 为模型名称
// 模型需要继承基础模型 \think\admin\Model
$query = MyModel::mQuery();
// 切入url参数,接收 username 和 sex 并使用 like 查询,接收 status 使用 eq 查询
$query->like('username,sex')->equal('status');
// 查询器分页输出
$query->page();
// 有时候,url输入的名称与数据字段不一定是匹配的,所以需要用到别名,这里就需要按规则写条件,如:
// 切入url参数,接收 username_alias 和 sex 并使用 like 查询,接收 user_status 使用 eq 查询
// 这里用到了别名,username_alias 对应数据库中的 username 字段,user_status 对应数据库的 status 字段
$query = $this->_query('表名')->like('username#username_alias,sex')->equal('status#user_status');
// 查询器分页输出
$query->page();
// 输出额外数据到模板,与 ThinkPHP 操作无异,如:
// 额外列表数据赋值到模板,模板里直接使用变量 $userList
$this->userList = Db::name('User')->where(['status'=>'1'])->select();
// 切入url参数,接收 username 和 sex 并使用 like 查询,接收 status 使用 eq 查询
$query = $this->_query('表名')->like('username,sex')->equal('status');
// 查询器分页输出
$query->page();
查询回调处理
对于通过 page
方法实现的即将显示到模板的列表,还可以进行引用二次处理,如:
protected function _page_filter(&$data){
// 这里可以对 $data 进行二次处理,注意是引用
}
### 当一个控制器存在多个page操作时,可以指定回调前缀
protected function _index_page_filter(&$data){
// 精准回调对 $data 进行二次处理,注意是引用
}
查询使用案例
/**
* 系统操作日志
* @auth true
* @menu true
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index()
{
$this->title = '系统操作日志';
$query = $this->_query($this->table)->like('action,node,content,username,geoip');
$query->dateBetween('create_at')->order('id desc')->page();
}
/**
* 列表数据处理
* @param array $data
* @throws \Exception
*/
protected function _index_page_filter(&$data)
{
$ip = new \Ip2Region();
foreach ($data as &$vo) {
$result = $ip->btreeSearch($vo['geoip']);
$vo['isp'] = isset($result['region']) ? $result['region'] : '';
$vo['isp'] = str_replace(['内网IP', '0', '|'], '', $vo['isp']);
}
}
快捷查询助手同样保留原 ThinkPHP Query
的功能,也可以使用 JOIN
进行关联查询。
// 在这里对 Db 进行操作,如果 $db->where()->buildSql() 等等
$db = $this->_query('表名')->db();
// or 模型调用法
$db = MyModel::mQuery()->db();
// 输出 Sql 语句
var_dump($db->buildSql());
// 对于联表操作,需要指定 field,join 如果用到了条件查询,一定要用上别名查询
$query = $this->_query('table_a')->alias('a')->field('a.id,a.name,b.pid,b.nickname');
$query->join('table_b b','a.id=b.pid')->like('a.name#a_name')->page();
// 另外,对于 TP 原有的用法也支持如 | 和 & 用法
$map = ['a&b' => 1]; // 生成的条件是: where a = 1 and b = 1
$map = ['a|b' => 1]; // 生成的条件是: where b = 1 or b = 1
// 以上两种情况配合别名使用
$this->_query('table_a')->alias('a')->equal('a|b#name')...
// or 模型调用法
MyModel::mQuery()->alias('a')->equal('a|b#name')...
// 当前请求带上 name 值时,会生成 where a=值 or b=值
$this->_query('table_a')->alias('a')->equal('a&b#name')...
// or 模型调用法
MyModel::mQuery()->alias('a')->equal('a&b#name')...
// 当前请求带上 name 值时,会生成 where a=值 and b=值