一、什么是MyBatis-Plus
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
建议安装 MybatisX 插件
二、整合MyBatis-Plus
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
自动配置
- MybatisPlusAutoConfiguration 配置类,MybatisPlusProperties 配置项绑定。yml文件中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能力,不需要再在xml写sql语句。
先定义与数据库表对应的Bean,默认找与类名相同的表(开头大小写不区分)。@TableName("user_tb")可以修改对应的表。
@Data
//@TableName("user")
public class User {
//表中没有的属性
@TableField(exist = false)
private String userName;
@TableField(exist = false)
private String password;
//以下是数据库的资料
private Long id;
private String name;
private Integer age;
private String email;
}
再编写对应Mapper继承BaseMapper,不需要写sql的xml文件。
//使用mybatis-plus编写mapper BaseMapper有写好的方法
public interface UserMapper extends BaseMapper<User> {
}
测试:
@SpringBootTest
class BootWebAdminApplicationTests {
@Autowired
UserMapper userMapper;
@Test
void testUserMapper(){
User user =userMapper.selectById(1L);
log.info("用户信息:{}",user);
}
}
三、CRUD功能
不仅Mapper可以继承BaseMapper接口,service层也可以继承IService接口,接口里就不用写重复的方法。然后service的实现类继承ServiceImpl类,里面帮忙实现好了默认方法,最后直接放入容器,就可以用里面的默认方法,包括增删改查等。
public interface UserService extends IService<User> {
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
@Controller
public class TableController {
@Autowired
UserService userService;
@GetMapping("/dynamic_table")
public String dynamicTable(@RequestParam(value = "pn",defaultValue = "1")Integer pn, Model model){
List<User> list = userService.list();
model.addAttribute("users", list);
return "/table/dynamic_table";
}
分页功能实现
配置分页插件:
@Configuration
public class MyBatisConfig {
@Bean
public MybatisPlusInterceptor paginationInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//分页拦截器
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
//在最后一页点击下一页,跳回到首页
paginationInnerInterceptor.setOverflow(true);
//每页限制最多500条
paginationInnerInterceptor.setMaxLimit(500L);
mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
return mybatisPlusInterceptor;
}
}
后端逻辑:
@GetMapping("/dynamic_table")
public String dynamicTable(@RequestParam(value = "pn",defaultValue = "1")Integer pn, Model model){
List<User> list = userService.list();
// model.addAttribute("users", list);
//第一个参数是当前页码,第二个参数是每页显示多少条记录
Page<User> userPage = new Page<>(pn, 2);
//分页查询结果,包括当前页码,总页数,总记录,所有记录集合。
Page<User> page = userService.page(userPage, null);
model.addAttribute("page", page);
return "/table/dynamic_table";
}
前端展示:
<tr class="gradeX" th:each="user,stat :${page.records}">
<td th:text="${stat.count}">Trident</td>
<td th:text="${user.id}"></td>
<td th:text="${user.name}">Win 95+</td>
<td th:text="${user.age}">Win 95+</td>
<td th:text="${user.email}">Win 95+</td>
<td class="center hidden-phone">4</td>
<td class="center hidden-phone">X</td>
</tr>
<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"><li class="next"><a href="#">下一页 → </a></li>
</ul>
</div>
</div>
删除用户
后端逻辑:
@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";
}
需要注意重定向是两次请求,所以使用HttpServletRequest携带参数会失效,要使用RedirectAttributes 携带参数。
前端逻辑:
<td>
<a class="btn btn-danger btn-sm" type="button" th:href="@{/user/delete/{id}(id=${user.id},pn=${page.current})}">删除</a>
</td>