前言:
最近对mybatis-plus这块比较感兴趣,自己用SpringBoot整合了一下mybatis-plus,发现其中还是有很多点需要注意的,下面是整个搭建过程,涉及到mybatis-plus中的全局id设置、自动填充、乐观锁、 逻辑删除、性能分析插件、分页插件等知识点
想要学习具体API的使用可以查看:https://mp.baomidou.com/
1、pom.xml添加依赖
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.3</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>5.0.4</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.1</version>
</dependency>
2、配置文件
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/cms?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driverClassName=com.mysql.jdbc.Driver
# 扫描xml文件
mybatis-plus.mapper-locations=classpath*:/mapper/**Mapper.xml
# bean实体扫描
mybatis-plus.type-aliases-package=com.hand.cms.domain
# 逻辑已删除值(默认为1)
mybatis-plus.global-config.db-config.logic-delete-value=1
# 逻辑未删除值(默认为0)
mybatis-plus.global-config.db-config.logic-not-delete-value=0
# 全局id设置 auto:数据库ID自增 id_worker:全局唯一ID UUID:全局唯一ID
mybatis-plus.global-config.db-config.id-type=id_worker
3、配置类
主启动类上使用@MapperScan扫描mapper所在包
package com.hand.cms.config;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("com.hand.cms.mapper")
public class MybatisPlusConfig {
/**
* mybatis-plus性能分析插件
*
* @return
*/
@Bean
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
//SQL执行性能分析,开发环境使用,线上不推荐 maxTime指的是sql最大执行时长
performanceInterceptor.setMaxTime(1000);
//SQL是否格式化 默认false
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
/**
* mybatis-plus分页插件
*
* @return
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
/**
* mybatis-plus乐观锁插件
*
* @return
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
package com.hand.cms.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 插入时自动填充
*
* @param metaObject
*/
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createdDate", formatter.format(ZonedDateTime.now()), metaObject);
this.setFieldValByName("lastUpdatedDate", formatter.format(ZonedDateTime.now()), metaObject);
}
/**
* 更新时自动填充
*
* @param metaObject
*/
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("lastUpdatedDate", formatter.format(ZonedDateTime.now()), metaObject);
}
}
4、通用实体
package com.hand.cms.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.io.Serializable;
@Data
public class BaseDomain implements Serializable {
@TableId(value = "id")
protected Long id;
@TableField(value = "created_date", fill = FieldFill.INSERT)
protected String createdDate;
@TableField(value = "last_updated_date", fill = FieldFill.INSERT_UPDATE)
protected String lastUpdatedDate;
/**
* 乐观锁实现方式:
* 取出记录时,获取当前version
* 更新时,带上这个version
* 执行更新时, set version = newVersion where version = oldVersion
* 如果version不对,就更新失败
*/
@TableField(value = "version_number", strategy = FieldStrategy.NOT_NULL)
@Version
protected Integer versionNumber;
/**
* 逻辑删除:
* 使用mybatis-plus自带方法删除和查找都会附带逻辑删除功能(自己写的xml不会)
*/
@TableField(value = "deleted", strategy = FieldStrategy.NOT_NULL)
@TableLogic
protected Integer deleted;
}
5、实体类Bean
package com.hand.cms.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@TableName(value = "user")
@Data
public class User extends BaseDomain {
/**
* 用户名
*/
@TableField("username")
private String username;
/**
* 真实姓名
*/
@TableField("real_name")
private String realName;
/**
* 密码
*/
@TableField("password")
private String password;
/**
* 邮箱
*/
@TableField("email")
private String email;
}
6、数据库表设计
user表:
名 | 类型 | 长度 | 是否为主键 | 默认值 |
---|---|---|---|---|
id | bigint | 20 | 主键 | |
username | varchar | 30 | ||
real_name | varchar | 30 | ||
password | varchar | 30 | ||
varchar | 30 | |||
created_date | varchar | 30 | ||
last_updated_date | varchar | 30 | ||
version_number | int | 11 | 1 | |
deleted | int | 11 | 0 |
7、Mapper
package com.hand.cms.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hand.cms.domain.User;
public interface UserMapper extends BaseMapper<User> {
}
8、Service层接口
package com.hand.cms.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.hand.cms.domain.User;
import java.util.List;
public interface UserService extends IService<User> {
/**
* 分页查询用户
*
* @param page
* @return
*/
IPage<User> getUserPage(Page page);
/**
* 根据用户名模糊查询用户信息
*
* @param username
* @return
*/
List<User> getUserByUsername(String username);
/**
* 添加用户
*
* @param user
*/
void insertUser(User user);
/**
* 修改用户
*
* @param user
*/
void updateUser(User user);
/**
* 根据ID删除用户
*
* @param id
*/
void deleteUserById(Long id);
}
9、Service实现类
package com.hand.cms.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hand.cms.domain.User;
import com.hand.cms.mapper.UserMapper;
import com.hand.cms.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override
public IPage<User> getUserPage(Page page) {
return baseMapper.selectPage(page, null);
}
@Override
public List<User> getUserByUsername(String username) {
return baseMapper.selectList(new QueryWrapper<User>().like(username != null, "username", username));
}
@Transactional(rollbackFor = Exception.class)
@Override
public void insertUser(User user) {
baseMapper.insert(user);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateUser(User user) {
baseMapper.updateById(user);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteUserById(Long id) {
baseMapper.deleteById(id);
}
}
10、工具类
package com.hand.cms.utils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.http.HttpHeaders;
public class PageUtils {
public static HttpHeaders getTotalHeader(Page<?> page) {
HttpHeaders headers = new HttpHeaders();
headers.add("x-total-count", "" + page.getTotal());
return headers;
}
}
11、Controller
package com.hand.cms.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hand.cms.domain.User;
import com.hand.cms.service.UserService;
import com.hand.cms.utils.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/list")
public ResponseEntity<List<User>> getUserPage(@RequestParam(value = "page", defaultValue = "1") int page,
@RequestParam(value = "size", defaultValue = "10") int size) {
Page mybatisPage = new Page(page, size);
IPage<User> userPage = userService.getUserPage(mybatisPage);
HttpHeaders httpHeaders = PageUtils.getTotalHeader(mybatisPage);
return new ResponseEntity<>(userPage.getRecords(), httpHeaders, HttpStatus.OK);
}
@GetMapping("/getUserByUsername")
public ResponseEntity<List<User>> getUserByUsername(@RequestParam(value = "username", required = false) String username) {
List<User> user = userService.getUserByUsername(username);
return new ResponseEntity<>(user, HttpStatus.OK);
}
@PostMapping("/insert")
public ResponseEntity insertUser(@RequestBody User user) {
userService.insertUser(user);
return new ResponseEntity<>(HttpStatus.OK);
}
@PutMapping("/update")
public ResponseEntity updateUser(@RequestBody User user) {
userService.updateUser(user);
return new ResponseEntity<>(HttpStatus.OK);
}
@DeleteMapping("/deleteById")
public ResponseEntity deleteUserById(@RequestParam(value = "id") Long id) {
userService.deleteUserById(id);
return new ResponseEntity<>(HttpStatus.OK);
}
}