当前位置: 首页 > article >正文

Spring(8)——MyBatis入门(2)

一、Mybatis的xml配置文件

Mybatis的开发有两种方式:

  1. 注解
  2. xml

上一篇博客介绍了用注解的方式操作数据库,这一篇介绍通过xml配置文件的方式操作数据库。

1.1 xml配置文件规则

在Mybatis中使用XML映射文件方式开发,需要符合一定的规范:

  1. XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)。
  2. XML映射文件的namespace属性为Mapper接口全限定名一致
  3. XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。

在这里插入图片描述

其中< select >标签中的resultType属性,指的是查询返回的单条记录所封装的类型。

1.2 xml配置文件实现

第一步:创建XML映射文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第二步:编写xml映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mhw.quick_mybatis.mapper.EmpMapper">
    <select id="list3" resultType="com.mhw.quick_mybatis.pojo.Emp">
        SELECT *
        FROM emp
        WHERE name LIKE CONCAT('%', #{name}, '%')
        AND gender = #{gender}
        AND entrydate BETWEEN #{begin} AND #{end}
        ORDER BY update_time DESC
    </select>
</mapper>

映射文件中的sql语句的id与Mapper接口方法名保持一致,并且返回值为相同类型。
在这里插入图片描述

二、Mybatis动态SQL

随着用户的输入或外部条件的变化而变化的Sql语句,就是动态Sql。

2.1 <if>标签

用于判断条件是否成立。使用test属性进行条件判断,如果条件为true则进行拼接。

对上面sql进行改造:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mhw.quick_mybatis.mapper.EmpMapper">
    <select id="list3" resultType="com.mhw.quick_mybatis.pojo.Emp">
        SELECT *
        FROM emp
        WHERE
        <if test="name != null">
            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>
        ORDER BY update_time DESC
    </select>
</mapper>

修改之后就可以通过传入的参数(如下)动态的拼接sql语句。

@Test
public void getList(){
    List<Emp> emps = empMapper.list3("张", (short) 1, LocalDate.of(2010, 1, 1), LocalDate.of(2020, 1, 1));
    System.out.println(emps);
 }

但是此时还有些问题:

  1. 当name参数为null时,sql就会拼接为

    select * from emp where and gender = 1 
    and entrydate BETWEEN  2010-1-1 and 2020-1-1
    order by update_time DESC
    

    可以看到,where的后面多了一个and。

  2. 当参数都为null的时候,sql就会拼接为

    select * from emp 
    where 
    order by update_time DESC
    

    可以看到,where都成多余的了。

2.2 <where>标签

以上问题的解决方案:使用 <where> 标签代替SQL语句中的where关键字 。<where> 只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或OR 。

再次修改:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mhw.quick_mybatis.mapper.EmpMapper">
    <select id="list3" resultType="com.mhw.quick_mybatis.pojo.Emp">
        SELECT *
        FROM emp
        <where>
            <if test="name != null">
                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>
</mapper>

测试:

@Test
    public void getList(){
        List<Emp> emps = empMapper.list3(null, null, null,null);
        System.out.println(emps);
     }

在这里插入图片描述

2.3 <set>标签

当我们需要使用update更新数据库的时候,运用<if>标签:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mhw.quick_mybatis.mapper.EmpMapper">
    <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>
        where id=#{id}
    </update>
</mapper>

测试:

 @Test
    public void testUpdate2(){
//要修改的员工信息
        Emp emp = new Emp();
        emp.setId(20);
        emp.setUsername("Tom111");
        emp.setName("汤姆911");
        emp.setUpdateTime(LocalDateTime.now());
//调用方法,修改员工数据
        empMapper.update2(emp);
    }

因为使用了<if>标签,可以动态拼接sql,但是在上面这个测试案例中,我们对于最后一个

 <if test="updateTime != null">
            update_time=#{updateTime}
        </if>

也是有传值的,但是如果我们改为这样:

 @Test
    public void testUpdate2(){
//要修改的员工信息
        Emp emp = new Emp();
        emp.setId(20);
        emp.setUsername("Tom111");
        emp.setName("汤姆911");
//调用方法,修改员工数据
        empMapper.update2(emp);
    }

然后进行测试会发生报错,因为最后一个update_time我们没有传值,这个位置就空了,上一个参数是name,但是在拼接sql时
在这里插入图片描述

name后面多一个逗号,这会导致出现sql语法错误,这里就需要引入新的标签<set>了,他的作用可以理解为和<where>一样,可以动态的在SQL语句中插入set关键字,并会删掉额外的逗号。

2.4 <foreach>标签

在这里插入图片描述

当进行批量删除的时候,如果我们手动编写sql语句(按照用户id删除),可以这样写:

delete from emp where id in (1,2,3);

将范围改为动态的,传入一个list,删除list里所有id对应记录,此时就需要用到<foreach>

Mapper接口:

@Mapper
public interface EmpMapper {
//批量删除
public void deleteByIds(List<Integer> ids);
}

XML映射文件:

使用 <foreach> 遍历deleteByIds方法中传递的参数ids集合

<foreach collection="集合名称" item="集合遍历出来的元素/项" separator="每
一次遍历使用的分隔符"
open="遍历开始前拼接的片段" close="遍历结束后拼接的片段">
</foreach>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
<!--删除操作-->
<delete id="deleteByIds">
delete from emp where id in
<foreach collection="ids" item="id" separator="," open="("
close=")">
#{id}
</foreach>
</delete>
</mapper>

在这里插入图片描述

2.5 <sql> & <include>

在xml映射文件中配置的SQL,有时可能会存在很多重复的片段,此时就会存在很多冗余的代码。
在这里插入图片描述
在这里插入图片描述

我们可以对重复的代码片段进行抽取,将其通过 <sql> 标签封装到一个SQL片段,然后再通过<include> 标签进行引用 。

在这里插入图片描述

SQL片段: 抽取重复的代码

<sql id="commonSelect">
select id, username, password, name, gender, image, job,
entrydate, dept_id, create_time, update_time from emp
</sql>

然后通过 <include> 标签在原来抽取的地方进行引用。操作如下:

<select id="list" resultType="com.itheima.pojo.Emp">
<include refid="commonSelect"/>
<where>
<if test="name != null">
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>

http://www.kler.cn/a/592167.html

相关文章:

  • pycharm运行OpenCV项目踩坑记录
  • 3D开发工具HOOPS SDK:赋能CAM软件开发的利器
  • 以太网安全管理实验——ARP欺骗
  • Deepseek本地部署及本地知识库搭建(保姆级截图)
  • VIVO手机如何实现证件照换底色?证件照换底色技巧分享
  • 【RabbitMQ】RabbitMQ的基本架构是什么?包括哪些核心组件?
  • NIC数据包的接收与发送
  • 【STL】string类用法介绍及部分接口的模拟实现
  • pnpm创建vite
  • 蓝桥杯第13届真题2
  • C++项目:高并发内存池_上
  • 【云原生之kubernetes实战】在k8s环境中高效部署minio对象存储(详细教程)
  • pytorch 笔记:张量索引的维度扩展规则
  • python二级每日十题
  • JS逆向_腾讯点选_VMP补环境
  • (五)Reactor核心-前置知识4
  • (六)Reactive-Stream 响应式流
  • 霍尔传感器与电流互感器的区别
  • 男女搭配(数学思维)
  • 如何实现一个bind函数?