Mybatis动态构建Sql(无实体类)
来源:互联网 发布:axure rp中文版 mac 编辑:程序博客网 时间:2024/06/06 03:19
先简单说下Mybatis的动态sql,这不是今天的重点。
MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。
例如,sql语句where条件中,需要一些安全判断,例如按某一条件查询时如果传入的参数是空,此时查询出的结果很可能是空的,也许我们需要参数为空时,是查出全部的信息
MyBatis中用于实现动态SQL的元素主要有:
- if
- choose(when,otherwise)
- trim
- where
- set
- foreach
示例mapper.xml:
<select id="findActiveBlogLike"parameterType="BLOG" resultType="BLOG">SELECT * FROM BLOGWHERE<trim prefix="WHERE" prefixOverrides="AND |OR "><choose><when test="title != null">AND title like #{title}</when><when test="author != null and author.name != null">AND title like #{author.name}</when><otherwise>AND featured = 1</otherwise></choose></trim></select><update id="updateAuthorIfNecessary"parameterType="Author">update Author<trim prefix="where" prefixOverrides=","> <set><if test="username != null">username=#{username},</if><if test="password != null">password=#{password},</if><if test="email != null">email=#{email}</if></set>where id=#{id}</trim></update>
但是问题来了,如果我们没有实体怎么办?如上代码,都是关联实体Author,BLOG。
更进一步,如果我们连字段和表名都是程序运行时产生的,那么在Mybatis中,我们的mapper.xml又该如何写呢?
不要说这种需求很少,实际上很多灵活性和扩展性要求比较高的应用,物理模型不确定,也即是你的表结构不确定,甚至连表名字都不确定,基本上sql中的每一个字母都不是写死的。
我现在就遇到了这种需求,简单描述如下:
事先定义好了很多数据集的信息模型,针对这些信息模型生成物理模型。而我们需要针对这些物理模型进行操作。而这些数据集一旦更新,信息模型以及物理模型都要变动,所以事先不可能完全确定物理表结构等等信息。此时应该怎么在mybatis中进行处理呢?
翻阅mybatis文档,在一个不起眼的地方发现update标签有一个属性statementType,根据jdbc的经验,这应该是控制sql预编译还是非预编译的,如果sql执行是预编译的,那么动态传入字段名,表名之类的,显然
是不行的,所以你必须改成非预编译的。
两者有什么区别呢?如果是预编译的,那么系统在初始化时就会读取这段sql代码,将指定的实体类中的字段替换了类似#{}这样的语句,就是形成了类似这样的语句:
"select * from tableName where id=?" 这个时候你在系统运行时再想向这句sql中替换tableName或者id,结果可想而知。如果是非预编译呢,结果刚好相反,他会在系统运行时才会去生成这样类似的语句。此时就可以去替换这些动态的字段或者表名之类。这样在结合之前所讲的返回类型的设置,我们的问题就解决了。
我们可以不用设定参数和返回类型的实体类,只需要形成一个动态的表名和字段名的列表类。就可以动态对那些未知的物理模型进行操作.如下代码可作参考:
<select id="queryMetaList" resultType="Map" statementType="STATEMENT">select * from ${tableName} t where<foreach item="item" index="index" collection="field" open=" "separator="and" close=" "><choose><when test="item.fieldType == 'DATE' and item.dateQueryFlag == 0">${item.fieldCode} betweento_date('${item.fieldValue}','yyyy-mm-ddhh24:mi:ss') </when><when test="item.fieldType == 'DATE' and item.dateQueryFlag == 1">to_date('${item.fieldValue}','yyyy-mm-ddhh24:mi:ss') </when><when test="item.fieldItemCode != null and item.fieldItemCode != ''">${item.fieldCode} ='${item.fieldItemCode}'</when><otherwise>${item.fieldCode} ='${item.fieldValue}'</otherwise></choose></foreach></select>
注:会有sql注入危险,代码中要处理。
另外,注意返回值,在mybatis中,无论你指定还是不指定返回类型,mybatis都会默认的先将查询回的值放入一个hashMap中(如果返回的值不止一条就是一个包含hashMap的list)。这其中的区别在于,如果你指定了返回类型,mybatis将会根据返回类型的实体类来从hashMap中获取值并set到这个实体类中。如果不指定就默认返回一个HashMap<String,Object>(List<HashMap<String,Object>>)。
我们没有实体,当然就不要指定返回值,默认接受处理List<HashMap<String,Object>>结构的返回值即可。
最后发点感慨:
亲,不要再把实体写死了,或者不要有实体。实体写死,最直接的后果就是:Hibernate会把sql框死,Mybatis也会把sql框死,手写jdbc放入实体,也一样是死,有新模块,你还得从web到dao写一串,累不累,你还怎么玩。
所以,做大型平台级应用的架构设计,尽量不要停留在一个表对应一个实体的阶段,必须考虑应用的动态可扩展和灵活性。
0 0
- Mybatis动态构建Sql(无实体类)
- MyBatis--动态SQL原笔记(无案例)
- mybatis动态sql参数为实体类时出现的问题
- mybatis传入集合类型参数 动态sql构建
- Mybatis 动态SQL批量插入(有则更新无则插入)
- mybatis系列-SQL语句构建器类(六)
- MyBatis(3):MyBatis的动态SQL
- Mybatis总结(6)---Mybatis动态sql
- mybatis(6)动态sql
- MyBatis动态SQL(1)
- MyBatis动态SQL(2)
- MyBatis(4):动态SQL
- MyBatis(4):动态SQL
- MyBatis(4):动态SQL
- MyBatis(4):动态SQL
- MyBatis(4):动态SQL
- mybatis-动态 SQL(五)
- 【Mybatis】(三)动态SQL
- 博弈论一 [ 巴什博奕 ]
- 搭建rails开发环境(ruby2.1+rails4.1.6)
- Java制作jar包的几种方法
- 利用while语句求1000以内偶数的和
- Android开发软件安装与环境配置
- Mybatis动态构建Sql(无实体类)
- PE文件之DOS头
- linux下cat命令详解
- JAVA小程序:和电脑猜拳
- 利用DO WHILE 语句求1000以内偶数和
- Android Developer Toolkit (ADT)升级
- 稀疏矩阵的十字链表存储
- 黑马程序员---C语言指针
- maven介绍和环境搭建