Spring Boot 框架核心技术之 05-Spring Boot 整合 MyBatis Plus 和 Thymeleaf
AI 摘要
Spring Boot 整合 MyBatis Plus
MyBatis Plus 简介
MyBatis Plus 是一个 MyBatis 的增强工具,为简化开发、提高效率而生。
MyBatis Plus 文档:https://www.baomidou.com/
MyBatis Plus 的特性:
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响。
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求。
Mybatis Plus 初体验
MyBatis Plus 内置通用 Mapper、通用 Service,无需编写 SQL 语句就能实现简单的 CRUD。
示例:Mybatis Plus 初体验
SQL 脚本:
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`
(
id BIGINT NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);Maven 项目配置文件(pom.xml):
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.2</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>Spring Boot 项目配置文件(classpath:/application.properties):
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo_project?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456..User 实体类(package.entity.User):
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
private Integer id;
private String name;
private Integer age;
private String email;
}UserMapper 数据访问接口(package.dao.UserMapper):
@Mapper // Spring Boot中,数据访问接口需要加@mapper注解
public interface UserMapper extends BaseMapper<User> {
// 在Mapper接口类上继承MyBatis Plus提供的BaseMapper
// 继承的BaseMapper接口是泛型类,泛型对应实体类
// 此时MyBatis Plus自动实现对这一实体的基本CRUD操作
}UserService 业务逻辑接口(package.service.UserService):
public interface UserService extends IService<User> {
// 在Service接口类上继承MyBatis Plus提供的IService
// 继承的IService接口是泛型类,泛型对应实体类
}UserServiceImpl 业务逻辑接口实现类(package.service.UserServiceImpl):
@Service // 业务逻辑接口实现类加上@Service注解
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
// 在Service实现类上继承MyBatis Plus提供的ServiceImpl
// 继承的ServiceImpl接口是泛型类,第一个参数表示对应的Mapper接口,第二个参数表示对应的实体类
// 业务逻辑接口实现类实现业务逻辑接口
}测试类(test.Tester):
// 注入Service层实现类
@Resource
UserService userService;
@Test
void contextLoads() {
// 调用Service层查询用户列表
List<User> userList = userService.list();
// 遍历用户列表
for (User user : userList) {
System.out.println(user);
}
}示例效果:
借助 MyBatisCodeHelperPro 插件,可以快速生成 MyBatis Plus 代码。
示例:MyBatisCodeHelperPro
MyBatisCodeHelperPro 插件:
MyBatis Plus CRUD
数据访问层、业务逻辑层的内置了基础的增删改查方法,可以根据需求直接调用。
示例:MyBatis Plus CRUD
测试类(test.Tester):
@Test
void deleteUser() {
userService.removeById(1);
}如果需要手写 SQL 语句(如多表联查、复杂查询等),其实现方式和 MyBatis 一致。
MyBatis Plus 注解
MyBatis Plus 提供许多常用的注解。
- 实体类通常不需要显式添加 @TableName、@TableField 注解。
- MyBatis-Plus 提供了一种自动映射的机制,它会根据实体类的命名规则来推导对应的数据库表名和字段名。
示例:MyBatis Plus 注解
User 实体类(package.cn.duozai.demo.entity.User):
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@TableName("sys_user")
public class User {
@TableId
private Long id;
@TableField("nickname")
private String name;
private Integer age;
private String email;
}MyBatis Plus 配置
MyBatis Plus 的部分配置继承自 MyBatis 原生所支持的配置。
示例:MyBatis Plus 配置
Spring Boot 项目配置文件(classpath:/application.properties):
mybatis-plus.mapper-locations=classpath:/mappers/*.xmlMyBatis Plus 日志
MyBatis Plus 配置日志输出可以帮助我们更好地了解应用程序在运行时的行为,包括数据库操作语句、查询结果、异常信息等。
通过查看日志输出,我们可以快速定位问题并进行调试,提高开发效率和程序稳定性。
MyBatis Plus 支持的日志系统:Log4j、LogBack、slf4j、stdout 等。
示例:MyBatis Plus 日志
Spring Boot 项目配置文件(classpath:/application.properties):
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl示例效果:
MyBatis Plus 逻辑删除
逻辑删除是为了方便数据恢复和保护数据本身价值等等的一种方案。
- 逻辑删除要求数据里面有一个字段 deleted 表示是否删除,其取值 0 表示未删除,1 表示已删除。
- 删除数据时不再执行 DELETE,而是执行 UPDATE 将 deleted 字段的值修改为 1。
- 查询数据时将 deleted 字段的值为 1 的数据排除在外,即拼接查询条件 deleted = 0。
示例:MyBatis Plus 逻辑删除
数据库表(user):
User 实体类(package.entity.User):
@TableLogic // 标记该属性表示逻辑删除
private Integer deleted;Spring Boot 项目配置文件(classpath:/application.properties):
# 表示逻辑删除的字段
mybatis-plus.global-config.db-config.logic-delete-field=deleted
# 已删除时,逻辑删除字段的值,默认为1
mybatis-plus.global-config.db-config.logic-delete-value=1
# 未删除时,逻辑删除字段的值,默认为0
mybatis-plus.global-config.db-config.logic-not-delete-value=0测试类(test.Tester):
@Test
void deleteUser() {
// 仍然调用删除方法,MyBatis Plus自动识别逻辑删除
userService.removeById(1);
}示例效果:
MyBatis Plus 条件构造器
条件构造器(Wrapper)用于构造查询条件以实现复杂 SQL 语句。
示例:MyBatis Plus 条件构造器
测试类(test.Tester):
@Test
void contextLoads() {
// 使用条件构造器构造查询条件
QueryWrapper queryWrapper = new QueryWrapper();
// 查询名字是Tom的用户列表
queryWrapper.eq("name", "Tom");
// 调用Service层查询用户列表
List<User> userList = userService.list(queryWrapper);
// 遍历用户列表
for (User user : userList) {
System.out.println(user);
}
}示例效果:
MyBatis Plus 的条件构造器还支持使用 lambda 表达式,可以通过方法引用的方式来使用实体字段名的操作,避免直接写数据库表字段名时的错写名字。
示例:lambda 条件构造器
测试类(test.Tester):
@Test
void contextLoads() {
// 使用条件构造器构造查询条件
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>();
// 查询名字是Tom的用户列表
queryWrapper.eq(User::getName, "Tom");
// 调用Service层查询用户列表
List<User> userList = userService.list(queryWrapper);
// 遍历用户列表
userList.forEach(System.out::println);
}MyBatis Plus 分页
MyBatis Plus 内置分页插件,只需要简单的配置就可以实现分页功能。
示例:MyBatis Plus 分页
MyBatis Plus 配置类(package.config.MyBatisPlusConfiguration):
@Configuration
public class MyBatisPlusConfiguration {
/**
* MybatisPlusInterceptor是MyBatis Plus的一个拦截器,用于配置插件
*
* @return com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor
* @author 多仔ヾ
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}测试类(test.Tester):
@Test
void contextLoads() {
// 实例化分页对象,设置分页参数:页码,页大小
Page<User> page = new Page<User>(1, 2);
// 调用Service层查询用户列表(分页)
userService.page(page);
// 遍历用户列表
for (User record : page.getRecords()) {
System.out.println(record);
}
System.out.println("页码:" + page.getCurrent());
System.out.println("页大小:" + page.getSize());
System.out.println("数据总数:" + page.getTotal());
System.out.println("页码总数:" + page.getPages());
System.out.println("是否有上一页:" + page.hasPrevious());
System.out.println("是否有下一页:" + page.hasNext());
}示例效果:
Spring Boot 整合 Thymeleaf
Thymeleaf 简介
Thymeleaf 是一个流行的模板引擎。
- Thymeleaf 基于 HTML,以 HTML 标签为载体,Thymeleaf 要寄托在 HTML 标签下实现。
- Spring Boot 官方推荐使用 Thymeleaf 来替代 JSP 技术。
Thymeleaf 的特点:
- 动静结合:既可以直接使用浏览器打开,查看页面的静态效果,也可以通过 Web 应用程序进行访问,查看动态页面效果。
- 开箱即用:提供了 Spring 标准方言以及一个与 Spring MVC 完美集成的可选模块,可以快速地实现表单绑定、属性编辑器、国际化等功能。
- 多方言支持:提供了 Thymeleaf 标准和 Spring 标准两种方言,可以直接套用模板实现 JSTL、 OGNL 表达式,开发人员也可以扩展和创建自定义的方言。
- 与 Spring Boot 完美整合:Spring Boot 为 Thymeleaf 提供了的默认配置,并且还为 Thymeleaf 设置了视图解析器。
Thymeleaf 初体验
Thymeleaf 通过在 HTML 标签中,增加额外属性来达到模板 + 数据的展示方式。
示例:Thymeleaf 初体验
Maven 项目配置文件(pom.xml):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>Hello 控制器(package.HelloController):
@Controller
public class HelloController {
@Resource
UserService userService;
@GetMapping("/hello")
public String hello(Model model) {
// 存放一句话
model.addAttribute("message", "Hello, Thymeleaf");
// 存放用户列表
List<User> userList = userService.list();
model.addAttribute("userList", userList);
// 返回classpath:/templates/下的视图名称
return "hello";
}
}Hello 页面视图(classpath:/templates/hello.html):
<!DOCTYPE html>
<!--
xmlns:th:声明名称空间,可以省略
-->
<html lang="cn" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--
使用th:text设置标签的文本内容,使用$符号取值
也可以使用内联表达式取值
-->
<h1 th:text="${message}"></h1>
<h1>[[${message}]]</h1>
<!--
使用th:each遍历列表
item:列表中的每一个元素的别名
state:列表状态
state.index:数据下标,从0开始
state.count:数据序号,从1开始
-->
<div th:each="item,state : ${userList}">
<span th:text="${item.name}"></span>
</div>
</body>
</html>示例效果:
Thymeleaf 变量表达式
使用 ${xxx} 包裹的表达式被称为变量表达式。
变量表达式可以获取对象的属性和方法。
变量表达式获取对象的属性和方法的基本用法:
${user.userName}变量表达式可以使用内置的基本对象。
- #request:获取 HttpServletRequest 对象。
- #response:获取 HttpServletResponse 对象。
- #session:获取 HttpSession 对象。
变量表达式使用内置的基本对象的基本用法:
${#session.getAttribute('loginUser')}
${session.loginUser}变量表达式可以使用内置的工具对象。
- strings:字符串工具对象,常用方法有 equals、length、trim 等。
- lists/sets:List/Set 集合工具对象,常用的方法有 size、isEmpty、contains 等。
- arrays:数组工具对象,常用的方法 toArray、length、isEmpty、contains 等。
变量表达式使用内置的工具对象的基本用法:
${#strings.equals('多仔',name)}Thymeleaf th 属性
Thymeleaf 提供了大量的 th 属性,这些属性可以直接在 HTML 标签中使用。
Thymeleaf 的基本 th 属性:
| 名称 | 描述 |
|---|---|
| th:id | 替换 HTML 标签 的 id 属性 |
| th:text | 文本替换,会转义特殊字符,等同于 [[${xxx}]] |
| th:utext | 文本替换,不会转义特殊字符,等同于 [(${xxx})] |
| th:value | 替换 HTML 标签的 value 属性 |
| th:style | 替换 HTML 标签的 style 属性 |
| th:each | 遍历数组、列表、Map |
| th:if | 条件判断 |
| th:unless | 和 th:if 判断相反,满足条件时不显示 |
| th:switch th:case | 与 Java 的 switch case 语句类似,根据不同的条件展示不同的内容 |
| th:replace | 加载文件,并替换该节点 |
| th:include | 加载文件,将文件内容放到这个节点里面 |
| th:selected | 替换 HTML 标签的 selected 属性 |