Mybatis框架的动态sql技术是一种根据特定条件动态拼装sql语句的功能,它存在的意义是为了解决拼接sql语句字符串的痛点问题
比如在sql查询语句中,你的参数一般是来自服务器,服务器的数据有可能来自session之类的,例如多条件查询,你有个条件为空,那传了个空值给sql语句的参数会导致sql语句查询报错,但是你又不能把这个条件从where中去除,所以可以采用动态sql
- if标签
- 在sql语句标签内可以使用if标签
List<Emp> getEmpByCondition(Emp emp);
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp where
<if test="empName != null and empName != ''">
emp_name = #{empName}
</if>
<if test="age != null and age != ''">
and age = #{age}
</if>
<if test="gender != null and gender != ''">
and gender = #{gender}
</if>
</select>
- 在select标签中使用if标签,其中的test属性中填写条件语句,标签内填写拼接的sql语句,test可以直接使用传进来的参数不用加#{},除了这个以外其它的和之间的参数使用方式是一样的
- where标签
- 上面的if标签中我给的示例,假如我第一个条件不成立,第二个条件成立,那么where后面会直接拼接and,就会报错
- 解决办法1,在where语句后面加一个1=1,然后所有的拼接语句加上and
- 解决办法2,where标签
- 功能1 在条件if标签中只要有成立条件在sql语句中自动生成where语句
- 功能2 可以自动去掉where后面因为sql语句拼接前面多余的and,就不会出现where and 这种错误语句,但是可能会出现where xxx and xxx and 以and结尾这种错误语句
- 功能3 当条件语句中没有成立条件将不会生成where
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp
<where>
<if test="empName != null and empName != ''">
emp_name = #{empName}
</if>
<if test="age != null and age != ''">
and age = #{age}
</if>
<if test="gender != null and gender != ''">
and gender = #{gender}
</if>
</where>
</select>
- 上面的if标签中我给的示例,假如我第一个条件不成立,第二个条件成立,那么where后面会直接拼接and,就会报错
- trim标签
- 因为where标签虽然可以自动去掉拼接前面的and,但是不能去掉后面的and
- trim标签有四个属性
- 下面的sql语句指定都是添加的总拼接语句,就是下面例子后面t_emp后面拼接的所有部分
- prefix:给sql语句拼接的前缀
- prefixOverriders:去除sql语句前面的关键字或者字符,该关键字或者字符由prefixOverrides属性指定,假设该属性指定为"AND",当sql语句的开头为"AND",trim标签将会去除该"AND"
- suffix:给sql语句拼接的后缀
- suffixOverriders:去除sql语句后面的关键字或者字符,该关键字或者字符由suffixOverrides属性指定
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp
<trim prefix="where" suffixOverrides="and">
<if test="empName != null and empName != ''">
emp_name = #{empName} and
</if>
<if test="age != null and age != ''">
age = #{age} and
</if>
<if test="gender != null and gender != ''">
and gender = #{gender} and
</if>
</trim>
</select>
- 由于trim标签,会自动在拼接语句前面拼接where(有条件成立的前提),还会去掉sql语句最后的and
- choose,when,otherwise
- choose:相当于if
- when:相当于else if
- otherwise:相当于else
- 这一组标签和if标签的区别就是他是众多条件最后只会成立一个,而if可以有多个条件成立
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp
<where>
<choose>
<when test="empName != '' and empName != null">
emp_name = #{emName}
</when>
<when test="age != '' and age != null">
and age = #{age}
</when>
<when test="gender != '' and gender != null">
and gender = #{gender}
</when>
</choose>
</where>
</select>
- otherwise可用可不用
- foreach标签(用的多)
- 批量添加
void insertEmpList(List<Emp> list);
使用集合添加- 关于参数是list集合,那么在mybatis中怎么访问,之前似乎没遇到过,有两种吧,一种是mybatis默认会吧集合参数放到它的map集合中,以"list" 为键,以传进来的参数位置
#{list}
,另一种就是用@param的方法 直接#{(param注解中的值)}
- 关于参数是list集合,那么在mybatis中怎么访问,之前似乎没遇到过,有两种吧,一种是mybatis默认会吧集合参数放到它的map集合中,以"list" 为键,以传进来的参数位置
- 映射文件写法
<insert id="insertEmpList">
<foreach collection="list" item="emp" separator=",">
(null,#{emp.empName},#{emp.age},#{emp.gender},null)
</foreach>
</insert>
- 解释一下
- 上面的collection属性值为传过来的参数,具体使用和之前if标签中的text使用参数的方式一样,不需要加
#{}
,只要有list这个键名和对应的值就行 - item属性表示从集合了取出来对象,然后给对象赋予键名为emp,值为list中取出来的对象
- separator表示分隔符,用来分隔每条循环语句的,不会在总拼接语句的开头和结尾添加,只分隔中间的语句,而且会在分各符前后加空格
- 然后注意使用对象的属性的方式
#{emp.name}
- 上面的collection属性值为传过来的参数,具体使用和之前if标签中的text使用参数的方式一样,不需要加
- 批量删除
- 之前有一种where emp_id in (xxx,xxx) 这种删除方法,用的是${}来拼接到括号里面删除
- 第二种的语句跟上一种差不多,只是参数使用有区别
- 通过传入id数组
void deleteMoreEmp(@Param("emps") Integer[] integers);
- 使用foreach标签来删除
<delete id="deleteMoreEmp">
delete from t_emp where emp_id in (
<foreach collection="emps" item="empId" separator=",">
#{empId}
</foreach>
)
</delete>
- 这样通过循环将参数全放入in ( ) 的括号里的方式
- 另一种就是
<delete id="deleteMoreEmp">
delete from t_emp where emp_id in
<foreach collection="emps" item="empId" separator="," open="(" close=")">
#{empId}
</foreach>
</delete>
- 这里open和close分别表示总拼接语句的开始和结束符,这里会为总拼接语句开始加(和结束加)最后就会变成(?,?,?)的形式
- 还有一种
<delete id="deleteMoreEmp">
delete from t_emp where
<foreach collection="emps" item="empId" separator="or">
emp_id = #{empId}
</foreach>
</delete>
- 利用了分隔符会前后补空格的机制,可以这样写
- sql标签
- 主要是用来记录一个sql片段,在需要用的地方使用include标签来应用
<sql id="empfield">
emp_id,emp_name,age,gender
</sql>
- 将这个sql片段记录
<select id="xxxx">
select <include refid="empfield"></include> from t_emp
</select>
- 在使用的地方用include标签引用,refid就是sql标签的id