MyBatis-动态语句
Mybatis-动态语句
动态 SQL 是 MyBatis 的强大特性之一
通过在mapper.xml的标签来拼接所需的sql语句,例如不同的where条件
if标签
使用if标签可实现动态的sql语句
如果test属性中表达式的值为true,则将标签内的sql语句进行拼接,反之则忽略
test属性中的表达式的书写规则:
- 逻辑与用and,逻辑或用or
- 比较符号不推荐直接使用
<
>
因为老版本的MyBatis会错误的识别成标签结束符号,推荐使用实体符号- 实体符号是html中曾经使用过的转义符号:大于号用
>
小于号用<
- 实体符号是html中曾经使用过的转义符号:大于号用
where标签
- 如果where标签的子标签if标签满足条件,则会自动添加where关键字,反之缺省where关键字
- 自动去掉多余的and和or关键字
<select id="queryByNameAndSalary" resultType="employee">
select *
from t_emp
<where>
<if test="name != null">
emp_name = #{name}
</if>
<if test="salary != null">
and emp_salary = #{salary}
</if>
</where>
</select>
set标签
和where标签功能大致相同,用于取代原本sql的update关键字
<update id="update">
update t_emp
<set>
<if test="empName!=null">
emp_name = #{empName} ,
</if>
<if test="empSalary!=null">
emp_salary = #{empSalary}
</if>
</set>
where emp_id = #{empId}
</update>
trim标签
trim中文释义:修剪
trim标签相当于自定义模式,用以替代where和set标签
- prefix属性:如果if成立并且其标签下的语句存在,则自动补全prefix的值
- prefixOverrides属性:自动修剪sql前多余的语句
- suffixOverrides属性:自动修剪sql后多余的语句
可以理解成where和set只是定义好的trim
<select id="queryByNameAndSalaryTrim" resultType="employee">
select *
from t_emp
<trim prefix="where" prefixOverrides="and">
<if test="name != null">
emp_name = #{name}
</if>
<if test="salary != null">
and emp_salary = #{salary}
</if>
</trim>
</select>
choose、when和otherwise标签
这三个标签就相当于Java中的switch
<select id="queryByNameAndSalaryChoose" resultType="employee">
select *
from t_emp
where
<choose>
<!--根据名字查询-->
<when test="name != null">
emp_name = #{name}
</when>
<!--根据工资查询-->
<when test="salary != null">
emp_salary = #{salary}
</when>
<!--如果以上两个条件都不满足,则查询全部-->
<otherwise>1=1</otherwise>
</choose>
</select>
choose中一定会执行一个where的判断条件,所以无需使用where标签来考虑是否忽略where
choose中只会执行一个where的判断条件,所以无需考虑and或or的语句修建问题
无论是查询结果为一个对象还是一个集合,resultType都会选择实体类,如果是集合的话resultType也是填写其泛型
foreach标签
- collection属性:被遍历的数据
- 使用param注解添加的别名
- 使用arg0
- 使用list
- open属性:遍历之前要追加的字符串
- close属性:遍历结束要追加的字符串
- separator属性:每次遍历的分隔符号(最后一个不加符号)
- item属性:遍历项
batch中文释义:批处理
mapper接口
// 批量处理crud
List<Employee> queryBatch(@Param("ids") List<Integer> ids);
int deleteBatch(@Param("ids") List<Integer> ids);
int insertBatch(@Param("employees") List<Employee> employees);
int updateBatch(@Param("employees") List<Employee> employees);
批量查询
<!--这个select不考虑传入的id集合为空的情况-->
<select id="queryBatch" resultType="employee">
select * from t_emp
where emp_id in
<!--这个foreach的遍历结果为:(1,2,3,……)-->
<foreach collection="ids" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</select>
批量删除
<delete id="deleteBatch">
delete from t_emp
where emp_id in
<foreach collection="ids" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</delete>
批量插入
每一个item项中都是固定格式(empName,empSalary)所以没有遍历前后的追加括号
<insert id="insertBatch">
insert into t_emp(emp_name,emp_salary)
values
<foreach collection="list" separator="," item="employee">
(#{employee.empName},#{employee.empSalary})
</foreach>
</insert>
批量更新
update比较特殊,没有什么能单独foreach的数据,所以将整条语句循环执行
<update id="updateBatch">
<foreach collection="employees" item="emp">
update t_emp
set emp_name = #{emp.empName},emp_salary = #{emp.empSalary}
where emp_id = #{emp.empId}
</foreach>
</update>
但这种操作需要开启数据库支持,在mybatis-config.xml配置文件中,url一项后增加?allowMultiQueries=true
参数即可
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis-example?allowMultiQueries=true"/>
<property name="username" value="root"/>
<property name="password" value="Zhuwenxue2002"/>
sql&include标签
通过使用sql将重复的sql代码提取出来,通过include重新引用
<sql id="selectSql">
select *
from t_emp
</sql>
<select id="queryALl" resultType="employee">
<include refid="selectSql"/>
</select>