动态sql
sql的内容是变化的, 可以根据条件获取到不同的sql语句.
主要是where部分发生变化。
动态sql的实现, 使用的是mybatis提供的标签, <if>, <where>, <foreach>
1. <if>是判断条件的
// 动态Sql, 使用时候需要用Java对象作为参数
// <if>测试
List<Student> selectStudentIf(Student student);
mapper文件
<!--
if
参数:
test : java对象的属性值作为判断条件
-->
<select id="selectStudentIf" resultType="org.example.domain.Student">
select * from t_student where 1=1
<if test="name != null and name != ''">
name = #{name}
</if>
<if test="age >= 21">
and age = #{age}
</if>
</select>
<!--
分析上面语法, 主sql为select * from t_student where
当if中的test成立, 也就是说, 方法的参数java对象的name属性不为null且不为空字符串时
将if语句块中的句子加入到主sql之后
上述条件成立, sql语句变为select * from t_student where name = #{name}
下面的age判断也一样, 如果成立就拼接, 不成立就不拼接
所以上面的可能会出现sql语法错误, name不成立, age成立
sql语句为 : select * from t_student where or age = #{age}
这样是语法错误的
为了避免这样的错误, 我们使用一个小技巧, 在主sql语句中加入一个一定成立的条件, 这个条件并不影响下面的条件
如 : select * from t_student where id > 0
-->
2. <where> 用来包含多个<if>的
上面的if标签有局限性, 这个标签就可以很好的解决上面的问题
// where使用
List<Student> selectStudentWhere(Student student);
mapper文件
<select id="selectStudentWhere" resultType="org.example.domain.Student">
select * from t_student
<where>
<if test="name != null and name != ''">
name = #{name}
</if>
<if test="age >= 21">
and age = #{age}
</if>
</where>
</select>
<!--
where的作用就是处理上面多个if只有一个生效的问题,
select语句中不用写if了, 转而用<where>标签代替
当多个if只有一个生效时, where标签会自动将SQL语句中别的影响语句语法的信息删除
-->
3. <foreach>是用来循环java中的数组, list集合
主要用在sql的in语句中
select * from student where id in (1, 2, 3)
dao中方法为
List<Student> selectFor(List<Integer> idList)
这个idList中存放的就是上面的1, 2, 3
一般有两种情况
1. 参数为List<基本类型>
// foreach用法1, 参数为List<基本类型>
List<Student> selectForeachOne(List<Integer> idList);
mapper文件
<!--
foreach用法1, 接口方法参数为List<基本类型>
List<Student> selectForeachOne(List<Integer> idList);
-->
<!--
参数介绍
collection:表示接口中的方法参数的类型, 如果是数组使用array, 如果是List集合使用list
item:自定义的, 表示数组和集合成员的变量, 好比for(Integer i : List)中的i
open:循环开始时最前面添加的字符
close:循环结束时最后面添加的字符
separator:集合成员之间的分隔符
-->
<select id="selectForeachOne" resultType="org.example.domain.Student">
select * from t_student where id in
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
<!--
最后循环的结果(为传入的list为(1, 2, 3))
select * from t_student where id in (1, 2, 3)
这里是字符串的拼接, 所以完全可以这样写
select * from t_student where id in (
<foreach collection="list" item="id" separator=",">
#{id}
</foreach>
)
-->
2. 参数为List<自定义类型>
// foreach用法2, 参数为List<自定义类型>
List<Student> selectForeachTwo(List<Student> students);
<!--
传入参数为list<Student>
#{item的值.属性}
-->
<select id="selectForeachTwo" resultType="org.example.domain.Student">
select * from t_student where id in
<foreach collection="list" item="stu" open="(" close=")" separator=",">
#{stu.id}
</foreach>
</select>
<!--
这样将List中的每个Student对象的id循环拼接
-->
4. sql代码片段, 就是复用一些语法
<!--
sql代码片段, 可以复用
先定义 : <sql id="唯一标识符" >可以复用的sql语句</sql>
再使用 : <include refid="id的值" />
-->
<!--定义-->
<sql id="sqlStu" >
select * from t_student
</sql>
<!--使用-->
<select id="selectForSql" resultType="org.example.domain.Student">
<include refid="sqlStu"/>
</select>