什么是动态SQL呢???顾名思义,就是SQL语句不是固定的,而是在程序运行过程中动态变化的,MyBatis框架提供了动态SQL的功能,这也是MyBatis框架强大的功能之一。通过使用MyBatis的动态SQL,可以很容易实现复杂SQL语句的拼接,而不需要像原始的JDBC那样,通过任何的java代码来拼接SQL字符串。下面介绍动态SQL的常用标签。
if标签只有一个【test】属性,这个属性用于判断表达式是否成立。当test条件成立之后,Mybatis就会将if标签之间的代码拼接到SQL语句上面。
<?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="com.js.demo.mapper.UserMapper">
<!-- 动态SQL -->
<select id="queryTable" parameterType="com.js..demo.domain.User" resultType="com.js.demo.domain.User">
select * from user
<if test="username != null and username != ''">
where username = #{username}
</if>
</select>
</mapper>
if标签中,test属性如果由多个条件,则可以使用【and】或者【or】进行连接。
如果要访问某个对象中的属性,可以直接通过【对象名称.属性名称】的方式获取到。
<?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="com.mybatis.demo.mapper.UserMapper">
<!-- 动态SQL -->
<select id="queryTable" parameterType="com.js.demo.domain.User" resultType="com.js.demo.domain.User">
select * from user
<if test="user.password != null and user.password != ''">
where password = #{password}
</if>
</select>
</mapper>
choose标签和if标签类似,作用都是用于判断是否满足条件,但是choose标签可以同时设置多个情况,也就是java中的switch…case语句。
在choose标签里面,通过使用【when】标签和【otherwise】标签来实现条件的判断。
when标签,只有一个【test】属性,当满足test条件的时候,就会执行when标签里面的代码。
otherwise标签,是在所有的when标签都不满足条件的时候,才会执行otherwise标签里面的代码。
<?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="com.js.mapper.UserMapper">
<!-- 动态SQL -->
<select id="query2" parameterType="com.js.domain.User" resultType="com.js.domain.User">
select * from user
where 1 = 1
<choose>
<when test="username != null and username != ''">
and username = #{username}
</when>
<when test="password != null and password != ''">
and password = #{password}
</when>
<otherwise>
and id = #{id}
</otherwise>
</choose>
</select>
</mapper>
where标签,主要作用就是在拼接SQL语句的时候,如果SQL语句没有where关键字,那么此时会自动添加一个where关键字,并且如果拼接的SQL语句中,查询条件是以【and】或者【or】开头,那么where标签也会将多余的【and】或者【or】去掉,从而避免SQL语句错误。
<?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="com.js.mapper.UserMapper">
<!-- 动态SQL -->
<select id="query" parameterType="com.js.domain.User" resultType="com.js.domain.User">
select * from user
<where>
and username = #{username}
</where>
</select>
</mapper>
上面SQL语句,可以看到拼接的SQL语句是【and】开头的,按理来说应该是错误的,但是由于使用了where标签,所以Mybatis在拼接的时候会将开头多余的【and】去掉,这样就保证了SQL语句是正确的。
set标签是用于update更新操作的set关键字。set标签作用是在拼接的SQL字符串之前添加【set】关键字,并且还可以去除多余的【,】逗号。
<?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="com.js.mapper.UserMapper">
<!-- 动态SQL -->
<update id="updateData" parameterType="com.js.domain.User">
update user
<set>
<if test="username != null">
username = #{username},
</if>
<if test="password != null">
password = #{password},
</if>
</set>
where id = #{id}
</update>
</mapper>
trim标签,可以实现和where标签、set标签相同的功能,但是trim标签更加的灵活,它可以自定义去除哪些前缀,并且插入哪些内容。
<?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="com.mybatis.demo.mapper.UserMapper">
<!-- 动态SQL -->
<select id="query3" parameterType="com.js.domain.User" resultType=com.js.domain.User">
select * from user
where " prefixOverrides="and |or ">
!= null and username != ''">
AND username = #{username}
</if>
</trim>
</select>
</mapper>
trim标签属性:
- prefix属性:需要在拼接的SQL之前添加的前缀内容。
- prefixOverrides属性:需要将哪些SQL前缀内容去除。不区分大小写,多个可以使用【|】竖线分隔。
- suffix属性:需要在拼接的SQL之后添加的后缀内容。
- suffixOverrides属性:需要将哪些SQL后缀内容去除。不区分大小写,多个可以使用【|】竖线分隔。
就以上面的代码为案例,就是将【and 】和【or 】开头的前缀内容全部替换为where内容。
注意:【and 空格|or 空格】这个之间必须使用空格。
<?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="com.js.mapper.UserMapper">
<!-- 动态SQL -->
<update id="updateData2" parameterType="com.js.domain.User">
update user
<trim prefix="set" suffixOverrides=",">
<if test="username != null">
username = #{username},
</if>
<if test="password != null">
password = #{password},
</if>
</trim>
where id = #{id}
</update>
</mapper>
foreach标签,可以遍历一些集合、数组等数据,它是实际开发中使用最多的标签之一。foreach标签有如下几个属性:
- collection属性:需要遍历的集合、数组等名称,如果通过@Param注解指定了名称,则使用具体的名称,否则会有以下几个默认值:collecction、array、list、arg0。
- item属性:当前集合、数组中遍历到的一条数据。
- index属性:当前集合、数组中遍历到的下标。
- open属性:指定开头的字符。
- close属性:指定结尾的字符。
- seperator属性:指定分隔符。
<?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="cn.js.domain.UserMapper">
<!-- 动态SQL -->
<select id="query5" parameterType="com.js.domain.User" resultType="com.js.domain.User">
select * from user
<where>
id in
<foreach collection="list" item="item" index="index" open="(" close=")" separator=",">
#{item.id}
</foreach>
</where>
</select>
</mapper>