使用jdbc或者其他框架,很多时候需要去拼装sql,这是一个麻烦的事情。
例如:一个多筛选条件的页面,需要根据筛选的条件去查询所符合条件的数据,使用hibernate需要在类中一个个条件的去判断,来选择sql拼装,由于是在类中当新增筛选条件时需要去类中修改并且重新编译方可生效。
而mybatis提供对sql 语句动态的组装能力,而且它只有几个基本元素,十分简单明了,大量的判断都可以在mybatis的映射xml文件里面配置,以达到许多我们需要大量代码才能实现的功能,大大减少了我们编写代码的工作量,这体现了mybatis的灵活性高度可配置和可维护性。
mybatis也可以在注解中配置sql,但是由于注解中配置功能受限,对于复杂的sql而言可读性很差,所以使用较少,并且使用注解的方式sql是写在java类中,每次修改都需要编译。
mybatis中有哪些元素?
元素:if 、choose when otherwise 、trim 、foreach 、where 、set 、bind
属性: test
下面就来一 一介绍这些元素的作用
<select id="queryStudentAll" parameterType="student" resultType="student">
select * from student
where 1=1
<if test="stuName != null and stuName != ''">
and stu_name = #{stuName}
if>
<if test="age != null">
and age > #{age}
if>
select>
缺点: 需要手动在动态sql前面写上一个 where 1=1 条件
<select id="queryStudentChoose" parameterType="student" resultType="student">
select * from student where 1=1
<choose>
<when test="grade != null and grade != ''">
and grade = #{grade}
when>
<when test="email != null and email != '' ">
and email like '%${email}%'
when>
<otherwise>
and id > 2
otherwise>
choose>
select>
缺点:同 if 需要在前面手动添加一个 where条件。
注:只有一个条件会生效
<select id="queryStudentWhere" parameterType="student" resultType="student">
select * from student
<where>
<if test="email != null and email != ''">
and email like '%${email}%'
if>
<if test="grade != null and grade != ''">
and grade = #{grade}
if>
where>
select>
<select id="queryStudentTrim" parameterType="student" resultType="student">
select * from student
<trim prefix="where" prefixOverrides="and" >
<if test="email != null and email != ''">
and email like '%${email}%'
if>
<if test="grade != null and grade != ''">
and grade = #{grade}
if>
trim>
select>
<update id="updateStudentInfo" parameterType="student" >
update student
<set>
<if test="stuName != null and stuName != ''">
stu_name=#{stuName},
if>
<if test="age != null">
age=#{age},
if>
<if test="email != null and email != ''">
email=#{email},
if>
<if test="grade != null and grade != ''">
grade=#{grade}
if>
set>
where id=#{id}
update>
<select id="queryStudentInfoByIn" parameterType="int" resultType="student">
select * from student where id in
<foreach collection="list" item="item" index="index" separator="," open="(" close=")">
#{item}
foreach>
select>
<select id="queryStudentInfoByBind" parameterType="student" resultType="student">
<bind name="pattern" value="'%' + email + '%'"/>
select * from student where email like #{pattern}
select>
注意bind标签中参数不是 #{email } 这么取得,直接属性名就可 email
一般不会这么使用bind元素来达到上面的效果,上面主要是用于 拼接 %%
示例一: $ 处理,$不会预编译参数,会直接去参数字面值
<if test="email != null and email != ''">
and email like '%${email}%'
if>
如下日志,发现并没有为email参数占位符? ,而是直接取值拼装
2019-07-31 15:53:46 DEBUG mybatis.sql.com.cjy.mybatis.dao.StudentMapper.queryStudentWhere - ==> Preparing: select * from student WHERE email like '%xiaoming%' and grade = ?
示例二: || 拼接
<select id="queryPersonByIdAndLikeNames" resultMap="baseResult" >
select <include refid="baseColumns"/>
from person where id = #{id} and user_name like '%' || #{userName}
select>
示例三:使用concat函数处理
<if test="email != null and email != ''">
and email like concat('%' ,#{email} ,'%')
if>
注意:上面几种拼接sql %% 的方式需要注意使用的数据库。
demo地址 : https://github.com/chenjy512/mybatis-demo/tree/master/source-mybatis-05dynamic_SQL