zoukankan      html  css  js  c++  java
  • Mybatis动态构建Sql(无实体类)

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。

    例如,sql语句where条件中,需要一些安全判断,例如按某一条件查询时如果传入的参数是空,此时查询出的结果很可能是空的,也许我们需要参数为空时,是查出全部的信息

    MyBatis中用于实现动态SQL的元素主要有:

    • if
    • choose(when,otherwise)
    • trim
    • where
    • set
    • foreach
    示例mapper.xml:
     
    [html] view plain copy
     
     print?
    1. <select id="findActiveBlogLike"  
    2.     parameterType="BLOG" resultType="BLOG">  
    3.     SELECT * FROM BLOG  
    4.     WHERE  
    5.     <trim prefix="WHERE" prefixOverrides="AND |OR ">  
    6.         <choose>  
    7.             <when test="title != null">  
    8.                 AND title like #{title}  
    9.             </when>  
    10.             <when test="author != null and author.name != null">  
    11.                 AND title like #{author.name}  
    12.             </when>  
    13.             <otherwise>  
    14.                 AND featured = 1  
    15.             </otherwise>  
    16.         </choose>  
    17.     </trim>  
    18. </select>  
    19.   
    20. <update id="updateAuthorIfNecessary"  
    21.     parameterType="Author">  
    22.     update Author  
    23.     <trim prefix="where" prefixOverrides=",">   
    24.     <set>  
    25.         <if test="username != null">username=#{username},</if>  
    26.         <if test="password != null">password=#{password},</if>  
    27.         <if test="email != null">email=#{email}</if>  
    28.     </set>  
    29.     where id=#{id}  
    30.     </trim>  
    31. </update>  
    但是问题来了,如果我们没有实体怎么办?如上代码,都是关联实体Author,BLOG。
    更进一步,如果我们连字段和表名都是程序运行时产生的,那么在Mybatis中,我们的mapper.xml又该如何写呢?
     
    不要说这种需求很少,实际上很多灵活性和扩展性要求比较高的应用,物理模型不确定,也即是你的表结构不确定,甚至连表名字都不确定,基本上sql中的每一个字母都不是写死的。
     
    我现在就遇到了这种需求,简单描述如下:
    事先定义好了很多数据集的信息模型,针对这些信息模型生成物理模型。而我们需要针对这些物理模型进行操作。而这些数据集一旦更新,信息模型以及物理模型都要变动,所以事先不可能完全确定物理表结构等等信息。此时应该怎么在mybatis中进行处理呢?
     

    翻阅mybatis文档,在一个不起眼的地方发现update标签有一个属性statementType,根据jdbc的经验,这应该是控制sql预编译还是非预编译的,如果sql执行是预编译的,那么动态传入字段名,表名之类的,显然 

    是不行的,所以你必须改成非预编译的。

    两者有什么区别呢?如果是预编译的,那么系统在初始化时就会读取这段sql代码,将指定的实体类中的字段替换了类似#{}这样的语句,就是形成了类似这样的语句:

    "select * from tableName where id=?" 这个时候你在系统运行时再想向这句sql中替换tableName或者id,结果可想而知。如果是非预编译呢,结果刚好相反,他会在系统运行时才会去生成这样类似的语句。此时就可以去替换这些动态的字段或者表名之类。这样在结合之前所讲的返回类型的设置,我们的问题就解决了。

    我们可以不用设定参数和返回类型的实体类,只需要形成一个动态的表名和字段名的列表类。就可以动态对那些未知的物理模型进行操作.如下代码可作参考:

    [html] view plain copy
     
     print?
    1. <select id="queryMetaList" resultType="Map" statementType="STATEMENT">  
    2. select * from ${tableName} t where  
    3. <foreach item="item" index="index" collection="field" open=" "  
    4. separator="and" close=" ">  
    5. <choose>  
    6. <when test="item.fieldType == 'DATE' and item.dateQueryFlag == 0">  
    7. ${item.fieldCode} between  
    8. to_date('${item.fieldValue}','yyyy-mm-dd  
    9. hh24:mi:ss')   
    10. </when>  
    11. <when test="item.fieldType == 'DATE' and item.dateQueryFlag == 1">  
    12. to_date('${item.fieldValue}','yyyy-mm-dd  
    13. hh24:mi:ss')   
    14. </when>  
    15. <when test="item.fieldItemCode != null and item.fieldItemCode != ''">  
    16. ${item.fieldCode} =  
    17. '${item.fieldItemCode}'  
    18. </when>  
    19. <otherwise>  
    20. ${item.fieldCode} =  
    21. '${item.fieldValue}'  
    22. </otherwise>  
    23. </choose>  
    24. </foreach>  
    25.   
    26. </select>  
    注:会有sql注入危险,代码中要处理。
     
    另外,注意返回值,在mybatis中,无论你指定还是不指定返回类型,mybatis都会默认的先将查询回的值放入一个hashMap中(如果返回的值不止一条就是一个包含hashMap的list)。这其中的区别在于,如果你指定了返回类型,mybatis将会根据返回类型的实体类来从hashMap中获取值并set到这个实体类中。如果不指定就默认返回一个HashMap<String,Object>(List<HashMap<String,Object>>)。
     
    我们没有实体,当然就不要指定返回值,默认接受处理List<HashMap<String,Object>>结构的返回值即可。
  • 相关阅读:
    平易近人、兼容并蓄——Spark SQL 1.3.0概览
    System.getProperty
    Apache Commons CLI 简介
    The declared package does not match the expected package
    Maven常用命令
    使用SBT构建Scala应用(转自git)
    Area Under roc Curve(AUC)
    用特征来实现混入(mix-in)式的多重继承
    暗时间
    SVN如何commit(提交)项目代码
  • 原文地址:https://www.cnblogs.com/bojuetech/p/6890437.html
Copyright © 2011-2022 走看看