官方文档快速入门案例
# 配置日志
mybatis-plus:
configuration:
# 配置 mybatis-plus执行的日志类型(可以看到执行过程) 下面是使用了控制台输出 sl4j log4j 等等都可以
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
效果
数据库中未指定id自增方式 我们可以通过mybatis-plus 来生成
插入一条数据
User user = new User();
user.setAge(3);
user.setName("xiuyuan");
user.setEmail("[email protected]");
userMapper.insert(user);
System.out.println(user);
你会发现,我们虽然没有指定id,但是他会自动给我们生成id,并赋给了user
数据库插入的id的默认值为:全局的唯一id
分布式系统唯一Id生成方案汇总
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。具体实现的代码可以参看https://github.com/twitter/snowflake。
mybatis-plus 默认主键生成方案 ID_WORKER
我们可以通过 @TableId 指定主键生成方式
public class User {
@TableId(type = IdType.ID_WORKER)
private Long id;
private String name;
private Integer age;
private String email;
IdType
public enum IdType {
AUTO(0), // 数据库id自增
NONE(1), // 未设置主键
INPUT(2), //手动输入
ID_WORKER(3), // 默认的全局唯一id
UUID(4), // 全局唯一id uuid
ID_WORKER_STR(5); // ID_WORKER 字符串表示法
private int key;
private IdType(int key) {
this.key = key;
}
public int getKey() {
return this.key;
}
}
@Test
void update(){
User user = new User();
user.setId(2L);
user.setAge(20);
// 自动支持 动态sql(会自动判断 属性是否为''或null)
int i = userMapper.updateById(user);
}
从更新操作中 你会发现它是支持动态sql判断的(填充动态sql)。
创建时间和修改时间!这些操作一般都是自动化完成的,我们不希望手动更新!
方式一 数据库级别(工作中不推荐)
方式二 代码级别
自动填充功能入门
1、实体类上添加填充注解
// 字段添加填充内容
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
2、编写一个处理器来处理注解
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
// 插入时填充的操作
@Override
public void insertFill(MetaObject metaObject) {
// 方法签名 MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
}
// 更新时填充的操作
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
测试一下
mybaits-plus乐观锁官方文档
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
1、给数据库中增加version字段
2、我们的实体类同步字段
// mybatis-plus 的乐观锁 Version注解
@Version
private Integer version;
@Version 说明:
支持的数据类型只有:
int,Integer,long,Long,Date,Timestamp,LocalDateTime
整数类型下newVersion = oldVersion + 1
newVersion 会回写到 entity 中
仅支持 updateById(id) 与 update(entity, wrapper) 方法
在 update(entity, wrapper) 方法下, wrapper 不能复用!!!
3、配置乐观锁插件(新版本已失效)
新版本已失效
@MapperScan("com.zlf.mapper")
@Configuration
public class mybatisPlusConfig {
@Bean
public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor(){
return new OptimisticLockerInnerInterceptor();
}
}
新版本
@MapperScan("com.zlf.mapper")
@Configuration
public class mybatisPlusConfig {
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 配置 乐观锁拦截器
OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor();
interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);
return interceptor;
}
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> configuration.setUseDeprecatedExecutor(false);
}
}
测试
/**
* 测试乐观锁失败(模拟多线程)
*/
@Test
void testLock2(){
// 1、查询用户信息
User user = userMapper.selectById(1L);
// 2、修改用户信息
user.setEmail("cccc@abc");
user.setAge(18);
User user2 = userMapper.selectById(1L);
user.setName("小白");
// 插队修改
userMapper.updateById(user2);
userMapper.updateById(user);
}
/**
* 测试查询
*/
@Test
void testSelect(){
// 查询一个
User user = userMapper.selectById(1L);
// 查询多个 方法签名 List selectBatchIds(@Param("coll") Collection extends Serializable> idList);
List<User> users = userMapper.selectBatchIds(Arrays.asList(1L,2L,3L));
// 条件查询之一 selectByMap
HashMap<String, Object> map = new HashMap<>();
map.put("name","小白"); // key 是列名 value 是要查询的值
map.put("age",18); // 多个条件之间是 and
List<User> users1 = userMapper.selectByMap(map);
}
1、配置分页拦截器
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//分页拦截器
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 配置 乐观锁拦截器
OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor();
interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);
return interceptor;
}
2、直接使用Page对象
@Test
void testPage(){
// 参数一:当前页,参数二:显示条数
Page<User> page = new Page<>(1,5);
// 分页查询
Page<User> userPage = userMapper.selectPage(page, null);
// 获取记录 getRecords()
userPage.getRecords().forEach(System.out::println);
}
@Test
void testDelete(){
// 通过id删除一条记录
userMapper.deleteById(1L);
// 通过id集合删除整个集合对应记录
userMapper.deleteBatchIds(Arrays.asList(2L,3L));
// 通过条件删除 条件之间为 and
Map<String, Object> map = new HashMap<>();
map.put("name","小黑");
map.put("age",18);
userMapper.deleteByMap(map);
}
逻辑删除官方文档
物理删除:从数据库中直接移除
逻辑删除:在数据库中没有被移除,而是通过一个变量来让他失效!
类似管理员查看被删除的记录。防止数据的丢失,类似于回收站!
@TableLogic //逻辑删除注解
private Integer deleted;
mybatis-plus:
global-config:
db-config:
# 配置逻辑删除
logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略@TableLogic)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
@Test
void testDelete(){
// 通过id删除一条记录
userMapper.deleteById(2L);
}
我们再来查询一下
@Test
void testLock(){
// 1、查询用户信息
User user = userMapper.selectById(2L);
System.out.println(user);
}
旧版本就不说了。
新版本在 执行 SQL 分析打印官方文档
条件构造器官方文档
这边使用的版本是3.4.1
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-generatorartifactId>
<version>3.4.1version>
dependency>
<dependency>
<groupId>org.apache.velocitygroupId>
<artifactId>velocity-engine-coreartifactId>
<version>2.3version>
dependency>
代码生成器官方文档
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
@SpringBootTest
class MallApplicationTests {
@Test
void contextLoads() {
}
@Test
public void run() {
// 1、创建代码生成器
AutoGenerator mpg = new AutoGenerator();
// 2、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("zlf");
gc.setOpen(false); //生成后是否打开资源管理器
gc.setFileOverride(false); //重新生成时文件是否覆盖
gc.setServiceName("%sService"); //去掉Service接口的首字母I
gc.setIdType(IdType.ID_WORKER); //主键策略
gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型
gc.setSwagger2(true);//开启Swagger2模式
mpg.setGlobalConfig(gc);
// 3、数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/数据库名");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("xxxx");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
// 4、包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName("mall"); //模块名
pc.setParent("com");
// com.zlf.edu.controller
pc.setController("controller");
pc.setEntity("entity");
pc.setService("service");
pc.setMapper("mapper");
mpg.setPackageInfo(pc);
// 5、策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("表名");
strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀
strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作
strategy.setRestControllerStyle(true); //restful api风格控制器
strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符
strategy.setLogicDeleteFieldName("is_deleted");
// 自动填充配置
TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
TableFill gmtModified = new TableFill("gmt_modified",
FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(gmtCreate);
tableFills.add(gmtModified);
strategy.setTableFillList(tableFills);
mpg.setStrategy(strategy);
// 6、执行
mpg.execute();
}
}