mybatis(三)之⾼级⽤法
mybatis之⾼级⽤法
⼀、动态 SQL
  MyBatis 的强⼤特性之⼀便是它的动态 SQL。如果你有使⽤ JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利⽤动态 SQL 这⼀特性可以彻底摆脱这种痛苦。
  通常使⽤动态 SQL 不可能是独⽴的⼀部分,MyBatis 当然使⽤⼀种强⼤的动态 SQL 语⾔来改进这种情形,这种语⾔可以被⽤在任意的 SQL 映射语句中。
  动态 SQL 元素和使⽤ JSTL 或其他类似基于 XML 的⽂本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis3 ⼤⼤提升了它们,现在⽤不到原先⼀半的元素就可以了。MyBatis 采⽤功能强⼤的基于 OGNL 的表达式来消除其他元素。
  mybatis 的动态 sql 语句是基于 OGNL 表达式的。可以⽅便的在 sql 语句中实现某些逻辑。总体说来 mybatis 动态 SQL 语句主要有以下⼏类:
  1.if 语句 (简单的条件判断)
  2.choose (when,otherwize),相当于 java 语⾔中的 switch,与 jstl 中的 choose 很类似。
  3.trim (对包含的内容加上 prefix,或者 suffix 等,前缀,后缀)
  4.where (主要是⽤来简化 sql 语句中 where 条件判断的,能智能的处理 and or,不必担⼼多余导致语法错误)
  5.set (主要⽤于更新时)
  6.foreach (在实现 in 语句查询时特别有⽤)
  在实际开发中我们经常封装⽤于包含所有查询条件的询条件类,有时条件类也可以使⽤ map 代替,只是使⽤ map 代码可读性较差。
public class ConditionPet{
private String name;
private int minWeight;
private int maxWeight;
}
if 的⽤法
  ⽤于根据参数的条件,动态拼接 SQL。if ⾥⾯的 test 就是对应的条件,当条件满⾜,if 中的 SQL 就会正常拼接。
案例:
<select id="findByCondition" resultType="ity.Pet">
select * from pet
<if test="name != null and name != ''">
where name like #{name}
</if>
</select>
案例2:
<select id="findByCondition" resultType="ity.Pet">
select * from pet where true
<if test="name != null">jstl条件标签
and  name = #{name}
</if>
<if test="minWeight != null">
and weight >= #{minWeight}
</if>
</select>
⼆、choose(when,otherwize)
  相当于 java 语⾔中的 if-else/switch,与 jstl 中 的 choose 很类似。但是它与 if 的区别是,如下案例中三条分⽀语句程序只能⾛其中⼀条。
<select id="findByCondition" resultType="ity.Pet">
select * from pet where
<choose>
<when test="name != null">
name = #{name}
</when>
<when test="minWeight != null">
weight >= #{minWeight}
</when>
<otherwise>
id =1
</otherwise>
</choose>
</select>
三、trim
  mybatis 的 trim 标签⼀般⽤于去除 sql 语句中多余的 and 关键字,逗号,或者给 sql 语句前拼接 “where“、“set“以
及“values(“ 等前缀,或者添加“)“等后缀,可⽤于选择性插⼊、更新、删除或者条件查询等操作,如果要同时去除多个使⽤管道符连接prefixOverrides=“AND|OR”。
  案例1:去除多余的 and 或者 where
select * from pet
<trim prefix="WHERE" prefixOverrides="AND">
<if test="name != null">
name = #{name}
</if>
<if test="minWeight != null">
AND weight >= #{minWeight}
</if>
<if test="maxWeight != null">
AND weight <![CDATA[<=]]> #{maxWeight}
</if>
</trim>
prefix:前缀
prefixOverrides:去除 SQL 语句前⾯的关键字或者字符。
suffixOverrides:去除 SQL 语句结束位置的关键字或者字符。
案例2:使⽤ trim 标签去除结尾多余的逗号
insert into pet
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name != null">name,</if>
<if test="weight != null">weight,</if>
</trim>
values
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name!=null">#{name},</if>
<if test="weight!=null">#{weight},</if>
</trim>
四、where
  where 会⾃动判断后⾯的条件,如果没有条件则不在 SQL 中拼接 where 关键字。同时还能⾃动去掉 where 最前⾯多出的 and 或者or 关键字。
  案例:
<where>
<if test="name != null">and name like #{name}</if>
<if test="weight != null">and weight = #{weight}</if>
</where>
练习:
  1.在 resource 表中增加如下的查询条件,并使⽤⼀条查询语句完成,参数统⼀使⽤ map。
  ⼀、⽤户传⼊ page 与 size 参数时分页查询。
  ⼆、⽤户传⼊ beginTime ⽤于查询创建时间在 beginTime 的之后创建的资源。
  三、传⼊ url 后可以根据 url 模糊查询。
  四、传⼊ name 后可以根据 name 模糊查询。
  参考代码:
<resultMap id="BaseResultMap" type="ity.Resource">
<id column="id" jdbcType="INTEGER" property="id"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
<result column="url" jdbcType="VARCHAR" property="url"/>
<result column="pid" jdbcType="INTEGER" property="pid"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
<result column="order_number" jdbcType="INTEGER" property="orderNumber"/>
</resultMap>
<sql id="Base_Column_List">
id, `name`, url, pid, create_time, update_time, order_number
</sql>
<select id="select" parameterType="map" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from resource
<where>
<if test="name != null and name !=''">
and `name` like #{name}
</if>
<if test="url != null and url != ''">
and url like #{url}
</if>
<if test="pid != null">
and pid = #{pid}
</if>
<if test="beginTime != null">
and create_time >= #{beginTime }
</if>
</where>
<if test="page!=null and size!=null">
limit #{page},#{size}
</if>
</select>
五、set的⽤法
  与 trim 类似 set 元素会动态地在⾏⾸插⼊ SET 关键字,并会删掉额外的逗号(这些逗号是在使⽤条件语句给列赋值时引⼊的)。  案例:
update pet
<set>
<if test="name != null">name = #{name},</if>
<if test="weight != null">weight = #{weight},</if>
</set>
where id =#{id}
练习:
  1.在 resource 表中增加如下的修改⽅法,使其能完成只修改不为空的属性,参数统⼀使⽤ map。
  参考代码:
<update id="updateByPrimaryKeySelective" parameterType="ity.Resource">
update resource
<set>
<if test="name != null">
`name` = #{name},
</if>
<if test="url != null">
url = #{url},
</if>
<if test="pid != null">
pid = #{pid},
</if>
<if test="orderNumber != null">
order_number = #{orderNumber},
</if>
update_time =now()
</set>
where id = #{id}
</update>
六、bind
  bind 元素允许你在 OGNL 表达式以外创建⼀个变量,并将其绑定到当前的上下⽂。⽐如:
<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + parameter.titie + '%'"/>
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>
七、foreach
  foreach 主要⽤于数组、集合的遍历,foreach 提供⼤量属性⽤于满⾜开发需求如:collection ⽤于指
定遍历的集合名称、 item 正在遍历的那个对象、 open 遍历前拼接的字符串、 close 结束时拼接的字符串、 separator 间隔字符和 index 指定遍历的索引。
  案例:
where id in
<foreach collection="ids" item="id"open="(" close=")" separator=",">
#{id}
</foreach>
等价于
where id in (
<foreach collection="ids" item="id" separator=",">
#{id}
</foreach>
)
练习:
  1.在修改时经常使⽤到批量修改操作,创建如下⽅法完成 resource 批量修改。
  int updateAll(int[]ids, Resource resource);
  ids 为修改的数据id集合
  resource 包含修改的属性,不为空的属性才修改。
  参考代码:
<update id="updateAll">
update resource
<set>
<if test="param1.name != null and param1.name != ''">
name = #{param1.name},
</if>
<if test="param1.url != null and param1.url != ''">
url = #{param1.url},
</if>
<if test="param1.pid != null">
pid = #{param1.pid},
</if>
<if test="derNumber != null">
order_number = #{derNumber},
</if>
update_time =now()
</set>
where id
<foreach collection="param2"open="in (" close=")" separator="," item="i">#{i}</foreach>
</update>
接⼝⽅法
int update(Resource resource,List<Integer> ids);
⼋、collection 深⼊学习
  foreach 中的 collection 在实际开发中有如下使⽤⽅法:
  1.如果传⼊的是单参数且参数类型是⼀个 array 数组的时候,collection 的属性值为 array
  2.如果传⼊的是单参数且参数类型是⼀个 List 的时候,collection 属性值为 list
  3.如果传⼊的参数是多个的时候,我们就需要把它们封装成⼀个 Map,当然单参数也可,如果传⼊的参数是多个的时候,我们也可以放在实体类中(这种实际⽤到也是⾮常多的)
1.普通数组
<select id="select" parameterType="int">
select * from person
where id in
<foreach collection="array" item="id"open="(" close=")" separator=",">
#{id}
</foreach>
</select>
使⽤时
int[] ids ={4,6};
mapper.select(int[] ids);
2.List 集合

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。