MyBatis的使用(XML映射文件)
MyBatis的使用(XML映射文件)
MyBatis基于注解开发简单便捷,但是弊端是失去SQL语句的灵活性,不能根据实际情况产生不同的SQL语句
MyBatis除了支持注解开发以外,还支持一种开发方式:XML映射文件,将SQL语句写到XML映射文件中,基于更多种的选择可以让SQL变得更加灵活
1.开发方式
1.和基于注解开发方式一样,有映射类/编写配置文件/编写Mapper持久层接口
2.将方法执行时候要运行的SQL语句放到XML文件中进行编写,提高灵活性
2.三重绑定
-
接口与XML文件的绑定关系,在XML映射文件的namespace中声明绑定的接口的全类名
<?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.itheima.mapper.EmpMapper"> </mapper>
必须还要在配置文件中声明xml文件位置,MyBatis才可以扫描到这些文件,扫描到与接口建立绑定关系
mybatis.mapper-locations=classpath:mappers/*.xml
-
接口中的方法与XML文件中标签的绑定关系
如果接口中有一个方法,XML文件中就必须有对应的标签保存该方法对应的SQL语句
根据方法功能的不同,提供四种标签:< select >、< update >、< delete >、< insert >
public void deleteEmp(@Param("id") Integer id);
标签必须给出id属性,属性就是对应的方法名称
<delete id="deleteEmp"> DELETE FROM emp WHERE id = #{id} </delete>
-
查询语句的返回值类型与XML文件中标签属性的绑定关系
如果执行的是DQL语句,< select >标签中除了要生命id为方法名之外,还需要声明一个属性resultType值为封装结果的全类名
public Emp selectEmpById(@Param("id") Integer id);
<select id="selectEmpById" resultType="com.itheima.entity.Emp"> SELECT * FROM emp WHERE id = #{id} </select>
3.动态SQL概述
可以随着条件的改变随之发生改变的SQL语句就是动态SQL,在MyBatis中只有XML映射文件的方式支持动态SQL
-
动态SQL使用-IF
< if >标签的核心功能对条件进行判断,当条件为true,则标签中的内容参与SQL拼接,否则不参与
if标签中有一个核心属性test,基于test传递条件可以进行判断
(1)在test条件中可以直接获取本次参数的内容并且不需要加#{}
(2)test条件中可以基于=、!=、>、>=、<、<=对数据进行判断,并且可以基于and或者or进行多条件连接
<if test="empQuery.name != null and empQuery.name != ''"> name LIKE CONCAT('%', #{empQuery.name}, '%') </if>
**如果有多个test条件,那么除了第一个之外后续的条件需要加 前AND **
<if test="empQuery.name != null and empQuery.name != ''"> name LIKE CONCAT('%', #{empQuery.name}, '%') </if> <if test="empQuery.gender != null"> AND gender = #{empQuery.gender} </if>
-
动态SQL使用-WHERE
如果if经过了判断第一个条件前包含AND,基于where标签进行包裹可以自动将前AND去掉
如果没有任何一个if满足,基于where标签进行包裹可以不在SQL中拼接WHERE
SELECT * FROM emp <where> <if test="empQuery.name != null and empQuery.name != ''"> name LIKE CONCAT('%', #{empQuery.name}, '%') </if> <if test="empQuery.gender != null"> AND gender = #{empQuery.gender} <!-- 注意:多个条件判断除了第一个之外剩余条件需要前AND --> </if> <if test="empQuery.begin != null"> AND entrydate >= #{empQuery.begin} </if> <if test="empQuery.end != null"> AND entrydate <= #{empQuery.end} <!-- <在XML中有特殊含义 需要被转义字符代替 --> </if> </where>
-
动态SQL使用-SET
如果if经过了判断第一个更新字段包含前,,基于set标签进行包裹可以自动将前逗号去掉
UPDATE emp <set> <if test="emp.username != null and emp.username != ''"> username = #{emp.username} </if> <if test="emp.password != null and emp.password != ''"> , password = #{emp.password} </if> <if test="emp.name != null and emp.name != ''"> , name = #{emp.name} </if> <if test="emp.gender != null"> , gender = #{emp.gender} </if> </set> WHERE id = #{emp.id}
-
动态SQL使用-FOREACH
foreach标签可以用于遍历接口中的集合/数组参数,在SQL语句中进行动态的拼接
//基于集合删除员工信息 public void batchDelete(@Param("deleteIds") List<Integer> deleteIds);
<delete id="batchDelete"> DELETE FROM emp WHERE id IN <foreach collection="deleteIds" item="deleteId" separator="," open="(" close=")"> #{deleteId} </foreach> </delete>
-
动态SQL使用-SQL
SQL片段标签可以将XML文件重复的内容抽取出来,并且可以在多处复用
当要使用指定SQL片段的内容进行拼接时,使用include标签
<!-- SQL片段可以抽取XML文件中重复的内容 --> <sql id="BASE_COLUMN"> id, username, password, name, gender, image, job, entrydate, dept_id </sql> <select id="selectEmpById" resultType="com.itheima.entity.Emp"> SELECT <include refid="BASE_COLUMN"> </include> FROM emp WHERE id = #{id} </select> <select id="selectEmpListByCondition" resultType="com.itheima.entity.Emp"> SELECT <include refid="BASE_COLUMN"> </include> FROM emp </select>