动态SQL
介绍
Mybatis 的映射文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了。
关于动态SQL参考的官方文档,描述如下:
之前存在的问题
多条件查询样例:
这个时候我们的SQL语法要怎么写呢?
如果还是使用之前的方法,则就要写两条SQL语句 ,如果再多的话,代码量就会变的越来越大!
所以我们就要用到动态SQL
我们只要学其中的 if 和 foreach 就好。
动态 SQL 之<if>
介绍
<where>:条件标签。如果有动态条件,则使用该标签代替where关键字
<if>:条件判断标签
语法
例如上述案例:
我们只要将StudentMapper.xml,按如下写法即可!!!
注意:是#{},表示${}!!!刚刚不小心写错了,找bug找了好久!!!
<select id="selectCondition" resultType="student" parameterType="student">
SELECT * FROM student
<where>
<if test="id != null">
id = #{id}
</if>
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
动态 SQL 之<foreach>
介绍
<foreach>:循环遍历标签。适用于多个参数”或者“的关系
语法
collection:参数容器类型,(list - 集合,array - 数组)
open:开始的SQL语句
close:结束的SQL语句
item:参数的变量名
separator:分隔符
循环执行sql的拼接操作,例如:SELECT * FROM student WHERE id IN (1,2,5)。
<select id="selectByIds" resultType="student" parameterType="list">
<!-- SELECT * FROM student WHERE id IN (1,2,5) -->
SELECT * FROM student
<where>
<foreach collection="list" open="id IN (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
这里的parameterType是list,表示传进来的参数是一个集合类型;item为id,表示使用名为id的变量去接收list中的每一个元素。
对于SQL语句:SELECT * FROM student WHERE id IN (1,2,5)来说,上述的xml就不会吧SQL写“死”!list传几个id过来,“()”中就有几个值!
SQL片段抽取
介绍
SQL中可将重复的 SQL 提取出来,使用时用 include 引用即可,最终达到 SQL重用的目的。
<sql>:抽取 SQL 语句标签。
<include>:引入 SQL 片段标签。
语法
例如在StudentMapper.xml中 SELECT * FROM student 语句较多!我们可以对它们进行抽取
在StudentMapper.xml文件中的<mapper>根标签下写入:
<sql id="select">SELECT * FROM student</sql>
再在使用到该语句的地方用<include>标签进行替换
<select id="selectAll" resultType="student">
<include refid="select"/>
</select>
修改后的完整的StudentMapper.xml如下
<?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属性:名称空间
-->
<mapper namespace="com.itheima.mapper.StudentMapper">
<sql id="select">SELECT * FROM student</sql>
<!--
select:查询功能的标签
id属性:唯一标识
resultType属性:指定结果映射对象类型
parameterType属性:指定参数映射对象类型
-->
<select id="selectAll" resultType="student">
<include refid="select"/>
</select>
<select id="selectById" resultType="student" parameterType="int">
<include refid="select"/> WHERE id = #{id}
</select>
<!--
返回的是一个int类型的行数!所以可以省略resultType
但是,SQL语句的参数id、name、age是从学生对象中来所以,要有parameterType
-->
<insert id="insert" parameterType="student">
INSERT INTO student VALUES (#{id},#{name},#{age})
</insert>
<update id="update" parameterType="student">
UPDATE student SET name = #{name},age = #{age} WHERE id = #{id}
</update>
<!-- java.lang.Integer -> int-->
<delete id="delete" parameterType="int">
DELETE FROM student WHERE id = #{id}
</delete>
<select id="selectCondition" resultType="student" parameterType="student">
<include refid="select"/>
<where>
<if test="id != null">
id = #{id}
</if>
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
<select id="selectByIds" resultType="student" parameterType="list">
<include refid="select"/>
<where>
<foreach collection="list" open="id IN (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
</mapper>