产品设计排版网站软文平台发布

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

产品设计排版网站,软文平台发布,自在威海智慧旅游平台app,个人网站首页模板文章目录 前言一、初识 MyBatis1.1 什么是 MyBatis1.2 为什么学习 MyBatis 二、MyBatis 在软件开发框架中的定位三、基于 Spring Boot 创建 MyBatis 项目3.1 添加 MyBatis 框架的支持3.2 配置数据库连接信息和映射文件的保存路径#xff08;Mapper XML#xff09; 四、MyBati… 文章目录 前言一、初识 MyBatis1.1 什么是 MyBatis1.2 为什么学习 MyBatis 二、MyBatis 在软件开发框架中的定位三、基于 Spring Boot 创建 MyBatis 项目3.1 添加 MyBatis 框架的支持3.2 配置数据库连接信息和映射文件的保存路径Mapper XML 四、MyBatis 项目结构的创建与使用4.1 数据库和表的准备4.2 根据数据库表创建实体类4.3 创建 Mapper 接口和 XML 映射文件4.4 创建服务层 Service 和 控制层 Controller 五、通过 MyBatis 实现增、删、改操作5.1 增加用户5.2 修改用户5.3 删除用户 六、通过 MyBatis 实现查询操作6.1 单表查询6.1.1 通过用户 ID 查询6.1.2 参数占位符 #{} 和 ${}6.1.3 SQL 注入问题6.1.3 like 查询6.1.4 使用 resultMap 解决实体类参数与数据库表字段不匹配问题 6.2 多表查询6.2.1 VO类的创建6.2.2 创建 Mapper 接口和 XML 映射文件6.2.3 查询文章详情 七、MyBatis 动态 SQL 的使用7.1 if 标签7.2 trim 标签7.3 where 标签7.4 set 标签7.5 foreach 标签 前言 在软件开发领域持久层框架的选择对于项目的实现和维护起着至关重要的作用。MyBatis 作为一款优秀的持久层框架以其灵活性、高度可定制化以及对SQL的直接控制等特性而广受关注和应用。本文将深入探索 MyBatis 框架从初识到实际应用逐步揭示其在现代软件开发中的关键作用。 一、初识 MyBatis 1.1 什么是 MyBatis MyBatis 是一个优秀开源的 Java 持久层框架用于简化数据库访问和操作的过程。它允许开发者使用简单的XML或注解配置来映射 Java 对象与数据库表之间的关系从而实现数据库的持久化操作。MyBatis并不是一个全面的ORM对象关系映射框架而是更强调对 SQL 的精确控制使开发者能够更直接地编写和优化 SQL 语句。 ORM对象关系映射框架 ORM全称为对象关系映射Object-Relational Mapping是一种软件技术用于将面向对象的编程语言如Java、Python等中的对象模型与关系型数据库中的数据模型之间进行映射和转换。简单来说ORM框架允许开发者使用面向对象的思维来操作数据库而不需要直接编写SQL语句。 MyBatis 的核心思想在于 SQL 的分解它将 SQL 语句与 Java 代码分开从而降低了代码的耦合度提供了更大的灵活性和可维护性。通过配置映射文件Mapper XML开发者可以将SQL语句和查询结果的映射关系定义清晰而Java代码则专注于业务逻辑的编写。此外MyBatis还支持动态SQL、参数绑定、缓存等特性使得数据库操作更加高效和便捷。 1.2 为什么学习 MyBatis 对于后端开发来说程序是由以下两个重要的部分组成的即 后端程序 和 数据库。 这两个重要的组成部分要通讯就要依靠数据库连接工具比如之前的 JDBC 以及现在的 MyBatis 框架都是为了连接并操作数据库。 然而使用 JDBC 的操作会非常的繁琐因此就需要使用其他更加简单高效的数据库连接方式了而 MyBatis 就是一个更好的选择。 MyBatis 作为一个持久层框架在现代软件开发中具有许多优势和价值学习 MyBatis 的主要原因有

  1. 灵活的SQL 控制 MyBatis 允许开发者直接编写和控制 SQL 语句这对于需要对数据库操作进行精确控制和优化的场景非常有用。开发人员可以编写自己的SQL语句根据具体需求进行调整而不受自动生成的SQL的限制。

  2. 良好的性能 由于开发者可以优化 SQL 语句使其更适合特定的数据库和查询需求因此 MyBatis 在性能方面表现出色。合理编写和优化的 SQL 语句可以显著提升应用程序的数据库访问效率。

  3. 适应不同数据库 MyBatis 支持多种数据库因此无论使用哪种关系型数据库如MySQL、Oracle、SQL Server等MyBatis 都可以适应并提供一致的操作方式。

  4. 良好的扩展性 MyBatis 允许开发者编写自定义的 TypeHandlers、Plugins 等来满足特定需求从而增强了框架的扩展性和定制性。

  5. 轻量级框架 相对于一些重量级的 ORM 框架MyBatis 是一个相对轻量级的框架学习成本较低上手相对容易。

  6. 可与其他框架集成 MyBatis 可以很容易地与其他流行的框架如Spring、Spring Boot进行集成使得整体开发流程更加顺畅。

  7. 更好地理解数据库 通过学习 MyBatis将不仅仅是在学习一个框架还会更深入地理解数据库的工作方式和性能优化方法这对于数据库设计和应用优化都有很大帮助。 二、MyBatis 在软件开发框架中的定位 理解 MyBatis 在整个软件开发框架中的定位是非常重要的特别是对于了解其在系统架构中的作用和角色有帮助。下面是一个简单的交互流程图展示了 MyBatis 在整个应用架构中的位置和交互关系
    在上述流程中MyBatis主要位于持久层Persistence它的作用是将业务逻辑和数据库之间的交互进行封装和管理。下面是各层之间的交互关系 前端界面这是应用程序的用户界面用户通过界面与系统进行交互发送请求。 控制层 (Controller)控制层接收来自用户界面的请求处理请求的分发和调度调用适当的服务层进行业务处理。 服务层 (Service)服务层包含了应用程序的业务逻辑。它接收控制层传递的请求处理业务逻辑并可能需要与持久层进行数据交互。 持久层 (Persistence - MyBatis)MyBatis 位于持久层它负责将业务逻辑中的数据访问需求转化为对数据库的操作。通过映射文件Mapper XML和对应接口Mapper Interface进行关系映射MyBatis 将 Java 对象和数据库表之间的数据转换进行管理。 数据库 (DB)数据库是存储实际数据的地方。MyBatis通过SQL语句执行实际的数据库操作将数据存储、检索、更新等操作反映到数据库中。
    在这个流程中MyBatis 在持久层起到了桥梁的作用负责将业务逻辑与数据库操作连接起来。它允许开发者通过映射文件或注解定义数据库表与 Java 对象之间的关系从而实现数据的存取。这种定位使得开发者能够充分利用数据库的性能和功能同时保持代码的可维护性和可扩展性。 三、基于 Spring Boot 创建 MyBatis 项目 3.1 添加 MyBatis 框架的支持 创建 Spring Boot 项目 添加 MyBatis 依赖 在创建 Spring Boot 项目的时候如果想要创建 MyBatis 项目需要在依赖中勾选MyBatis Framework除此之外还需要勾选一个具体的数据库驱动比如MySQL Driver。 3.2 配置数据库连接信息和映射文件的保存路径Mapper XML 在创建好 Spring Boot 项目后还需要在 application.yml 配置文件中为 MyBatis 配置数据库连接信息和映射文件的保存路径Mapper XML。 配置的内容如下

    配置数据库的连接字符串

    spring:datasource:url: jdbc:mysql://127.0.0.1:3306/database?characterEncodingutf8username: rootpassword: passworddriver-class-name: com.mysql.cj.jdbc.Driver这部分配置用于设置数据库连接信息。需要根据实际情况修改url、username 和 password 字段以连接到自己的 MySQL 数据库。其中driver-class-name 字段指定了MySQL数据库驱动程序的类名。

    设置 Mybatis 的 xml 保存路径在 resources/mapper 创建所有表的 xml ⽂件

    mybatis:mapper-locations: classpath:mapper/*Mapper.xml这部分配置设置了 Mapper XML 文件的保存路径。mapper-locations 字段指定了 MyBatis 应该在classpath:mapper/ 路径下查找 Mapper XML文件。首先需要在这个路径下创建与MyMapper接口对应的Mapper XML文件才能够使用 MyBatis。 四、MyBatis 项目结构的创建与使用 4.1 数据库和表的准备 此处创建一个userinfo表和 articleinfo表 – 创建数据库 drop database if exists mycnblog; create database mycnblog DEFAULT CHARACTER SET utf8mb4;– 使用数据数据 use mycnblog;– 创建表[用户表] drop table if exists userinfo; create table userinfo(id int primary key auto_increment,username varchar(100) not null,password varchar(32) not null,photo varchar(500) default ,createtime timestamp default current_timestamp,updatetime timestamp default current_timestamp,state int default 1 ) default charset utf8mb4;– 创建文章表 drop table if exists articleinfo; create table articleinfo(id int primary key auto_increment,title varchar(100) not null,content text not null,createtime timestamp default current_timestamp,updatetime timestamp default current_timestamp,uid int not null,rcount int not null default 1,state int default 1 )default charset utf8mb4;– 添加一个用户信息 INSERT INTO mycnblog.userinfo (id, username, password, photo, createtime, updatetime, state) VALUES (1, admin, admin, , 2023-8-09 10:10:48, 2023-8-09 10:10:48, 1);– 文章添加测试数据 insert into articleinfo(title,content,uid) values(Java,Java正文,1); insert into articleinfo(title,content,uid) values(C,C正文, 1); insert into articleinfo(title,content,uid) values(Python,Python, 1); insert into articleinfo(title,content,uid) values(PHP,PHP正文, 1); 4.2 根据数据库表创建实体类 例如针对表 userinfo 创建一个实体类 Data public class UserInfo {private Integer id;private String username;private String password;private String photo;private LocalDateTime createtime;private LocalDateTime updatetime;private Integer state; } 实体类中的属性名称为了更好的兼容性一般与数据库表中的字段相匹配。此处使用了 Lombok 库中的Data 注解来自动生成实体类getter、setter、equals、hashCode 和 toString等方法这样可以减少样板代码的编写。 4.3 创建 Mapper 接口和 XML 映射文件 上述实体类已经包含了与数据库表字段对应的属性以及对应的数据类型。只需要确保在使用MyBatis时Mapper 接口和 Mapper XML 文件与该实体类正确匹配。可以创建一个对应的Mapper接口和XML文件然后使用Mapper注解标记接口。 在 mapper 目录下创建 UserMapper 接口 其中Mapper 注解是 MyBatis 中的一个注解用于标记一个接口为 MyBatis 的 Mapper 接口从而告诉 MyBatis 这个接口定义了数据库操作的方法。在这个接口中只需编写与数据库操作的相关代码即可比如获取所有的 User 信息 import com.example.demo.entity.UserInfo;import java.util.List;Mapper public interface UserInfoMapper {ListUserInfo getAll(); } 创建 XML 映射文件 首先在resources目录下创建一个mapper子目录用于存放Mapper XML 文件 在这个 mapper 路径下创建与UserInfoMapper.java接口对应的 XML 文件 UserInfoMapper.xml 然后需要在这个文件中填充以下内容 ?xml version1.0 encodingUTF-8? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.example.demo.mapper.UserInfoMapper/mapper其中 namespace 字段指定的就是与 UserInfoMapper.xml 对应的 UserInfoMapper 接口的路径此时便建立了 XML 文件与接口之间的映射关系。 当在 IDEA 中安装了 MyBatisX 插件就可以发现出现了一对小鸟此时点击 UserInfoMapper.xml边上的蓝色小鸟就可以调整到与之映射的 UserInfoMapper 接口中。 反之点击UserInfoMapper 接口中的红色小鸟也会跳转到与之对应的UserInfoMapper.xml文件中。
    此时发现接口中的方法会报错那是因为在 Mapper XML文件中没有与之对应的 SQL 语句。 实现 getAll 方法对应的 SQL 语句 在UserInfoMapper.xml编写查询所有用户的SQL语句 其中id字段指定的是与这个 SQL 语句对应的 Mapper接口中方法即getAll而resultType 字段则是返回数据的类型此处返回的是UserInfo对象MyBatis 框架会根据这个映射配置在查询执行完成后将查询结果自动映射到 UserInfo 对象中。但是前提条件是要确保实体类中的属性名称与数据库表的字段名称相匹配这样 MyBatis 才能正确地进行结果映射。 4.4 创建服务层 Service 和 控制层 Controller 创建服务层 service目录然后在该目录下创建 UserInfoService 类 Service public class UserInfoService {Autowiredprivate UserInfoMapper userInfoMapper;public ListUserInfo getAll(){return userInfoMapper.getAll();} }创建控制层 controller 目录然后在该目录下创建 UserInfoController 类 RequestMapping(/user) RestController public class UserInfoController {Autowiredprivate UserInfoService userInfoService;GetMapping(/getAll)public ListUserInfo getAll(){return userInfoService.getAll();} } 此时已经完成了服务层和控制层的创建其中控制层负责处理 HTTP 请求以及与用户、服务层之间的交互而服务层用于处理与用户信息相关的业务逻辑并向控制层返回处理的结果。这种结构符合典型的三层架构Controller - Service - Repository/DAO设计模式让代码更加清晰和易于维护。 在上述的代码中UserInfoService 负责调用 UserInfoMapper 执行数据库操作而 UserInfoController 则负责处理 HTTP 请求将业务逻辑和数据库操作分离。 在这个基本的结构允许通过访问/user/getAll来获取所有用户信息例如此时运行服务器然后在浏览器中输入http://localhost:8080/user/getAll进行访问可以看到获取到了数据库中的所有用户信息 五、通过 MyBatis 实现增、删、改操作 5.1 增加用户

  8. 在UserInfoMapper 接口中添加一个 addUser 方法 // 增加用户 int addUser(UserInfo user);2. 在UserInfoMapper.xml中编写对应的 SQL 语句 insert idaddUserinsert into userinfo(username, password) values (#{username}, #{password}) /insert3. 此时可以对 addUser 进行单元测试 1首先在UserInfoMapper接口中点击右键然后选择Generate 2选择其中的Test 3创建单元测试类 此处选择添加测试addUser方法。添加完成后可以在 test 目录下找到对应的测试类 4编写测试代码 简单说明 在测试代码中使用了SpringBootTest注解表示这是一个 Spring Boot 测试。Autowired注解用于自动注入UserInfoMapper允许在测试中使用它。Transactional注解用于表示测试过程中的事务操作它会在测试结束时回滚以避免对数据库造成实际的影响。 运行该测试代码发现通过测试则说明刚才的代码是正确的
    5.2 修改用户 例如此时需要通过用户 id 来修改用户名

  9. 在UserInfoMapper 接口中添加一个 updateUserById 方法 // 根据id修改用户名 int updateUserById(Integer id, String username);2. 在UserInfoMapper.xml中编写对应的 SQL 语句 update idupdateUserByIdupdate userinfo set username#{username} where id#{id} /update3. 进行单元测试 1添加测试方法 Test void updateUserById() { }2编写测试代码 此时 userinfo 表中的内容有 要求把 id 为 1 的用户名修改为 admin Test void updateUserById() {Integer id 1;String username admin;int res userInfoMapper.updateUserById(id, username);System.out.println(影响行数 res); }3运行该测试方法 执行成功 再次查看 userinfo 表发现已经成功进行了修改
    5.3 删除用户 现在要求通过用户id删除指定用户

  10. 在UserInfoMapper 接口中添加一个 deleteUserById 方法 // 根据 id 删除用户 int deleteUserById(Integer id);2. 在UserInfoMapper.xml中编写对应的 SQL 语句 delete iddeleteUserByIddelete from userinfo where id#{id} /delete3. 进行单元测试 1添加测试方法 Test void deleteUserById() { }2编写测试方法 此时要删除 id 为 12 的用户 Testvoid deleteUserById() {Integer id 12;int res userInfoMapper.deleteUserById(id);System.out.println(影响行数 res);}3运行测试代码 测试通过
    发现此时userinfo表中 id 为 12 的用户被删除了 六、通过 MyBatis 实现查询操作 6.1 单表查询 6.1.1 通过用户 ID 查询

  11. 在UserInfoMapper接口中添加getUserById方法 // 根据id查询用户 UserInfo getUserById(Integer id);2. 在UserInfoMapper.xml中编写对应的 SQL 使用 #{} 参数占位符 select idgetUserById resultTypecom.example.demo.entity.UserInfoselect * from userinfo where id#{id} /select使用 \({} 参数占位符 select idgetUserById resultTypecom.example.demo.entity.UserInfoselect * from userinfo where id\){id} /select3进行单元测试 查询id 为 1 的用户 Test void getUserById() {UserInfo user userInfoMapper.getUserById(1);System.out.println(user); }使用 #{} 参数占位符的运行结果 使用 \({} 参数占位符的运行结果 通过上述的测试代码不难发现 在使用 #{} 参数占位符的时候准备执行的SQL语句中的参数位置为?即经过了 SQL 的预编译后面还需要对这个?进行赋值操作而使用 \){} 参数占位符的时候参数是直接替换的。 6.1.2 参数占位符 #{} 和 \({} 在 MyBatis 中#{} 和 \){} 是两种常用的参数占位符用于在 SQL 语句中引用参数值。虽然它们看起来类似但在使用时有一些重要的区别。

  12. #{} 占位符 #{} 占位符在 SQL 语句中使用时会 自动进行预编译防止 SQL 注入攻击 并且能够处理参数的类型转换。它适用于大多数的 SQL 参数如字符串、数字等。

  13. \({} 占位符 \){} 占位符在 SQL 语句中使用时会 将参数值直接嵌入到 SQL 语句中不进行预编译 。这可能会导致 SQL 注入风险因此需要谨慎使用。它适用于一些特殊的场景如动态表名或列名等。 因此在大多数情况下推荐尽可能使用 #{} 占位符以确保 SQL 的安全性和可维护性。只在必要的情况下使用 \({} 占位符同时保证输入参数的合法性和安全性。 6.1.3 SQL 注入问题 下面通过使用\){}模拟登录时发生的 SQL 注入问题 1. 在UserInfoMapper接口中添加getUserById方法 // 实现登录操作 UserInfo login(UserInfo user);2. 在UserInfoMapper.xml中编写对应的 SQL select idlogin resultTypecom.example.demo.entity.UserInfoselect * from userinfo where username\({username} and password\){password} /select由于使用\({}是直接进行参数替换的因此需要在\){}外面加上。

  14. 编写单元测试 首先进行正常的演示 Test void login(){String username zhangsan;String password 123456;UserInfo user new UserInfo();user.setUsername(username);user.setPassword(password);UserInfo loginUser userInfoMapper.login(user);System.out.println(loginUser); }此时可以成功获取到对象
    但是如果将 password 改成 String password or 11;再次运行测试代码 发现此时获取到了数据库中的全部内容其执行的 SQL 语句是 select * from userinfo where usernamezhangsan and password or 11即不管输入的username 和 password 是否正确where 条件始终为 true这就是 SQL 注入带来的风险。 如果此时将 \({} 改为 #{} select idlogin resultTypecom.example.demo.entity.UserInfoselect * from userinfo where username#{username} and password#{password} /select再次运行刚才的代码 此时通过预编译然后再获取参数避免了 SQL 注入带来的风险。 6.1.3 like 查询 使用 like 通过用户名模糊查询 1. 在UserInfoMapper接口中添加getListByName方法 // like 模糊查询 ListUserInfo getListByName(Param(username) String username);2. 在UserInfoMapper.xml中编写对应的 SQL 使用#{}参数占位符 select idgetListByName resultTypecom.example.demo.entity.UserInfoselect * from userinfo where username like %#{username}% /select此时通过单元测试发现最后会报错 这是因为当使用#{}时最终形成的 SQL 语句是 select * from userinfo where username like %ang%而这是一条错误的 SQL 语句所有会报错因此使用 like 查询的时候需要使用\){}参数占位符进行直接替换。 select idgetListByName resultTypecom.example.demo.entity.UserInfoselect * from userinfo where username like %\({username}% /select再次运行测试代码发现可以成功查找了 但是这样还是存在 SQL 注入问题所以还是需要使用 #{}对于这种情况可以使用 MySQL 的内置函数 concat 来解决 select idgetListByName resultMapBaseMapselect *from userinfowhere username like concat(%, #{username}, %); /select其中concat的作用就是拼接字符串并且支持可变参数。 6.1.4 使用 resultMap 解决实体类参数与数据库表字段不匹配问题 有时候我们程序中实体类中的参数名可能会和数据库表中的字段名不匹配那么 MyBatis 就无法正确绑定查询结果到实体类对象了此时可以使用 Mapper XML 中的 resultMap 来解决。 例如userinfo表中的密码字段为 password而实体类中的属性名为 pwd此时再通过getUserById来查询用户最后发现pwd属性为空 此时在UserInfoMapper.xml文件中新加入一个 resultMap 标签 简单说明 id 元素定义了主键的映射。column 属性指定数据库表的列名property 属性指定实体类的属性名。在这个示例中数据库表的主键列 “id” 映射到实体类的属性 “id”。 result 元素定义了普通列的映射。column 属性指定数据库表的列名property 属性指定实体类的属性名。在这个示例中数据库表的 “username” 列映射到实体类的属性 “username”“password” 列映射到实体类的属性 “pwd”“photo” 列映射到实体类的属性 “photo”。 然后修改 getUserById 方法对应的 SQL修改其返回结果为字典映射 baseMap select idgetUserById resultMapbaseMapselect * from userinfo where id\){id} /select再次运行测试代码就可以拿到正确的结果了 当然也可以在 SQL 语句中将 password 重命名为 pwd 来解决这个问题例如 select idgetUserById resultTypecom.example.demo.entity.UserInfoselect id, username, password as pwd, photo, createtime, updatetime, state from userinfo where id${id} /select此时同样可以拿到正确的结果
    6.2 多表查询 6.2.1 VO类的创建 在进行代表查询的时候通常都需要创建一个值对象VOValue Object来包含多个表的相关信息。VO类是一个 Java 类通常用于封装多个实体类的属性从而方便在多个表查询中传递和处理数据。 例如此时需要通过文章 id 来查询文章详情而文章详情中需要包含用户名但articleInfo 表中只有用户 uid所有就需要进行多表查询。为了方便将用户名和文章信息相结合因此就需要额外创建一个ArticleInfoVO类。 首先创建 articleinfo 表对应的实体类 ArticleInfo
    然后继承该类在vo目录下创建一个 ArticleInfoVO 类
    6.2.2 创建 Mapper 接口和 XML 映射文件

  15. 创建 Mapper 接口 ArticleInfoVOMapper 2. 创建 XML 映射文件 ArticleInfoVOMapper.xml
    6.2.3 查询文章详情

  16. 在 ArticleInfoVOMapper接口中创建方法getDetial // 通过文章 id 查询文章详情 ArticleInfoVO getDetial(Integer id);2. 在 ArticleInfoVOMapper.xml文件中编写对应的 SQL 语句 select idgetDetial resultTypecom.example.demo.entity.vo.ArticleInfoVOselect a., u.username from articleinfo a left join userinfo u on a.uid u.id where a.id #{id} /select3. 编写单元测试 SpringBootTest class ArticleInfoVOMapperTest {Autowiredprivate ArticleInfoVOMapper articleInfoVOMapper;Testvoid getDetail() {ArticleInfoVO detail articleInfoVOMapper.getDetail(1);System.out.println(detail);} }运行测试代码发现能正确查找出结果
    七、MyBatis 动态 SQL 的使用 MyBatis 动态 SQL 是指根据不同的条件和参数动态地生成 SQL 查询或更新语句的过程。它允许在编写 SQL 映射文件时根据业务需求来动态组装 SQL 语句的各个部分从而实现更灵活的数据库操作。动态 SQL 在处理不同的查询条件、排序、过滤等方面非常有用它可以避免因为多种情况而编写大量重复的 SQL 语句从而提高开发效率。 MyBatis 提供了一系列的 XML 标签和语法用于构建动态 SQL。这些标签可以用来包含条件判断、循环遍历、动态拼接 SQL 片段等操作。一些常用的动态 SQL 标签包括 if、choose、when、otherwise、trim、where、set、foreach 等详情可以参考MyBatis 官网 动态SQL。 总之MyBatis 动态 SQL 是一种强大的机制使得在 SQL 映射文件中根据不同情况生成合适的 SQL 语句变得更加灵活和方便。下面是对一些常见的动态 SQL 标签的详细介绍。 7.1 if 标签 if 标签用于在 SQL 语句中添加条件判断根据条件的真假来动态生成 SQL 片段。 例如在添加用户信息的时候photo 字段的内容可能不确定用户是否输入这时就需要使用 if 标签来构建动态 SQL insert idaddUserinsert into userinfo(username,if testphoto!null and photo!photo,/ifpassword)values (#{username},if testphoto! null and photo!#{photo},/if#{pwd}) /insert需要注意的是其中 if标签中的 test 属性指定的是传入的对象的属性而不是数据库表中的字段。 在单元测试中只输入 username 和 password最后形成的 SQL 也只有这两个字段 如果在增加输入一个photo 属性 可以发现此时三个字段都有。 7.2 trim 标签 如果当输入的所有属性都是可选的情况下那么只使用 if 标签就不能解决其中的 , 问题了因为不知道,在哪个位置出现可以出现在前面也可能在后面如果没有输入的话可能都不出现。因此要解决这个问题就需要引入trim标签。 trim标签属性 prefix表示整个语句块以prefix的值作为前缀suffix表示整个语句块以suffix的值作为后缀prefixOverrides表示整个语句块要去除掉的前缀suffixOverrides表示整个语句块要去除掉的后缀 例如此时设置添加用户时的 username、password、photo 三个字段都是可选的 insert idaddUserinsert into userinfotrim prefix( suffix) suffixOverrides,if testusername!null and username!username,/ifif testphoto!null and photo!photo,/ifif testpwd!null and pwd!password,/if/trimvaluestrim prefix( suffix) suffixOverrides,if testusername!null and username!#{username},/ifif testphoto!null and photo!#{photo},/ifif testpwd!null and pwd!#{pwd},/if/trim /insert其中trim 标签的作用就是用于修剪插入的列名和值部分可以在开始和结束位置删除多余的逗号。prefix 属性表示在 SQL 片段前添加的内容suffix 属性表示在 SQL 片段后添加的内容suffixOverrides 属性表示在 SQL 片段结尾删除的内容。 7.3 where 标签 where 标签用于将条件添加到 SQL 语句的 WHERE 子句中并处理条件之间的逻辑。 例如现在可以通过文章的 id 或者 title 来进行查询其中 id 和 title 的内容都是可选输入项并且title使用的是模糊匹配。 select idgetListByIdOrTitle resultTypecom.example.demo.entity.vo.ArticleInfoVOselect a.
    , u.username from articleinfo aleft join userinfo u on a.uid u.idwhereif testid ! null and id 0and a.id #{id}/ifif testtitle!null and title!nulland a.title like concat(%, #{title}, %)/if/where /select另外where标签会自动去除前缀的and。 当然也可以使用 trim 和 if 标签来实现这个功能 select idgetListByIdOrTitle resultTypecom.example.demo.entity.vo.ArticleInfoVOselect a.*, u.username from articleinfo aleft join userinfo u on a.uid u.idtrim prefixwhere prefixOverridesandif testid ! null and id 0and a.id #{id}/ifif testtitle!null and title!nulland a.title like concat(%, #{title}, %)/if/trim /select此时需要使用trim标签用来去除一个前缀and以及添加一个前缀where。 7.4 set 标签 set 标签用于在更新语句中设置需要更新的字段并根据条件动态生成更新语句。 例如通过用户 id 来修改该用户不为 null 的属性 update idupdateByIdupdate userinfosetif testusername!null and username!username#{username},/ifif testpwd!null and pwd!password#{pwd},/ifif testphoto!null and photo!photo#{photo},/if/setwhere id#{id} /updateset标签和where 相反它只会去除后缀的, 。 7.5 foreach 标签 foreach 标签用于遍历集合或数组并将其中的元素添加到 SQL 语句中。 foreach标签有如下属性 collection绑定⽅法参数中的集合如 ListSetMap或数组对象item遍历时的每⼀个对象open语句块开头的字符串close语句块结束的字符串separator每次遍历之间间隔的字符串 例如现在需要根据多个文章 id来删除对应的文章

  17. 在ArticleInfoVOMapper接口中添加方法 // 根据多个文章 id来删除对应的文章 int deleteByIds(ListInteger ids);2. 在ArticleInfoVOMapper.xml编写对应SQL delete iddeleteByIdsdelete from articleinfo where id inforeach collectionids itemitem open( close) separator,#{item}/foreach /delete这段代码演示了使用 MyBatis 的动态 SQL 构建删除语句的示例。这个删除语句会根据给定的 ID 列表动态地生成 DELETE 语句中的 IN 子句从而批量删除满足条件的记录。 简单说明 delete 标签这个标签表示一个删除语句的定义。 foreach 标签这个标签用于遍历集合将集合中的元素添加到 SQL 语句中。在这个示例中它会将 ids 集合中的每个元素添加到 IN 子句中形成类似 (id1, id2, id3) 的结构。 collection 属性指定要遍历的集合。item 属性指定在遍历过程中每个元素的别名。open 属性指定遍历开始时的字符这里是 (。close 属性指定遍历结束时的字符这里是 )。separator 属性指定元素之间的分隔符这里是逗号 ,。
    通过这种方式可以使用动态 SQL 构建批量删除语句根据给定的 ID 集合删除相应的记录。

  18. 进行单元测试 Transactional Test void deleteByIds() {ListInteger ids new ArrayList();ids.add(1);ids.add(2);ids.add(3);ids.add(4);int res articleInfoVOMapper.deleteByIds(ids);System.out.println(影响行数 res); }测试通过