一次动态sql查询订单数据的设计

订单数据一般是变化比较多的数据,查询条件也是比较复杂,如果没有一个规则解释,写接口的变动就会比较频繁;由于个人不喜欢在业务端使用拼接sql的方式,另外本身是做安全出身,业务端的sql拼接容易sql注入,所以不考虑使用;为了满足这个特性,将订单的条件进行了一次划分: 状态、用户、时间、公司、上车地点、下车地点;

第一步: 先处理状态查询, 状态查询定义在t_om_group表中,后台人员可以手动添加状态分组,前端业务只需要状态分组对应哪些状态即可;如:

group_id 1 对应 order_staus (1001,1002,1003)

group_id 对应 order_status(1002,1003)

第二步: 处理用户,用户有两个 driver 和 passenger, 这里当成参数输入,-1表示不验证


BEGIN

DECLARE sqlPattern VARCHAR(255);
DECLARE sqlTemp VARCHAR(1024);
DECLARE sqlExec VARCHAR(1024);
DECLARE sqlCondi VARCHAR(1024);

Select pattern into sqlPattern from t_om_group where group_id=groupId;

IF driverUid >= 0 AND passengerUid>=0 THEN
SET sqlCondi = CONCAT("driver_uid=", driverUid, " AND passenger_uid=", passengerUid);
ELSEIF driverUid<0 AND passengerUid>=0 THEN
SET sqlCondi = CONCAT("passenger_uid=", passengerUid);
ELSEIF driverUid>=0 AND passengerUid<0 THEN
SET sqlCondi = CONCAT("driver_uid=", driverUid);
ELSE
SET sqlCondi = "";
END IF;

IF sqlPattern=‘‘ OR sqlPattern IS NULL THEN
IF sqlCodi = "" THEN
set sqlTemp = "Select * from v_order";
ELSE
SET sqlTemp = CONCAT("Select * from v_order where", sqlCondi);
END IF;

ELSE
IF sqlCondi = "" THEN
SET sqlTemp = CONCAT("Select * from v_order where ", sqlPattern);
ELSE
SET sqlTemp = CONCAT("Select * from v_order where ", sqlCondi, " and ", sqlPattern);
END IF;

END IF;

SET @sqlExec=sqlTemp;
prepare stmt from @sqlExec;
EXECUTE stmt;
deallocate prepare stmt;

END

第三步: 组装sql并执行,也就是动态sql

第四步: 调用存储过程;


@Select("call sp_getGroupOrders(#{groupId}, #{driverUid}, #{passengerUid})")
@Options(statementType = StatementType.CALLABLE)
List<Map<String, Object>> getGroupOrders(@Param("groupId") Integer groupId,
@Param("driverUid") Integer driverUid,
@Param("passengerUid") Integer passengerUid);

上面就完成第一个阶段的设计,动态查询数据;

当然,这不是我们最终需要的,因为在实际使用过程中还会有更多的条件设置;我们需要查询进行一次定义;

1, 哪些字段可以进行条件查询

2, 业务是否传递该字段的值

3,字段支持哪些表示式

这里我们就需要参考Mybaits的Example的设计了,但为了支持查询安全和动态sql,我们仍然需要将sql的查询与我们在t_om_group配置的条件进行一次匹配,然后再根据输入的参数进行查询处理;

例如: group 验证规则为:   order_status in (${statusList}) and start_time>${startTime} and end_time<${endTime}

那么解释sql时,就只处理这个三个参数定义值,那么同时要求业务端必须传递这三个参数,否则不执行查询;

若按照上面的规则来处理,那么我们在处理查询的同时还可定义到t_om_order之外的表,下面来来设计这个查询规则表:

group_id:编号 group_name:名称 table_name:表名 fields:字段列表 where_expr:条件表达式 order_expr:排序表达式 group_expr: 分组表达式

sql模板: select ${fields} from ${table_name} where ${where_expr} order by ${order_expr} group by ${group_expr}

验证参数 : 如果配置了where_expr, 通过拦截处理 where_expr中的动态参数,参数不匹配则查询失败;匹配成功则执行查询;

第二阶段完成,基本动态sql询就可以了;

第三阶段: 多表和嵌套查询,未完待续

时间: 2024-08-02 06:59:10

一次动态sql查询订单数据的设计的相关文章

kettle中实现动态SQL查询

kettle中实现动态SQL查询 在ETL项目中,通常有根据运行时输入参数去执行一些SQL语句,如查询数据.本文通过kettle中的表输入("table input")步骤来说明动态查询.参数查询.示例代码使用内存数据库(H2),下载就可以直接运行,通过示例学习更轻松. SQL查询语句中占位符绑定字段值 第一个接近动态语句的是大家熟悉的从SQL代码中执行,开始写一个SQL查询,包含一些占位符,然后绑定值到占位符,使之成为一个有效的查询并执行.根据需要可以绑定多个值并循环执行.本示例的名

mybatis 动态SQL查询总结

背景 ××项目需要提供系统部分函数第三方调用接口,基于安全性和避免暴露数据库表信息的基础上进行函数接口的设计,根据第三方调用身份的权限提供某张表的自定义集合.本项目基于mybatis的持久层框架,支持定制化的SQL,这样可以避免拼接sql语句的痛苦.例如拼接时要确保不能添加空格,还要注意去掉列表的最后一个列名的都逗号.基于OGNL的表达式的mybatis框架可以彻底解决这种痛苦. 动态返回mysql某张表指定列的名字,类型和注释 <select id="queryColumns"

MyBatis的动态SQL查询-让查询更灵活多变!

序言 MyBatis,大家都知道,半自动的ORM框架,原来叫ibatis,后来好像是10年apache软件基金组织把它托管给了goole code,就重新命名了MyBatis,功能相对以前更强大了.它相对全自动的持久层框架Hibernate,更加灵活,更轻量级,这点我还是深有体会的. MyBatis的一个强大特性之一就是动态SQL能力了,能省去我们很多串联判断拼接SQL的痛苦,根据项目而定,在一定的场合下使用,能大大减少程序的代码量和复杂程度,不过还是不是过度太过复杂的使用,以免不利于后期的维护

获取动态SQL查询语句返回值(sp_executesql)

在写存储过程时经常会遇到需要拼接SQL语句的情况,一般情况下仅仅是为了执行拼接后的语句使用exec(@sql)即可. 而今天的一个存储过程却需要获取动态SQL的查询结果. 需求描述:在某表中根据Id值查询Cost值(表名不确定但表结构确定,如下面的Product表) 如果不考虑获取返回值,我们这样写即可: declare @tableName varchar(50) declare @id varchar(10) declare @cost numeric(18,2) declare @sql

SQL查询将数据按字段(2017-08-15 11:34:05)进行按月分组

关于进行sql查询按字段me_createTime按月进行排序 使用函数:date_format 按月进行分组查询,并按月进行排序 上代码 $sql="select date_format(me_createTime,'%Y-%m')as create_month,count(me_id) as me_num from {$SETTING['db']['prefix']}member where me_state in(1,2) and sm_id='$sm_id' group by date_

sql 查询大数据 常用 50列优化

大数据量的问题是很多面试笔试中经常出现的问题,比如baidu google 腾讯 这样的一些涉及到海量数据的公司经常会问到. 下面的方法是我对海量数据的处理方法进行了一个一般性的总结,当然这些方法可能并不能完全覆盖所有的问题,但是这样的一些方法也基本可以处理绝大多数遇到的问题.下面的一些问题基本直接来源于公司的面试笔试题目,方法不一定最优,如果你有更好的处理方法,欢迎与我讨论. 1.Bloom filter 适用范围:可以用来实现数据字典,进行数据的判重,或者集合求交集 基本原理及要点: 对于原

动态SQL查询,多条件,分页

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.bdqn.mybatis.mapper.Camera

Hibernate动态SQL查询

一.需求背景 给hibernate插上ibatis动态查询的翅膀,既保留crud的简洁性,又能收获ibatis的特性. 二.ibatis的动态查询 1 <select id="findUser" resultClass="User"> 2 SELECT * From User 3 <dynamic prepend="WHERE"> 4 <isNull property="id"> 5 id

SQL 查询强化 - 数据准备

最近要搞新的项目了, 我的 BI 报表这块, 我感觉, 可能又要写sql, 对于一些简单的 查询, 表连接我还应付得来, 如果涉及多个表的, 什么子查询嵌套, 自定义函数, 加上控制流...就感觉就不行了, 下的我赶紧从网上找几篇教程来跟着写一写... SQL 真的是, 特别, 特别重要, 面试,笔试必考... 而我是专做数据这块, 必然是重中之重. 而然,我真实中却, 真的写的很少, 主要是我太依赖 Pandas 了, 直接连接上多个表, 然后就可以为所欲为, 其实跟sql 是一样的, 什么段