前言
MyBatis-Plus 是在 MyBatis 框架基础上的增强工具库,旨在简化 MyBatis 的开发。它提供了一系列增强功能,简化了数据访问层(DAO 层)的开发,并且降低了 Java 开发者在与数据库交互时的工作量。
事前准备
1 首先我们需要准备设计好数据库表
Drop database if EXISTS aaa;
CREATE SCHEMA `aaa` DEFAULT CHARACTER SET utf8mb4;
use `aaa`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) PRIMARY KEY NOT NULL,
`name` varchar(20),
`password` varchar(50) ,
`age` int(10) ,
`tel` varchar(255)
);
INSERT INTO `user` VALUES (1, 'tom', 'tom', 3 , '188666888');
INSERT INTO `user` VALUES (2, 'jerry', 'jerry', 4 , '166888666');
INSERT INTO `user` VALUES (3, 'jock', '123456', 41 , '400618400');
INSERT INTO `user` VALUES (4, '传智播客', 'itcast', 23 , '400617500');
2 创建项目
这里不需要加入MyBatis依赖,在加入MyBatis-Plus后会自动加入MyBatis,只需加入以下依赖即可
1 加入依赖
增加
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.15</version>
</dependency>
修改(由于版本问题,会有兼容问题,我的spring boot 3.2.1版本,后续会无法注入mapper方法。因此我将其修改为 2.7.6版本,大家可以根据自己版本自行选择)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.6</version> <!-- 这里修改的 -->
<relativePath/>
</parent>
2 介绍application.yaml
1 改名(将application.properties --> application.yaml)
2 加入内容(记得将密码修改为自己的)
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql:///aaa?characterEncoding=utf-8
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
mvc:
static-path-pattern: /static/**
thymeleaf:
# 这个属性设置了 Thymeleaf 模板的缓存。
# 将其设置为 false 后,模板在修改后会立即生效,方便开发阶段查看变化。
# 在生产环境中,可以考虑开启缓存以提升性能。
cache: false
# 这两个属性分别指定了模板文件的前缀和后缀。
# 在这个配置中,模板文件应位于类路径下的 /templates/???.html 作为扩展名。
prefix: classpath:/templates/
suffix: .html
encoding: utf-8
# text/html:设置了生成的内容类型为 text/html,表明渲染后的内容将被视为 HTML 文档。
servlet:
content-type: text/html
mode: HTML5
mybatis-plus:
global-config:
db-config:
# 这个属性指定了实体类中主键 ID 的生成策略。`auto`
# 表示使用数据库自增特性(比如 MySQL 的 AUTO_INCREMENT)来生成主键,
# 也就是说,当插入一条新记录时,会自动为 ID 字段生成一个递增的值作为主键。
id-type: auto
# 这个属性设置了字段的插入策略
# 策略意味着在执行插入操作时,只有字段值不为空的情况下才会被插入到数据库中
field-strategy: not_empty
#驼峰下划线转换
column-underline: true
#逻辑删除配置
logic-delete-value: 0 # 数据删除时 设置为0
logic-not-delete-value: 1 # 数据没有删除时 设置为1
db-type: mysql # 数据库类型
# 该设置控制是否启用刷新缓存。
# 当设置为 false 时,在进行更新操作(比如插入、更新、删除)后,MyBatis-Plus 不会自动刷新缓存。
# 这意味着,在进行修改操作后,查询时仍然可能获取到旧的缓存数据,直到下次缓存被重新加载或者手动刷新缓存为止。
refresh: false
configuration:
# 这个选项指定了是否开启驼峰命名和下划线命名的自动映射转换。(java实体类驼峰命名对应数据库字段使用下划线命名)
# 当设置为 `true` 时,数据库表字段使用下划线命名方式(比如 `user_name`),
# 在映射到 Java 实体类时会自动转换为驼峰命名规则(如 `userName`),简化了实体类属性和数据库字段的对应关系。
map-underscore-to-camel-case: true
# 这个属性用来控制 MyBatis 的二级缓存是否启用。
# 当设置为 `false` 时,禁用了 MyBatis 的二级缓存功能。
# 二级缓存是指在会话级别的缓存,可以提高查询性能,但有时也可能带来一致性和并发问题。
cache-enabled: false
# 这个属性指定了 MyBatis 使用的日志输出实现。
# 在这个例子中,日志输出到控制台(标准输出流)。可以根据需求设置不同的日志实现,比如输出到文件或集成其他日志框架
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 这个属性配置了 MyBatis Mapper XML 文件的位置。
# 指定了 XML Mapper 文件所在的路径,这些文件描述了 SQL 映射和查询语句。
#mapper-locations: classpath:/mapper/*.xml
3 column-underline 和 map-underscore-to-camel-case 的区别
当涉及 MyBatis-Plus 的配置时,两个属性 `column-underline` 和 `map-underscore-to-camel-case` 都涉及数据库列名和 Java 对象字段之间的映射规则。
1. **`column-underline: true` (在 `global-config` 的 `db-config` 下)**:
这个属性告诉 MyBatis-Plus 在进行数据库列名到 Java 对象字段的映射时,使用了下划线风格。
例如,如果数据库中的列名是 `user_name`,那么在 Java 对象中对应的字段会是 `userName`。
这只影响 MyBatis-Plus 的默认映射规则,强制其使用下划线风格。
2. **`map-underscore-to-camel-case: true` (在 `configuration` 下)**:
这个属性也涉及数据库列名到 Java 对象字段的映射,但它是用于将数据库中的下划线命名风格转换为 Java 中的驼峰命名风格。
例如,如果数据库列名是 `user_name`,这个配置会使 MyBatis-Plus 在映射到 Java 对象时将其命名为 `userName`。
这个配置更多是为了自动化处理下划线风格到驼峰风格的转换,方便在代码中使用驼峰命名规则。
两者的区别在于作用范围和影响的方式:
- `column-underline: true` 是强制性地告诉 MyBatis-Plus 使用下划线风格,而不管其他配置或约定。它影响默认映射策略。
- `map-underscore-to-camel-case: true` 是告诉 MyBatis-Plus 将数据库列名中的下划线风格自动转换为驼峰风格。
- 这更多是一种方便的约定,用于在代码中保持一致的命名风格。
3 对User类的介绍(实体类)
配置 User.java
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "user")
public class User {
private int id;
private String name;
private String password;
private int age;
private String tel;
private String imagePath;
}
4 springboot绑定到mybatis-plus (数据层)
配置 UserMapper.java
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo5_mybatis.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
5 测试
测试是否可以正常运行
import com.example.demo5_mybatis.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class Demo5MybatisApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
System.out.println(userMapper.selectList(null));
}
}
如果在按上述步骤仍然出现以上问题, 请排除如下问题
1. 数据库配置:
确保数据库连接配置正确,用户名密码正确
2. 依赖版本不兼容(见 1 加入依赖的修改内容):
可以将spring boot 版本改为2.7.6
正确输出
6 写入mapper service层
UserMapper.java
添加@mapper注解,或者在配置类,运行类中添加 @MapperScan(“mapper路径”)用来识别
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo5_mybatis.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
完善 UserService.java
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo5_mybatis.entity.User;
public interface UserService extends IService<User> {
}
完善实现类 UserServiceImpl.java (此处要添加 @Service)
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo5_mybatis.entity.User;
import com.example.demo5_mybatis.mapper.UserMapper;
import com.example.demo5_mybatis.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
7 基础配置controller层
包括查询,删除,修改,增加用户
import com.example.demo5_mybatis.entity.User;
import com.example.demo5_mybatis.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Collections;
import java.util.List;
@Controller
public class UserController {
@Autowired
private UserService userService;
// 用来储存用户数据
private List<User> users;
@RequestMapping("/")
public String index(Model model){
users=userService.list();
model.addAttribute("li",users);
return "index";
}
@RequestMapping("/update")
public String update(int id,Model model){
User u=userService.getById(id);
u.setAge(10);
u.setName("name1");
u.setTel("123456789");
userService.updateById(u);
System.out.println("修改的信息为:"+u);
users=userService.list();
model.addAttribute("li",users);
return "index";
}
@RequestMapping("/delete")
public String delete(int id,Model model){
userService.removeById(id);
System.out.println("删除用户,id="+id);
users=userService.list();
model.addAttribute("li",users);
return "index";
}
@RequestMapping("/addUser")
public String addUser(Model model){
User u=new User();
u.setName("hello");
u.setPassword("pass1");
u.setAge(11);
u.setTel("123456789");
userService.save(u);
users=userService.list();
model.addAttribute("li",users);
return "index";
}
}
8 初始化页面
现有的页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
.t_all{
border: solid 1px black; width:auto;
margin: auto;
}
.bu{
width: 70px; background-color: aqua; color: black;
}
.bu:hover{
background-color: darkorange;
}
</style>
</head>
<body>
<div>
<table class="t_all" border="1">
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>号码</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr th:each="l : ${li}">
<td th:text="${l.id}"></td>
<td th:text="${l.name}"></td>
<td th:text="${l.age}"></td>
<td th:text="${l.tel}"></td>
<td width="160px">
<span>
<a th:href="@{/update(id=${l.id})}">
<button class="bu">修改</button>
</a>
</span>
<span>
<a th:href="@{/delete(id=${l.id})}">
<button class="bu">删除</button>
</a>
</span>
</td>
</tr>
<a th:href="@{/addUser}">
<button class="bu" style="margin-left: 500px;">增加</button>
</a>
</tbody>
</table>
</div>
</body>
</html>
正确页面
9 加入模糊查询功能
这里我们添加可以匹配姓名的模糊查询选项
index.html
<div style="margin: 0px 0px 10px 500px;">
<form method="post" th:action="@{/selectLike}">
姓名:
<input type="text" name="name" />
<input type="submit" value="提交" />
</form>
</div>
UserController.java
@PostMapping("selectLike")
public String selectSome(String name,Model model){
LambdaQueryWrapper<User> lambdaQueryWrapper= Wrappers.lambdaQuery();
lambdaQueryWrapper.like(User::getName,name);
users=userMapper.selectList(lambdaQueryWrapper);
model.addAttribute("li",users);
return "index";
}
正确样式
10 使用分页
如果使用分页,首先需要进行分页配置,再者需要对index.html进行修改
1 创建config软件包,在其中创建类NewPaginationInnerInterceptor 类MybatisPlusConfig
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class NewPaginationInnerInterceptor extends PaginationInnerInterceptor {
private DbType dbType;
// 设置数据库类型
public NewPaginationInnerInterceptor(DbType dbType) {
this.dbType = dbType;
}
// 重写了 handlerOverflow 方法,在分页查询超出最大页码时,将当前页码调整为前一页。
@Override
protected void handlerOverflow(IPage<?> page) {
page.setCurrent(page.getCurrent()-1);
}
}
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
NewPaginationInnerInterceptor newPaginationInnerInterceptor = new NewPaginationInnerInterceptor(DbType.MYSQL);
// 设置了分页插件的 overflow 属性为 true,以便在分页查询超出最大页码时显示第一页。
newPaginationInnerInterceptor.setOverflow(true);
interceptor.addInnerInterceptor(newPaginationInnerInterceptor);
return interceptor;
}
}
2 重新修改index.html
我们新增页码
<nav>
共<a href="#" style="border-radius: 10px;margin-left: 8px;margin-right: 8px;" th:text="${page.pages}"></a>页 <br/>
<a th:href="@{/index(current=${page.current}-1)}">上一页</a> <br/>
当前第<a href="#" style="border-radius: 10px;margin-left: 8px;margin-right: 8px;" th:text="${page.current}"></a>页 <br/>
<a th:href="@{/index(current=${page.current}+1)}">下一页</a>
</nav>
<!-- 进行修改 -->
<tbody>
<tr th:each="l : ${page.records}"></tr>
</tbody>
3 新增index,并且进行page修改
UserController.java
// 用于翻页
@RequestMapping("/index")
public String index(int current,Model model){
Page<User> page=new Page<>(current,10);
userService.page(page,null);
model.addAttribute("page",page);
return "index";
}
@RequestMapping("/")
public String index(Model model){
Page<User> page=new Page<>(1,10);
userService.page(page,null);
model.addAttribute("page",page);
//users=userService.list();
//model.addAttribute("li",users);
return "index";
}
正常图片