是对mybatis的增强,只做增强不做改变
环境spring boot
com.baomidou mybatis-plus-boot-starter 3.5.1 mysql mysql-connector-java runtime
spring:
# 配置数据源信息
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&characterEncoding=utf-8&userSSL=false
username: root
password: root
mybatis-plus:
configuration:
# 配置sql日志信息
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 配置类型别名所对应的包
type-aliases-package: com.xxx.mybatis.domain
# mybatisplus的全局配置
global-config:
db-config:
# 设置所有实体类所对应的表名的共同前缀
table-prefix: t_
# 设置统一主键生成策略
id-type: assign_id
# 扫描通用枚举包
type-enums-package: com.xxx.mybatis.enums
spring boot 启动类增加@MapperScan注解
@SpringBootApplication
//用于扫描mapper接口所在的包
@MapperScan("com.xxx.mybatis.mapper")
public class MybatisApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisApplication.class, args);
}
}
baseMapper 通用mapper
baseMapper是mybatisplus提供的类,里面有大量增删改查方法可供使用
public interface UserMapper extends baseMapperIservice 通用service{ }
public interface IUserService extends IService{ }
@Service public class UserServiceImpl extends ServiceImpl@TableNameimplements IUserService { }
当实体类所对应的数据库表名不一致时,可以使用@TableName标注实体类所对应的表名,如果所有表都有固定前缀,可以在配置文件中设置表名前缀
@Data
@TableName("t_user")
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
# yml中配置 # 设置所有实体类所对应的表名的共同前缀 table-prefix: t_@TableId
可以将这个注解所对应的字段指定为主键
type属性用来定义主键生成策略
IdType.AUTO 设置id自增,但必须保证数据库表id也设置了自增,否则无效
IdType.ASSIGN_ID 雪花算法自动生成id
IdType.ASSIGN_UUID 生成UUID
@TableId(value = "uid",type = IdType.AUTO)
private Long id;
通过全局配置设置主键生成策略
# yml中配置 # 设置统一主键生成策略 id-type: assign_id@TableField
通过@TableField指定属性所对应的字段名
@Data
@TableName("t_user")
public class User {
@TableId(value = "uid",type = IdType.AUTO)
private Long id;
@TableField("user_name")
private String userName;
@TableField("age")
private Integer age;
@TableField("email")
private String email;
}
@TableLogic
逻辑删除,假删除,将对应数据中表示删除字段的状态改为被删除状态,在数据库仍旧存在,可以方便之后进行恢复数据
@Data
@TableName("t_user")
public class User {
@TableId(value = "uid",type = IdType.AUTO)
private Long id;
@TableField("user_name")
private String userName;
@TableField("age")
private Integer age;
@TableField("email")
private String email;
@TableLogic
private Integer isDelete;
}
Wapper queryWapper 条件构造器
查询
@Test
public void select01(){
//查询所有年龄大于等于20小于等于50且名字带有"测试"的人
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.ge("age",20)
.le("age",50)
.like("name","测试");
List users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
删除
@Test
public void delete02(){
//删除id是1,2,3,4,5的用户
UpdateWrapper updateWrapper= new UpdateWrapper<>();
updateWrapper.in("id",1,2,3,4,5);
int delete = userMapper.delete(updateWrapper);
System.out.println(delete);
}
修改
@Test
public void update03(){
//将所有年龄大于等于80或小于等于10的人的邮箱改为"111@qq.com"
//UPDATE t_user SET email=? WHERe is_delete=0 AND (age >= ? OR age <= ?)
UpdateWrapper updateWrapper = new UpdateWrapper<>();
updateWrapper.ge("age",80)
.or()
.le("age",10);
User user = new User();
user.setEmail("111@qq.com");
int updateResult = userMapper.update(user, updateWrapper);
System.out.println(updateResult);
}
condition使用方式
queryWrapper.ge(StringUtils.isNotBlank("age"),"age",20);
lambda使用方式
LambdaQueryWrapper分页插件lambdaQueryWrapper = new LambdaQueryWrapper<>(); //updateWrapper.in("id",1,2,3,4,5); lambdaQueryWrapper.in(User::getId,1,2,3,4,5); userMapper.delete(lambdaQueryWrapper);
分页插件配置类,可以把启动类上的@MapperScan放在配置类上
@Configuration
@MapperScan("com.xxx.mybatis.mapper")
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
@Test
public void select04(){
Page page = new Page<>(1,3);
userMapper.selectByPage(page);
}
public interface UserMapper extends baseMapper乐观锁插件 场景描述{ Page selectByPage(@Param("page") Page page); }
商品单价100,A员工将价格+50,B员工将价格-30,AB同时操作,出现了多读的情况,导致商品价格本应为120,却变成了70,为解决这个情况,使用乐观锁插件,增加了version版本字段
修改MyBatisPlusConfig@Configuration
@MapperScan("com.xxx.mybatis.mapper")
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
@Version
在版本号字段上增加@version注解
@Data
public class Product {
@TableId(value = "id",type = IdType.ASSIGN_UUID)
private Long id;
@TableField("product_name")
private String productName;
@TableField("price")
private Integer price;
@Version
private Integer version;
}
案例
@Test
public void selectA(){
//A员工查询的商品价格
Product productA = productMapper.selectById(1);
System.out.println("A员工查询的商品价格:"+productA.getPrice());
//B员工查询的商品价格
Product productB = productMapper.selectById(1);
System.out.println("B员工查询的商品价格:"+productB.getPrice());
//A员工将商品价格+50
productA.setPrice(productA.getPrice()+50);
productMapper.updateById(productA);
//B员工将商品价格-30
productB.setPrice(productB.getPrice()-30);
productMapper.updateById(productB);
//老板查询商品价格
Product productC = productMapper.selectById(1);
System.out.println("老板查询的商品价格:"+productC.getPrice());
}
结论
增加乐观锁后,A员工将商品价格+50同时修改了版本号,B员工-30时,因为带上的版本号与新版本号不一致,导致update失败,从而避免了修改出错;
通用枚举修改yml配置
# 扫描通用枚举包 type-enums-package: com.xxx.mybatis.enums
user表新增字段sex
创建枚举类@Getter
@AllArgsConstructor
public enum SexEnum {
MALE(1,"男"),
FEMALE(2,"女");
@EnumValue
private Integer sex;
private String sexName;
}
User实体类修改
private SexEnum sex;测试类
@Test
public void insertEnum(){
User user = new User();
user.setName("小王");
user.setAge(20);
user.setSex(SexEnum.FEMALE);
userMapper.insert(user);
}
代码生成器
引入依赖
模板com.baomidou mybatis-plus-generator 3.5.2
FastAutoGenerator.create("url", "username", "password")
.globalConfig(builder -> {
builder.author("baomidou") // 设置作者
.enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir("D://mybatisplus"); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.baomidou.mybatisplus.samples.generator") // 设置父包名
.moduleName("system") // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.xml, "D://mybatisplus")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude("t_simple") // 设置需要生成的表名
.addTablePrefix("t_", "c_"); // 设置过滤表前缀
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
MyBatisX很好用~



