亲宝软件园·资讯

展开

MyBatis 动态SQL

小皮猪 人气:0

情景:

     我们在使用JDBC或者其他类似的框架开发进行数据库开发时,通常要根据需求动手组装SQL,不用想都觉得是件很痛苦的事情了,而Mybatis框架提供的对SQL语句动态组装的功能,能很好地解决这个麻烦。

概述:

     动态SQL是MyBatis框架的一个强大特性,MyBatis3可采用功能强大的基于OGNL的表达式来完成动态SQL,它删除了之前版本中需要了解的大多数元素,只使用不到原来一半的元素就能完成所需的工作。

SQL元素:

SQL元素说明
<if>判断语句,用于单条件分支判断
<choose>  (<when>,<otherwise>)相当于Java中的switch...case...default语句,用于多条件分支判断
<where>简化SQL语句中的where的条件判断
<trim>可以灵活地去除多余的关键字
<set>解决动态更新语句
<foreach>循环语句,常用于in语句等列举条件中
<bind>从OGNL表达式中创建一个变量,并将其绑定到上下文,常用于模糊查询的SQL中

<if>:

使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分

<?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="org.example.mapper.BookMapper">
 
    <resultMap id="BookType" type="org.example.po.Book">
        <id property="id" column="id"></id>
        <result property="bookName" column="bookName"></result>
        <result property="price" column="price"></result>
        <result property="publisher" column="publisher"></result>
    </resultMap>
 
    <select id="bookSelectById" parameterType="int" resultMap="BookType">
        select * from t_book
        <where>
            <if test="id!=null and id!=''">
                id=#{id}
            </if>
        </where>
    </select>
 
    <select id="bookSelectByname" parameterType="string" resultMap="BookType">
        select * from t_book
        <where>
            <if test="bookNmae!=null and bookName!=''">
                bookName LIKE concat('%',#{bookName},'%')
            </if>
        </where>
    </select>
 
</mapper>

<choose>:

      有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

因为自己写的是单查询,引用官网代码。

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE'
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

<where>:

     <where>标签相当于 where 1=1 ,主要用来简化SQL语句中的where条件判断,并能智能地处理and和or不必担心多余关键字导致的语法错误。代码参考<if>标签代码。

<trim>:

      这个标签我觉得是最灵活的,trim元素也会自动识别其标签内是否有返回值,若有的话,则会在已包含的内容前加上某些前缀或者后缀(先判断是否有语句包含),用到的属性是

 1、prefix(前缀),suffix(后缀)

还可以把包含内容的首内容或尾内容的符号去掉,用到的属性是

2、prefixOverride(前缀覆盖),suffixOverride(后缀覆盖)

可以说功能很强大,可以利用它来替代where元素,并实现与where元素相同的效果。

<?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="org.example.mapper.BookMapper">
 
    <resultMap id="BookType" type="org.example.po.Book">
        <id property="id" column="id"></id>
        <result property="bookName" column="bookName"></result>
        <result property="price" column="price"></result>
        <result property="publisher" column="publisher"></result>
    </resultMap>
 
    <update id="bookUpdate" parameterType="book">
        UPDATE t_book
        <trim prefix="set" suffixOverrides=",">
            <if test="bookName!=null and bookName!=''">bookName=#{bookName},</if>
            <if test="price!=null and price!=''">price=#{price},</if>
            <if test="publisher!=null and publisher!=''">publisher=#{publisher}</if>
            WHERE id=#{id}
        </trim>
    </update>
 
</mapper>

<set>:

      set元素主要用于更新操作,它的主要功能和where元素差不多,主要是包含的语句前输入一个set,若包含的语句以逗号结束,则会自动把括号忽略掉,再配合if元素就可以动态地更新需要修改的字段;若不需要更改字段,则可以不再被更新。

把上面的代码修改一下:

<?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="org.example.mapper.BookMapper">
 
    <resultMap id="BookType" type="org.example.po.Book">
        <id property="id" column="id"></id>
        <result property="bookName" column="bookName"></result>
        <result property="price" column="price"></result>
        <result property="publisher" column="publisher"></result>
    </resultMap>
 
    <update id="bookUpdate" parameterType="book">
        UPDATE t_book
<!--        <trim prefix="set" suffixOverrides=",">-->
<!--            <if test="bookName!=null and bookName!=''">bookName=#{bookName},</if>-->
<!--            <if test="price!=null and price!=''">price=#{price},</if>-->
<!--            <if test="publisher!=null and publisher!=''">publisher=#{publisher}</if>-->
<!--            WHERE id=#{id}-->
<!--        </trim>-->
        <set>
            <if test="bookName!=null and bookName!=''">bookName=#{bookName},</if>
            <if test="price!=null and price!=''">price=#{price},</if>
            <if test="publisher!=null and publisher!=''">publisher=#{publisher},</if>
        </set>
        WHERE id=#{id}
    </update>
 
 
</mapper>

<foreach>:

foreach元素通常在构建in条件语句时使用,其使用方式如下。

(1).  item: 表示每个元素迭代时的别名。

(2).  index: 指定一个名称,用于表示在迭代过程中每次迭代的位置

(3).  open: 表示该语句以什么开始(in语句以“( ”开始)

(4).  separator: 表示每次进行迭代时以上面符号作为分隔符(in语句以“ ,”作为分隔符)

(5).  close: 表示该语句以什么结束(in语句以“ )”结束)

(注意:  这个open,separator,close基本上就是固定格式了)

(6).  collection: 表示最关键且最容易出错的属性,需格外注意。该属性必须指定,不同情况下该属性的值是不一样的,主要有三种情况:

        1).  若入参为单参数且参数类型是一个list时,collection属性值为list

        2).  若入参为单参数且参数类型是一个数组时,collection属性值为array

        3).  若入参为多参数,需要将其封装为一个Map进行处理

格式:

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  <where>
    <foreach item="item" index="id" collection="list"
        open="ID in (" separator="," close=")" nullable="true">
          #{item}
    </foreach>
  </where>
</select>

<bind>:

bind元素通常用于需要模糊查询的语句中,使用bind元素定义了一个name为pattern_username的变量,value的属性值就是拼接的查询字符串,其中_parameter.getTitle()表示传递进来的参数(也可以直接写成对应的参数变量名,如username)。

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern_username" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>

加载全部内容

相关教程
猜你喜欢
用户评论