【JavaWeb】Mybatis 布满荆棘的人生 2024-04-26 03:08 3阅读 0赞 > 🔥 本文由 [程序喵正在路上][Link 1] 原创,CSDN首发! > 💖 系列专栏:[JavaWeb开发][JavaWeb] > 🌠 首发时间:2024年3月7日 > 🦋 欢迎关注🖱点赞👍收藏🌟留言🐾 #### 目录 #### * Mybatis介绍 * Mybatis入门 * * 快速入门 * JDBC介绍 * 数据库连接池 * lombok * Mybatis基础增删改查 * * 准备 * 删除 * 插入 * 更新 * 查询 * Mybatis XML映射文件 * Mybatis动态SQL * * \\<if> * \\<foreach> * \\<sql>&\\<include> ## Mybatis介绍 ## **什么是Mybatis** * MyBatis是一款优秀的**持久层**框架,用于简化JDBC的开发 ![在这里插入图片描述][34d1f0bbcfad4b5aab077c6856584fca.png] * MyBatis本是 Apache的一个开源项目iBatis,2010年这个项目由apache迁移到了google code,并且改名为MyBatis,2013年11月迁移到Github * 官网:[https://mybatis.org/mybatis-3/zh\_CN/index.html][https_mybatis.org_mybatis-3_zh_CN_index.html] ## Mybatis入门 ## ### 快速入门 ### 案例:使用Mybatis查询所有用户数据 * 准备工作(创建springboot工程、数据库表user、实体类User) * 引入Mybatis的相关依赖,配置Mybatis(数据库连接信息) * 编写SQL语句(注解/XML) 打开我们之前创建的工程 web\_project,选择 File → \\rightarrow → New → \\rightarrow → Module → \\rightarrow → Spring Initializr,和之前一样填写一下内容: ![在这里插入图片描述][cdfd71bb94004dbbaa6ce850823f586a.png] 勾选Mybatis的相关依赖: ![在这里插入图片描述][167b7d1f28db42a49635e4faa06322bf.png] 然后我们将模块中不需要的部分删掉,保持工程的简洁,剩下这两个即可: ![在这里插入图片描述][c4dd71cd53e04d7da824edd836070fd6.png] 对 pom.xml 中一些依赖的说明: ![在这里插入图片描述][1316aaf12d0d4e9592e5f3074175f594.png] 新建数据库 mybatis,新建 console mybatis,复制下列语句并执行,创建表user: create table user ( id int unsigned primary key auto_increment comment 'ID', name varchar(100) comment '姓名', age tinyint unsigned comment '年龄', gender tinyint unsigned comment '性别, 1:男, 2:女', phone varchar(11) comment '手机号' ) comment '用户表'; insert into user(id, name, age, gender, phone) VALUES (null, '白眉鹰王', 55, '1', '18800000000'); insert into user(id, name, age, gender, phone) VALUES (null, '金毛狮王', 45, '1', '18800000001'); insert into user(id, name, age, gender, phone) VALUES (null, '青翼蝠王', 38, '1', '18800000002'); insert into user(id, name, age, gender, phone) VALUES (null, '紫衫龙王', 42, '2', '18800000003'); insert into user(id, name, age, gender, phone) VALUES (null, '光明左使', 37, '1', '18800000004'); insert into user(id, name, age, gender, phone) VALUES (null, '光明右使', 48, '1', '18800000005'); ![在这里插入图片描述][764a7e78f84f4f02943070582060c6fe.png] 在刚刚创建的模块的包下创建一个包 pojo 专门用来存放实体类,在 pojo 下创建实体类 User,根据表 User 先写出它的属性,然后快捷生成构造方法、get 和 set 方法以及 toString() 方法: ![在这里插入图片描述][f306edea2ea34ff9af9aabbcbada73a0.png] 配置Mybatis(数据库连接信息),复制以下内容到 application.properties 中: ![在这里插入图片描述][597e3f91bee84e76b29f28721689bd29.png] #驱动类名称 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #数据库连接的url spring.datasource.url=jdbc:mysql://localhost:3306/mybatis #连接数据库的用户名 spring.datasource.username=root #连接数据库的密码 spring.datasource.password=1234 记得将用户名和密码改成你自己的 然后,创建一个包 mapper,在包下创建一个接口 UserMappe,编写SQL语句r: ![在这里插入图片描述][341f4c7dcec94b209a2045304b5e9c3c.png] import com.xixi.pojo.User; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import java.util.List; @Mapper // 在运行时,会自动生成该接口的实现类对象(代理对象),并且将该对象交给IOC容器管理 public interface UserMapper { // 查询全部用户信息 @Select("select * from user") public List<User> list(); } 接下来,我们来测试一下: 找到工程自带的测试类,编写测试代码: ![在这里插入图片描述][57e706ce4b574d0b80a66e072430e117.png] import com.xixi.mapper.UserMapper; import com.xixi.pojo.User; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.List; @SpringBootTest // springboot整合单元测试的注释 class SpringbootMybatisQuickstartApplicationTests { @Autowired private UserMapper userMapper; @Test public void testListUser() { List<User> userList = userMapper.list(); userList.stream().forEach(user -> { System.out.println(user); }); } } 其中 `@Autowired` 注解为依赖注入方面的内容,如果不懂可以点击 [这篇文章][Link 2] 观看最后的分层解耦部分内容 最后,右键执行 testListUser 方法,显示出用户信息即为成功: ![在这里插入图片描述][ef49b72ae4e64e3a934935ed3e74b662.png] **配置SQL提示** 默认在mybatis中编写SQL语句是不识别的。可以做如下配置,选中SQL语句右键按下图操作: ![在这里插入图片描述][feb8e49044c4453388f1bbad8f5fb4a7.png] 然后我们发现SQL语句颜色变了,但是user报红了: ![在这里插入图片描述][de527f3d072e4fc9858b3fa3c1cd679c.png] * 产生原因:Idea和数据库没有建立连接,识别不到表信息 * 解决方式:在Idea中配置MySQL数据库连接 ![在这里插入图片描述][b16cd3776e3a4a95a01cc038c0fe3a7c.png] ![在这里插入图片描述][84f8e1382cfe4b7cbf6b73a7bab3ab87.png] ### JDBC介绍 ### JDBC: (Java DataBase Connectivity),就是使用Java语言操作关系型数据库的一套API。 ![在这里插入图片描述][0ef2e38a80794c7eae67bb90d8798eda.png] **本质** * sun公司官方定义的一套操作所有关系型数据库的规范,即接口 * 各个数据库厂商去实现这套接口,提供数据库驱动jar包 * 我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类 **Mybatis VS JDBC** ![在这里插入图片描述][c283b88a83324d59aed7ca2b5f240eed.png] ### 数据库连接池 ### * 数据库连接池是个容器,负责分配、管理数据库连接 (Connection) * 它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个 * 释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏 ![在这里插入图片描述][c642bde034504492ac2b4976f59e5981.png] **优势** * 资源重用 * 提升系统响应速度 * 避免数据库连接遗漏 **数据库连接池** 标准接口:DataSource * 官方(sun)提供的数据库连接池接口,由第三方组织实现此接口。 * 功能:获取连接 常见产品: ![在这里插入图片描述][c356a3b41a884c96899a2864a4eef96c.png] Druid(德鲁伊) * Druid连接池是阿里巴巴开源的数据库连接池项目 * 功能强大,性能优秀,是Java语言最好的数据库连接池之一 **切换Druid数据库连接池** 在 pom.xml 中添加依赖: ![在这里插入图片描述][dc89a9fcd70246138f0e28e6d30a8024.png] application.properties 中的内容写成这样也可以: ![在这里插入图片描述][5840421a5daa49e5aca9601b6cc76c47.png] ### lombok ### 在前面写的实体类 User 中,我们快捷生成了一大堆方法,虽然是快捷生成的,但是当类的属性多了之后,还是很麻烦的,下面我们介绍一个工具包 lombok ![在这里插入图片描述][1f6224e338e94c80a303313438718e18.png] **lombok** Lombok是一个实用的Java类库,能通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,并可以自动化生成日志变量,简化java开发、提高效率。 lombok 拥有以下注解: ![在这里插入图片描述][0a4bb238b83d44739378819ce6d8d403.png] **lombok使用方法** 1. 引入依赖,在 pom.xml 中加入 lombok 的依赖 <!-- lombok工具包--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> 2. 修改 User 类 ![在这里插入图片描述][f52ee151c4d24f51bf07b81346d07406.png] 3. 测试,能够查询出数据即为成功 ![在这里插入图片描述][acafd220a4a94fc4bfcf2161a6670ef5.png] **注意事项** * Lombok会在编译时,自动生成对应的java代码。我们使用lombok时,还需要安装一个lombok的插件 (idea自带)。 ## Mybatis基础增删改查 ## 根据页面原型及需求,完成员工管理的需求开发。 ![在这里插入图片描述][9826b6c8c0184877b88759a27b237b04.png] ### 准备 ### * 准备数据库表 emp * 创建一个新的springboot工程,选择引入对应的起步依赖(mybatis、mysql驱动、lombok) * application.properties中引入数据库连接信息 * 创建对应的实体类 Emp(实体类属性采用驼峰命名) * 准备Mapper接口 EmpMapper 1. 复制下列语句到 mybatis 中并执行 -- 部门管理 create table dept ( id int unsigned primary key auto_increment comment '主键ID', name varchar(10) not null unique comment '部门名称', create_time datetime not null comment '创建时间', update_time datetime not null comment '修改时间' ) comment '部门表'; insert into dept (id, name, create_time, update_time) values (1, '学工部', now(), now()), (2, '教研部', now(), now()), (3, '咨询部', now(), now()), (4, '就业部', now(), now()), (5, '人事部', now(), now()); -- 员工管理 create table emp ( id int unsigned primary key auto_increment comment 'ID', username varchar(20) not null unique comment '用户名', password varchar(32) default '123456' comment '密码', name varchar(10) not null comment '姓名', gender tinyint unsigned not null comment '性别, 说明: 1 男, 2 女', image varchar(300) comment '图像', job tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师', entrydate date comment '入职时间', dept_id int unsigned comment '部门ID', create_time datetime not null comment '创建时间', update_time datetime not null comment '修改时间' ) comment '员工表'; INSERT INTO emp (id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time) VALUES (1, 'jinyong', '123456', '金庸', 1, '1.jpg', 4, '2000-01-01', 2, now(), now()), (2, 'zhangwuji', '123456', '张无忌', 1, '2.jpg', 2, '2015-01-01', 2, now(), now()), (3, 'yangxiao', '123456', '杨逍', 1, '3.jpg', 2, '2008-05-01', 2, now(), now()), (4, 'weiyixiao', '123456', '韦一笑', 1, '4.jpg', 2, '2007-01-01', 2, now(), now()), (5, 'changyuchun', '123456', '常遇春', 1, '5.jpg', 2, '2012-12-05', 2, now(), now()), (6, 'xiaozhao', '123456', '小昭', 2, '6.jpg', 3, '2013-09-05', 1, now(), now()), (7, 'jixiaofu', '123456', '纪晓芙', 2, '7.jpg', 1, '2005-08-01', 1, now(), now()), (8, 'zhouzhiruo', '123456', '周芷若', 2, '8.jpg', 1, '2014-11-09', 1, now(), now()), (9, 'dingminjun', '123456', '丁敏君', 2, '9.jpg', 1, '2011-03-11', 1, now(), now()), (10, 'zhaomin', '123456', '赵敏', 2, '10.jpg', 1, '2013-09-05', 1, now(), now()), (11, 'luzhangke', '123456', '鹿杖客', 1, '11.jpg', 5, '2007-02-01', 3, now(), now()), (12, 'hebiweng', '123456', '鹤笔翁', 1, '12.jpg', 5, '2008-08-18', 3, now(), now()), (13, 'fangdongbai', '123456', '方东白', 1, '13.jpg', 5, '2012-11-01', 3, now(), now()), (14, 'zhangsanfeng', '123456', '张三丰', 1, '14.jpg', 2, '2002-08-01', 2, now(), now()), (15, 'yulianzhou', '123456', '俞莲舟', 1, '15.jpg', 2, '2011-05-01', 2, now(), now()), (16, 'songyuanqiao', '123456', '宋远桥', 1, '16.jpg', 2, '2010-01-01', 2, now(), now()), (17, 'chenyouliang', '123456', '陈友谅', 1, '17.jpg', NULL, '2015-03-21', NULL, now(), now()); 2. 创建一个新的springboot工程,选择引入对应的起步依赖(mybatis、mysql驱动、lombok) ![在这里插入图片描述][0b6a8027aa4547aea04fce5bc75abd8f.png] ![在这里插入图片描述][f19a6a284448417bb64e4025093af1dd.png] 3. application.properties中引入数据库连接信息 #驱动类名称 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #数据库连接的url spring.datasource.url=jdbc:mysql://localhost:3306/mybatis #连接数据库的用户名 spring.datasource.username=root #连接数据库的密码 spring.datasource.password=1234 4. 创建对应的实体类 Emp(实体类属性采用驼峰命名),准备Mapper接口 EmpMapper ![在这里插入图片描述][08bb45c18f954abe98aa66123e249b8a.png] ### 删除 ### **根据主键删除** ![在这里插入图片描述][f473e3d70d5b46669e6c8a221d195e43.png] * SQL语句: delete from emp where id = 17; * 接口方法: @Delete("delete from emp where id = #{id}") public void delete(Integer id); 记得刷新一下,不然是找不到 emp 表的: ![在这里插入图片描述][4bcf6eb4194f47628820a66bbab552e6.png] 写完后,我们来测试一下是否能够成功删除,在测试类中编写代码测试: ![在这里插入图片描述][ca2163ccde8d4f099be0908fc3464096.png] 运行后,发现 17 号已经不在表中,说明已经被删除了 ![在这里插入图片描述][f7c5bcf5793e4255bd365265028b8410.png] 注意事项 * 如果mapper接口方法形参只有一个普通类型的参数,\#\{…\} 里面的属性名可以随便写,如:\#\{id\}、\#\{value\}。 * 但是建议两者保持一致,增强可读性 **日志输出** * 可以在application.properties中添加配置,打开mybatis的日志,并指定输出到控制台。 #指定mybatis输出日志的位置,输出控制台 mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl 再次运行,我们发现运行结果多了一些东西,我们称之为预编译SQL ![在这里插入图片描述][5d7eff04eb694c368245b5148b1988da.png] ![在这里插入图片描述][1df0e749f42a449a92be19335511ebfe.png] **预编译SQL的优势** * 性能更高 * 更安全 (可以防止SQL注入) **SQL注入** * SQL注入是通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法。 **参数占位符** ![在这里插入图片描述][3a4a9d61cd76427b9b1b7745ed5f3318.png] ### 插入 ### 实现新增员工的操作: ![在这里插入图片描述][ccb9948e878c486a9a8f40ab2399dfd3.png] * SQL语句: insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values ('songyuanqiao', '宋远桥', 1, '1.jpg', 2, '2012-10-09', 2, '2022-10-01 10:00:00', '2022-10-01 10:00:00'); * 接口方法: //新增员工 @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) " + "values(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})") public void insert(Emp emp); * 测试方法: @Test public void testInsert() { //构造员工对象 Emp emp = new Emp(); emp.setUsername("Tom"); emp.setName("汤姆"); emp.setImage("1.jpg"); emp.setGender((short) 1); emp.setJob((short) 1); emp.setEntrydate(LocalDate.of(2000, 1, 1)); emp.setCreateTime(LocalDateTime.now()); emp.setUpdateTime(LocalDateTime.now()); emp.setDeptId(1); //执行新增员工信息操作 empMapper.insert(emp); } ![在这里插入图片描述][a3b7eb677bca4e8e82f3aec7f27a127e.png] **新增(主键返回)** * 描述:在数据添加成功后,需要获取插入数据库数据的主键。如:添加套餐数据时,还需要维护套餐菜品关系表数据。 如果我们在刚刚插入员工数据后,想获取它的ID,应该怎么办? 如果直接获取,是行不通的。我们先将Tom这个员工删除,然后在 testInsert() 方法中添加一行输出语句,来看看结果: ![在这里插入图片描述][a2442672b8ff4b31beefddc82f480bc1.png] 我们发现获取不到ID。那该如何实现呢? 在接口方法前添加主键返回的注解: //新增员工 @Options(useGeneratedKeys = true, keyProperty = "id") //会自动将生成的主键值,赋值给emp对象的id属性 @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) " + "values(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})") public void insert(Emp emp); ![在这里插入图片描述][610c1742affb4b0ebf47254363029cb5.png] ### 更新 ### ![在这里插入图片描述][2efba31b5d5546f49534117bf6b4ecb6.png] * 接口方法 //更新员工信息 @Update("update emp set username=#{username}, name=#{name}, gender=#{gender}, image=#{image}, job=#{job}, " + "entrydate=#{entrydate}, dept_id=#{deptId}, update_time=#{updateTime} where id=#{id}") public void update(Emp emp); 测试: ![在这里插入图片描述][b601cde5c41842de8f384e00efd154e6.png] ![在这里插入图片描述][eacf2a87ea014757ad582745aea1efef.png] ### 查询 ### **查询(根据ID查询)** * 接口方法 //根据ID查询 @Select("select * from emp where id = #{id}") public Emp getById(Integer id); * 测试方法: //根据ID查询员工 @Test public void testGetById() { Emp emp = empMapper.getById(16); System.out.println(emp); } ![在这里插入图片描述][0c2a22db4c6b436cb963dfb775b65932.png] **数据封装** * 实体类属性名和数据库表查询返回的字段名一致,mybatis会自动封装。 * 如果实体类属性名和数据库表查询返回的字段名不一致,不能自动封装。 ![在这里插入图片描述][98c51944899a4e2090c7bb969d24fa17.png] * 解决方案一:起别名:在SQL语句中,对不一样的列名起别名,别名和实体类属性名一样。 //方案一:给字段起别名,让别名与实体类属性一致 @Select("select id, username, password, name, gender, image, job, entrydate, dept_id deptId, " + "create_time createTime, update_time updateTime from emp where id = #{id}") public Emp getById(Integer id); * 方案二:手动结果映射:通过 `@Results`及`@Result` 进行手动结果映射。 //方案二:通过@Results,@Result注解手动映射封装 @Results({ @Result(column = "dept_id", property = "deptId"), @Result(column = "create_time", property = "createTime"), @Result(column = "update_time", property = "updateTime") }) @Select("select * from emp where id = #{id}") public Emp getById(Integer id); * 方案三:开启驼峰命名:如果字段名与属性名符合驼峰命名规则,mybatis会自动通过驼峰命名规则映射。 在 application.properties 中添加: #开启驼峰命名自动映射,即从数据库字段名 a_column 映射到Java 属性名 aColumn。 mybatis.configuration.map-underscore-to-camel-case=true 接口方法不用修改 三种方案都可以,最简单的是第三种 ![在这里插入图片描述][d7c921370b6243f2a3b4d0a17061ce65.png] **查询(条件查询)** ![在这里插入图片描述][7356b994ce1947a39a5a33a2df50d4d5.png] * SQL语句 select * from emp where name like '%张%' and gender = 1 and entrydate between '2010-01-01' and '2020-01-01 ' order by update_time desc; * 接口方法 //根据条件查询员工 //方法一:不推荐 @Select("select * from emp where name like '%${name}%' and gender = #{gender} and " + "entrydate between #{begin} and #{end} order by update_time desc") public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end); //方法二:推荐 @Select("select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and " + "entrydate between #{begin} and #{end} order by update_time desc") public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end); * 测试: //根据条件查询员工 @Test public void testList() { List<Emp> empList = empMapper.list("张", (short) 1, LocalDate.of(2000, 1, 1), LocalDate.of(2020, 1, 1)); System.out.println(empList); } ![在这里插入图片描述][422966a12f824c04bd29930c96bebe90.png] **参数名说明** ![在这里插入图片描述][291e9e72ef3a4a01847c12cf2656e572.png] ## Mybatis XML映射文件 ## 前面我们讲解了用注解的方式来编写SQL语句,下面我们来介绍用XML映射文件的方式 **规范** * XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)。 * XML映射文件的namespace属性为Mapper接口全限定名一致。 * XML映射文件中sql语句的id与Mapper 接口中的方法名一致,并保持返回类型一致。 右键 resources → \\rightarrow → New → \\rightarrow → Directory: ![在这里插入图片描述][8042cc68430b4749acf0c6dc178245bc.png] 然后在这个包下新建 EmpMapper.xml 文件,并复制下列约束到 XML 文件中: <?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"> 接着在后面写SQL语句: <!-- namespace属性与Mapper接口全限定名一致--> <mapper namespace="com.xixi.mapper.EmpMapper"> <!-- sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致--> <select id="list" resultType="com.xixi.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> 返回类型可以按下图操作复制: ![在这里插入图片描述][dda19e4ea9fe4206825fc06a4728d8ef.png] 然后我们再将接口方法的注解删掉,剩下方法即可: ![在这里插入图片描述][92bc2f5dff2a41628e9c6546aee67012.png] 接着,进行测试: ![在这里插入图片描述][129667957b3c4724b1d818ebf626f40c.png] **MybatisX** * MybatisX 是一款基于 IDEA 的快速开发Mybatis的插件,为效率而生 * 安装方法: ![在这里插入图片描述][a7d70f1052db4823aebc28336bab246d.png] 安装成功后,我们会发现页面多了几个小鸟的标志,点击一下接口方法前面的标志,发现页面会自动跳转到其对应的 XML 映射文件: ![在这里插入图片描述][7bd4a9c254d24e16a2b00b005379056c.png] ![在这里插入图片描述][df4c2f552b634eb386866f09c0df689d.png] **选择注解好还是XML好** 使用Mybatis的注解,主要是来完成一些简单的增删改查功能。如果需要实现复杂的SQL功能,建议使用XML来配置映射语句。 ## Mybatis动态SQL ## 随着用户的输入或外部条件的变化而变化的SQL语句,我们称为动态SQL。 ![在这里插入图片描述][39b5241b94a94c78b896588ef4f903f0.png] 在前面写的这个SQL语句中,如果我们在传递参数的时候只传递过来 name,gender 或者 begin 和 end,也就是不给全条件,那么我们是查询不到数据的,这个时候我们就需要动态SQL的帮助了 ### <if> ### * `<if>`:用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL。 * `<where>`:where 元素只会在子元素有内容的情况下才插入where子句。而且会自动去除子句的开头的AND或OR。 改进: <!-- namespace属性与Mapper接口全限定名一致--> <mapper namespace="com.xixi.mapper.EmpMapper"> <!-- sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致--> <select id="list" resultType="com.xixi.pojo.Emp"> select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time 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> 我们只传入一个性别,进行测试: ![在这里插入图片描述][a1e8e25bf78b499c92adafba6d0cf950.png] **<if>案例** 完善更新员工功能,修改为动态更新员工数据信息 ![在这里插入图片描述][242d1b8a4a70498a94d9cba8ab5cbc37.png] **需求** * 动态更新员工信息,如果更新时传递有值,则更新;如果更新时没有传递值,则不更新。 **实现** * `<set>`:动态地在行首插入 SET 关键字,并会删掉额外的逗号。(用在update语句中) 将接口方法的注解删掉,在 EmpMapper.xml 添加 XML 映射文件: <update id="update"> 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> 将测试方法随便修改一下进行测试: ![在这里插入图片描述][c9c9a308b50e46539b65b34fb5af50ad.png] 更新成功: ![在这里插入图片描述][7ed7bc36d34d4280bd4eb19e95883b74.png] ### <foreach> ### 需求:批量删除员工 ![在这里插入图片描述][d439a1751b994e968aa2d963faed93ac.png] * SQL语句 delete from emp where id in (1,2,3); * 接口方法 //批量删除 public void deleteByIds(List<Integer> ids); * XML映射文件 <delete id="deleteByIds"> delete from emp where id in <foreach collection="ids" item="id" separator="," open="(" close=")"> #{id} </foreach> </delete> * 测试方法 //批量删除员工 @Test public void testDeleteByIds() { List<Integer> ids = Arrays.asList(13, 14, 15); empMapper.deleteByIds(ids); } ![在这里插入图片描述][64d6dcea43844fa4bd4986eb87465840.png] `<foreach>`属性: * collection:集合名称 * item:集合遍历出来的元素/项 * separator:每一次遍历使用的分隔符 * open:遍历开始前拼接的片段 * close:遍历结束后拼接的片段 ### <sql>&<include> ### * `<sql>`:定义可重用的 SQL 片段 * `<include>`:通过属性refid,指定包含的sql片段 简单来说,`<sql>`用来保存SQL语句中经常用到的片段,而`<include>`则是用来将`<sql>`中的SQL片段引入,这样可以减小代码篇幅,同时方便我们对SQL语句进行修改 接下来我们对前面的这段SQL语句进行改造,将前面的部分拿出来: <!-- namespace属性与Mapper接口全限定名一致--> <mapper namespace="com.xixi.mapper.EmpMapper"> <!-- sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致--> <select id="list" resultType="com.xixi.pojo.Emp"> select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time 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> 改造后: <sql id="commonSelect"> select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp </sql> <!-- sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致--> <select id="list" resultType="com.xixi.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> 测试一下,成功: ![在这里插入图片描述][25d8c414325c41c18428f9ed33f0f1d5.png] [Link 1]: https://blog.csdn.net/weixin_62511863?spm=1011.2421.3001.5343 [JavaWeb]: https://blog.csdn.net/weixin_62511863/category_12511257.html?spm=1001.2014.3001.5482 [34d1f0bbcfad4b5aab077c6856584fca.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/14fa9c3cee264b2dad0aef5935368e37.png [https_mybatis.org_mybatis-3_zh_CN_index.html]: https://mybatis.org/mybatis-3/zh_CN/index.html [cdfd71bb94004dbbaa6ce850823f586a.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/3aa56fd90898484d8371c685e1049248.png [167b7d1f28db42a49635e4faa06322bf.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/f5fb34cbfcbc44539c28d1c0e6c1c012.png [c4dd71cd53e04d7da824edd836070fd6.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/667f4898c20d4664a3a840ae5b93051e.png [1316aaf12d0d4e9592e5f3074175f594.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/2940a692bbe847ccacb0fbddc1e089bb.png [764a7e78f84f4f02943070582060c6fe.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/cd4266d9347b4e4892776e8886aa00a6.png [f306edea2ea34ff9af9aabbcbada73a0.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/d7ecfdf6d25844428305d4e47e4e2988.png [597e3f91bee84e76b29f28721689bd29.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/d330506dbfab4239863bb47e50292c9e.png [341f4c7dcec94b209a2045304b5e9c3c.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/afdbaab1ac724333bccd0fc1c8f5bcd3.png [57e706ce4b574d0b80a66e072430e117.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/f7b086e0c1444b739b385b849cfbb548.png [Link 2]: https://blog.csdn.net/weixin_62511863/article/details/136017271 [ef49b72ae4e64e3a934935ed3e74b662.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/a6e745929f9c44c1b666cdaa42e8d487.png [feb8e49044c4453388f1bbad8f5fb4a7.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/e5173708d544445d88ade4a47b6017c7.png [de527f3d072e4fc9858b3fa3c1cd679c.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/2b07d74bea054c1a8845ce32b0ae9e0c.png [b16cd3776e3a4a95a01cc038c0fe3a7c.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/b3fa369eec1c409e9331c13b5b3e8b17.png [84f8e1382cfe4b7cbf6b73a7bab3ab87.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/d364c82a5ae74f91a870e6e182c947d0.png [0ef2e38a80794c7eae67bb90d8798eda.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/c04e9e85cb7540809cad02e02f00b222.png [c283b88a83324d59aed7ca2b5f240eed.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/083fd44ee3b241a289a38cc529397a6e.png [c642bde034504492ac2b4976f59e5981.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/55e6f9bd36c94a9f83dbc9a1807b5d9b.png [c356a3b41a884c96899a2864a4eef96c.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/5c61e5b5658b4d18aac0193ae3d5b20c.png [dc89a9fcd70246138f0e28e6d30a8024.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/64fa7fe675f54c4c8b20df0cfc71b021.png [5840421a5daa49e5aca9601b6cc76c47.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/905a84b84fb44ff784ba162e493ab6a6.png [1f6224e338e94c80a303313438718e18.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/b544613f6b804d4297404071564de5bb.png [0a4bb238b83d44739378819ce6d8d403.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/3794f299555745da969f789a34659aff.png [f52ee151c4d24f51bf07b81346d07406.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/cdaa09831e9b41cebed688bfca541406.png [acafd220a4a94fc4bfcf2161a6670ef5.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/96b9612db3c4450b8986ff07db32153f.png [9826b6c8c0184877b88759a27b237b04.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/dca6828ff0904cb1afd840b59d0f530b.png [0b6a8027aa4547aea04fce5bc75abd8f.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/3d12a420d6cb4cfc8a6270d834b48737.png [f19a6a284448417bb64e4025093af1dd.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/062a321b9da94df4917061c4cc55dc79.png [08bb45c18f954abe98aa66123e249b8a.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/8d9da6703e72419ca78c886ac4ff38ed.png [f473e3d70d5b46669e6c8a221d195e43.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/8f163dce58e34f24b33f9057d3f5726b.png [4bcf6eb4194f47628820a66bbab552e6.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/bb2a8356f1b348dcb3f45a6f0cf4e40e.png [ca2163ccde8d4f099be0908fc3464096.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/342d2d028f9343a39e8daec85bb6c1a9.png [f7c5bcf5793e4255bd365265028b8410.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/76c562f5a36e487e91c75b3052f69dc4.png [5d7eff04eb694c368245b5148b1988da.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/24c020170fe44c35925c2fbbf306ff41.png [1df0e749f42a449a92be19335511ebfe.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/9de5e568092a4dfebdbcca9cc16a6f9c.png [3a4a9d61cd76427b9b1b7745ed5f3318.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/eb0b93cad4ef48a083f1c91ab40f985d.png [ccb9948e878c486a9a8f40ab2399dfd3.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/30cb6fabdff441a99f77d272d1a937e1.png [a3b7eb677bca4e8e82f3aec7f27a127e.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/a0b8ab57cb1948489de8670dc45fcc87.png [a2442672b8ff4b31beefddc82f480bc1.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/448cb00173ac4ac09f3b93b2b2ce1ea3.png [610c1742affb4b0ebf47254363029cb5.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/5f9f15c51a904b49b94c49db574339f4.png [2efba31b5d5546f49534117bf6b4ecb6.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/2ed775f539aa4d15a8703f858f0f2a43.png [b601cde5c41842de8f384e00efd154e6.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/d6f47485ff994294bbc2e953cc403741.png [eacf2a87ea014757ad582745aea1efef.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/0249a3a31bc44f80b26113039cf98905.png [0c2a22db4c6b436cb963dfb775b65932.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/ec21f0beb9504ecb97a5cad6b542397d.png [98c51944899a4e2090c7bb969d24fa17.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/3fe5a6556c454372b4676fbb746fd569.png [d7c921370b6243f2a3b4d0a17061ce65.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/01685000e0274b13a589d5a79a5d8322.png [7356b994ce1947a39a5a33a2df50d4d5.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/fcbfde1a0949485d966c15998fea2b7a.png [422966a12f824c04bd29930c96bebe90.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/e15610a065fe482f9539c74b9dcd612e.png [291e9e72ef3a4a01847c12cf2656e572.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/f476cecb93804b8a99b241d69bc779fe.png [8042cc68430b4749acf0c6dc178245bc.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/28e0719a07f04e9d9c66d72289f7f68b.png [dda19e4ea9fe4206825fc06a4728d8ef.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/168ed416aae04bce82fefbdc1238e94f.png [92bc2f5dff2a41628e9c6546aee67012.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/8da504b0c9b8476991874f15fd794aac.png [129667957b3c4724b1d818ebf626f40c.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/5d60cfcdd6a54d1a902c67a6692217c9.png [a7d70f1052db4823aebc28336bab246d.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/d6c9d95283614c7983352d4ff6eb225f.png [7bd4a9c254d24e16a2b00b005379056c.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/b3351652aeed4128a45200cded388192.png [df4c2f552b634eb386866f09c0df689d.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/843b8094e2f74d758d4790db3badbd73.png [39b5241b94a94c78b896588ef4f903f0.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/1bac003530eb4195b53e4ae1889dd823.png [a1e8e25bf78b499c92adafba6d0cf950.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/8fbaedb492224b328bd7b96b06cefa3f.png [242d1b8a4a70498a94d9cba8ab5cbc37.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/2ccfa5eb877e4614866584b0b663c916.png [c9c9a308b50e46539b65b34fb5af50ad.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/fbc23e98485b4f6aa882dff3d1ce6fcc.png [7ed7bc36d34d4280bd4eb19e95883b74.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/e0d11699032f42fead9fab5acb40c8d3.png [d439a1751b994e968aa2d963faed93ac.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/3cca2e562fbd484898e6ff09dd55115a.png [64d6dcea43844fa4bd4986eb87465840.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/036a91cb2f0d4b74b6bd15de2e8d08c4.png [25d8c414325c41c18428f9ed33f0f1d5.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/22cb3632c6834351b1ebe554504ee337.png
还没有评论,来说两句吧...