MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
特性如下
更多请查看官网。
下面基于springboot,尝试这个MyBatis的增强工具,包括引入、配置、简单使用。
1、创建springboot工程,引入mybatis-plus
com.baomidou
mybatis-plus-boot-starter
3.5.0
com.baomidou
dynamic-datasource-spring-boot-starter
3.5.0
mysql
mysql-connector-java
runtime
2、mysql数据库环境
新建数据库
建议大家选择utf8mb4这种字符集,微信APP中微信用户名称的表情,是需要这种字符集才能存储的。
新建表
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nickname` varchar(255) NOT NULL COMMENT '昵称',
`sex` tinyint(1) NOT NULL COMMENT '性别,1男2女',
`create_time` datetime NOT NULL COMMENT '创建时间',
`is_delete` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除 1是,0否',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8mb4;
3、配置
启动类添加mapper扫描注解
@MapperScan("com.*.mapper")
@SpringBootApplication
public class SpringbootMybatisPlusApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisPlusApplication.class, args);
}
}
application.yml配置
spring:
datasource:
dynamic:
# 设置默认的数据源或者数据源组,默认值即为master
primary: master
# 严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
master:
url: jdbc:mysql://127.0.0.1:3306/mybatis_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone =Asia/Shanghai
username: root
password: root
slave_1:
url: jdbc:mysql://127.0.0.1:3306/mybatis_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone =Asia/Shanghai
username: root
password: root
# 连接池
hikari:
max-lifetime: 1800000
connection-timeout: 5000
idle-timeout: 3600000
max-pool-size: 12
min-idle: 4
connection-test-query: /**ping*/
mybatis-plus:
# 支持统配符 * 或者 ; 分割
typeEnumsPackage: com.*.*.enums
这里面因为默认使用的是HikariCP数据源,目前也推荐使用这个,相比于druid有更高的性能,但是不能忽略下面的配置,否则服务会不断抛出异常,原因是数据库的连接时常和连接池的配置没有做好。
3、使用
实体类添加注解
@TableName(value = "user")
public class User {
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 昵称
*/
@TableField("nickname")
private String nickname;
/**
* 性别
*/
@TableField(value = "sex")
private SexEnum sex;
/**
* 版本
*/
@TableField(value = "version",update = "%s+1")
private Integer version;
/**
* 时间字段,自动添加
*/
@TableField(value = "create_time",fill = FieldFill.INSERT)
private LocalDateTime createTime;
}
其中@TableName表名注解,用于标识实体类对应的表,其源码如下
@TableId主键注解,其源码如下
AUTO:数据库自增 ID;
NONE:该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT);
INPUT:用户自己设置的 ID;
ASSIGN_ID:当用户传入为空时,自动分配类型为 Number 或 String 的主键(雪花算法);
ASSIGN_UUID:当用户传入为空时,自动分配类型为 String 的主键;
ASSIGN_ID默认采用的是雪花算法
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。具体实现的代码可以参看https://github.com/twitter/snowflake。雪花算法支持的TPS可以达到419万左右(2^22*1000),几乎保证全球唯一。
@TableFiled字段注解,其源码如下
持久层,mybatis-plus已经封装好了接口提供直接调用。
@Mapper
public interface UserMapper extends BaseMapper {
}
业务层,也是mybatis-plus已经封装好了接口提供直接调用。
public interface IUserService extends IService {
}
@Service
public class UserServiceImpl extends ServiceImpl implements IUserService {
}
分页插件配置
@Configuration
@MapperScan("com.*.mapper*")
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
枚举配置
相信后端的同学都经历过一个情况,比如性别这个字段,分别值和名称对应1男、2女,这个字段在数据库时是数值类型,而前端展示则是展示字符串的名称,传统解决方式如下
相信无论哪种方法都有其缺点,所以我们可以使用mybatis-plus提供的方式,在返回给前端时,只需要在遍历时get这个枚举,直接赋值其名称,不需要再次判断。
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum SexEnum implements IEnum {
MAN(1, "男"),
WOMAN(2, "女");
private Integer code;
private String name;
SexEnum(Integer code, String name) {
this.code = code;
this.name = name;
}
@Override
public Integer getValue() {
return code;
}
public String getName() {
return name;
}
}
其中,@JsonFormat注解为了解决枚举类返回前端只展示构造器名称的问题。
配置文件扫描枚举
mybatis-plus:
# 支持统配符 * 或者 ; 分割
typeEnumsPackage: com.ldc.*.enums
自动填充配置
注解@TableFeild当中有个属性叫做fill,通过FieldFill设置属性,这个就是做自动填充用的。但是这个直接是不能使用的,需要通过实现mybatis-plus提供的接口,增加如下配置
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
// 起始版本 3.3.0(推荐使用)
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
// 起始版本 3.3.0(推荐)
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}
数据源配置
配置文件当中配置了主从的方式,其实mybatis-plus还支持更多的方式,其使用方式为添加@DS注解,可以注解在方法上或类上,同时存在就近原则 【方法上注解】 优先于 【类上注解】
@DS("slave_1")
@Service
public class UserServiceImpl extends ServiceImpl implements IUserService {
@DS("salve_1")
@Override
public List getList() {
return this.getList();
}
@DS("master")
@Override
public int saveUser(User user) {
boolean save = this.save(user);
if (save){
return 1;
}else{
return 0;
}
}
}
sql日志配置
mybatis-plus:
# 支持统配符 * 或者 ; 分割
typeEnumsPackage: com.ldc.*.enums
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
控制层
@Autowired
private IUserService userService;
/**
* description: 新增
* @return: boolean
*/
@RequestMapping("/save")
public boolean save() {
User user = new User();
user.setNickname("222");
user.setSex(SexEnum.MAN);
return userService.save(user);
}
/**
* description: 修改
* @param nickname
* @param id
* @return: boolean
*/
@RequestMapping("/update")
public boolean update(@RequestParam String nickname, @RequestParam Long id) {
User user = new User();
user.setNickname(nickname);
user.setId(id);
return userService.updateById(user);
}
/**
* description: 删除
* @param id
* @return: boolean
*/
@RequestMapping("/delete")
public boolean delete(@RequestParam Long id) {
User user = new User();
user.setId(id);
return userService.removeById(user);
}
/**
* description: 列表
*/
@RequestMapping("/list")
public List list() {
return userService.list();
}
/**
* description: 分页列表
* @param current
* @param size
*/
@RequestMapping("/page")
public Page page(@RequestParam int current, @RequestParam int size) {
return userService.page(new Page<>(current,size), new QueryWrapper(new User()));
}
还需在实际工程中应用,深入理解其能力和原理,加油吧,少年。