本文是在上一篇博客的代码基础上进行的,不清楚文件结构的请先回顾上一篇博客Mybatis——快速入门-CSDN博客
xml映射文件
介绍
MyBatis 的 XML 映射文件是 MyBatis 框架中用于定义 SQL 语句、映射规则等配置的重要文件。它允许开发者将 SQL 语句与 Java 对象映射关系进行分离,使得数据库操作更加灵活和方便。XML 映射文件通常以 .xml
作为文件扩展名,并且需要遵守 MyBatis 定义的 XML 格式和规则。
要求
1、XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)。
2、XML映射文件的namespace属性为Mapper接口全限定名一致。
3、XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。
如上图所示就是一个xml映射文件。
1、resources包和java包是同级的,所以xml映射文件的报名从下一级开始写,并且要和mapper接口的包名和接口名保持一致。所以我们在resources包下再新建com.itheima.mapper包,在这包下新建xml文件,命名为EmpMapper和接口名保持一致。
2、我们需要再mapper标签内编写SQL语句,mapper标签的namespace属性要和Mapper接口的全限定名一致。
3、在mapper标签内编写SQL语句,SQL语句是什么操作就用什么标签,比如查询操作就用<select></select>标签,标签的id属性和Mapper接口中的查询方法名一样, resultType返回值属性和方法返回值一样,如果是对象要用全限定名。
4、如果使用xml映射文件定义SQL语句,则在原Mapper接口中的相应方法上不需要加注解和SQL语句,SQL语句在xml中编写,会根据id自动匹配相应的方法
动态SQL
介绍
随着用户的输入或外部条件变化而变化的SQL语句,称为动态SQL
场景:查询时,不一定每次都指定全部条件,可能指定个别条件,其余条件设置为null。静态查询会查询时匹配字段值为null的数据,而动态查询会自动忽略null条件,根据每次指定的不同条件进行不同的查询(根据输入条件动态组装)
常见标签
<if>
用于判断条件是否成立,使用test属性进行条件判断(格式:test="条件"),如果条件为true,则拼接SQL
<where>
元素只会在子元素有内容的情况下才插入where子句,而且会自动去除子句开头多余的and或or
<set>
动态地在行首插入set关键字,并会删掉额外的逗号(在update语句中)
<foreach>
标签是遍历集合时使用的,有5个属性:
1.collection:集合名称
2.items:集合遍历出来的元素/项
3.separator:每一次遍历使用的分隔符
4.open:遍历开始前拼接的片段
4.close:遍历结束后拼接的片段
<sql>
定义可重用的sql片段(相当于方法),要指定id(相当于方法名)
<refild>
通过属性refid(指定要使用的sql标签的id,相当于方法名),使用指定的sql标签片段
应用
以下所有操作都需要在Mapper接口中先声明方法,再在xml中编写SQL语句,注意id和方法名一样
动态更新员工
根据id动态更新员工信息时,如果不同员工需要修改的字段不一样,比如要的人要修改name,有的人要修改gender,这时如果SQL语句写死就不能满足需求,需要使用动态SQL。
我们把每个员工对象作为参数传过去,如果此对象中某个属性值不为空,就更新它,如果某个属性值为空,就代表不用更新。
这时就需要<if>标签来判断表中所有字段每个字段是否为空,而由于SQL语句中不同字段间有逗号隔开,如果最后一个字段为空,倒数第二个字段不为空,那么拼接时自动忽略最后一个字段,倒数第二个字段后就会多一个逗号,这时就需要引入<set>标签。
<update id="update2">
update emp
<set>
<if test="username != null">username = #{username},</if>
<if test="name != null">name = #{name},</if>
<if test="gender != null">gender = #{gender},</if>
<if test="image != null">image = #{image},</if>
<if test="job != null">job = #{job},</if>
<if test="entrydate != null">entrydate = #{entrydate},</if>
<if test="deptId != null">dept_id = #{deptId},</if>
<if test="updateTime != null">update_time = #{updateTime}</if>
</set>
where id = #{id}
</update>
动态查询
查询时如果我们需要进行模糊查找并且每次按照不同的字段进行查找,比如这次查找性别为男的所有员工,下次查找姓名中含有张的所有员工,同样如SQL语句写死就不能满足需求,需要使用动态SQL。
将可以查找的所有字段作为参数传递,SQL语句中判断,如果该字段为空则不作为查询条件,如果不为空则作为查询条件。
需要使用<if>和<where>标签,并在<select>标签中制定返回值为Emp对象类型,还可以使用<include>标签引用<sql>标签
<sql id="commonSelect">
select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time
from emp
</sql>
<!--动态查询-->
<!--resultType: 单条记录封装的类型-->
<select id="list" resultType="com.itheima.pojo.Emp">
<include refid="commonSelect"/>
<where><!--自动判断标签内条件是否成立,如果都不成立则不会生成-->
<if test="name != null"><!--如果条件成立则拼接标签内SQL-->
name like concat('%', #{name}, '%')
</if>
<if test="gender != null">
and gender = #{gender}
</if>
<if test="begin != null and end != null">
and entrydate between #{begin} and #{end}
</if>
</where>
order by update_time desc
</select>
批量删除员工
根据id批量删除员工时,传递的参数是一个id类型的集合,就需要使用<foreach>标签来遍历这个集合
<!--批量删除员工 (18,19,20)-->
<!--
collection: 遍历的集合
item: 遍历出来的元素
separator: 分隔符
open: 遍历开始前拼接的SQL片段
close: 遍历结束后拼接的SQL片段
-->
<delete id="deleteByIds">
delete from emp where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}<!--每一次遍历出的元素-->
</foreach>
</delete>