什么是MyBatis-Plus?
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生
mybatis-pluss的官方网站
1. 准备环境
DROP TABLE IF EXISTS user;
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
2. 引入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
- 自动配置
- MybatisPlusAutoConfiguration 配置类,MybatisPlusProperties 配置项绑定。mybatis-plus:xxx 就是对mybatis-plus的定制
- SqlSessionFactory 自动配置好。底层是容器中默认的数据源
- mapperLocations 自动配置好的。有默认值。classpath*:/mapper/**/*.xml;任意包的类路径下的所有mapper文件夹下任意路径下的所有xml都是sql映射文件。 建议以后sql映射文件,放在 mapper下
- 容器中也自动配置好了 SqlSessionTemplate
- @Mapper 标注的接口也会被自动扫描;建议直接 @MapperScan(“com.atguigu.admin.mapper”) 批量扫描就行
只需要我们的Mapper继承 BaseMapper 就可以拥有crud能力
2.1 配置数据源
- 在application.yml文件中
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/student
username: root
password: tiger
2.2 配置扫描的mapper接口
@MapperScan("com.tjk.practice5.dao")
@ServletComponentScan(basePackages="com.tjk.practice5")
@SpringBootApplication
public class Practice5Application {
public static void main(String[] args) {
SpringApplication.run(Practice5Application.class, args);
}
}
- 一种是在每个mapper接口上注解@mapper
- 另一种是在启动类上利用@mapperScan(“”)进行配置
2.3 添加bean
**@TableName:**表示该bean对应的数据库中的表是哪一个
@Data
@TableName
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
@TableField(exist = false)
表示该属性在数据库中没有对应的属性
@Data
public class User {
@TableField(exist = false)
private String username;
@TableField(exist = false)
private String password;
2.4 mapper接口(dao)
BaseMapper 继承了这个类就相当于有一些基础的数据库操作已经存在 可以进行调用
/**
* extends BaseMapper<User> 继承了这个属性就相当于有一些基础的数据库操作已经存在 可以进行调用
*/
public interface UserMapper extends BaseMapper<User> {
}
2.5 Service 层
Service是所有的service的总接口 user是返回的数据类型即 需要操作的哪个bean类
/**
* IService是所有的service的总接口 user是返回的数据类型
*/
public interface UserService extends IService<User> {
}
2.6 ServiceImpl实现类
ServiceImpl Service的实现类 UserMapper操作的是那张表 User是返回的数据类型
/**
* ServiceImpl Service的实现类 UserMapper操作的是那张表 User是返回的数据类型
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
这样写就会将mybatisPlus提供给用户的基础数据库操作引入
2.7 controller的编写
@GetMapping("dynamic_table")
public String dynamic_table(@RequestParam(value="pn",defaultValue = "1")Integer pn,Model model ){
/* List<User> users = Arrays.asList(new User("tjk", "123"),
new User("zjj", "123"),
new User("yzy", "123"),
new User("mlh", "123"),
new User("ww", "123"));
model.addAttribute("users",users);*/
//从数据库中查出user表的数据进行填充
List<User> list = userService.list();
//分页查询数据
Page<User> userPage=new Page<>(pn,2);
//分页查询数据的结果
Page<User> page = userService.page(userPage, null);
model.addAttribute("users",list);
model.addAttribute("page",page);
return "/table/dynamic_table";
}
}
2.8 分页的步骤
1. 编写分页的配置类
- MybatisPlusConfig
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
// 开启 count 的 join 优化,只针对部分 left join
//这是分页的拦截器
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
paginationInnerInterceptor.setOverflow(true);//表示可以循环
paginationInnerInterceptor.setMaxLimit(500L);//每页限制500条数据
mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
return mybatisPlusInterceptor;
}
2.8 编写分页的逻辑
@GetMapping("dynamic_table")
public String dynamic_table(@RequestParam(value="pn",defaultValue = "1")Integer pn,Model model ){
/* List<User> users = Arrays.asList(new User("tjk", "123"),
new User("zjj", "123"),
new User("yzy", "123"),
new User("mlh", "123"),
new User("ww", "123"));
model.addAttribute("users",users);*/
//从数据库中查出user表的数据进行填充
List<User> list = userService.list();
//分页查询数据
Page<User> userPage=new Page<>(pn,2);
//分页查询数据的结果
Page<User> page = userService.page(userPage, null);
List<User> records = page.getRecords();
model.addAttribute("users",records);
model.addAttribute("page",page);
return "/table/dynamic_table";
}
3. 前端界面
<table class="display table table-bordered table-striped" id="dynamic-table">
<thead>
<tr>
<th>序号</th>
<th>id</th>
<th>name</th>
<th>age</th>
<th>email</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr class="gradeX" th:each="user,stats: ${page.records}">
<td th:text="${stats.count}"></td>
<td th:text="${user.id}"></td>
<td>[[${user.name}]]</td>
<td th:text="${user.age}"></td>
<td th:text="${user.email}"></td>
<td>
<button th:href="@{/user/delete/{id}(id=${user.id})}" class="btn btn-danger btn-sm">删除</button>
</td>
</tr>
</tfoot>
</table>
<div class="row-fluid">
<div class="span6">
<div class="dataTables_info" id="dynamic-table_info">
当前第[[${page.current}]]页 总计 [[${page.pages}]]页 共[[${page.total}]]条记录
</div>
</div>
<div class="span6">
<div class="dataTables_paginate paging_bootstrap pagination">
<ul>
<li class="prev disabled"><a href="#">← 前一页</a></li>
<li th:class="${num == page.current?'active':''}"
th:each="num:${#numbers.sequence(1,page.pages)}">
<a th:href="@{/dynamic_table(pn=${num})}">[[${num}]]</a>
</li>
<li class="next disabled"><a href="#">下一页 → </a></li>
</ul>
</div>
</div>
这里我发现一个问题,就是点删除按钮没用,找了半天发现是button标签的问题,需要改成<a>
标签即可
4. 删除功能
@GetMapping("/user/delete/{id}")
public String deleteUser(@PathVariable("id") Long id,
@RequestParam(value = "pn",defaultValue = "1")Integer pn,
RedirectAttributes ra){
userService.removeById(id);
ra.addAttribute("pn",pn);
return "redirect:/dynamic_table";
}
<td><a th:href="@{/user/delete/{id}(id=${user.id},pn=${page.current})}" class="btn btn-danger btn-sm">删除</a></td>