Mybatis-Plus


引入mybatis-plus

简介

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

环境配置
  • 1、在SpringBoot项目中引入依赖,引入mybatis-plus后不用引入mybatis依赖

    
     mysql
     mysql-connector-java
     runtime
    
    
     org.projectlombok
     lombok
     true
    
    
     com.baomidou
     mybatis-plus-boot-starter
     3.4.1
    
    
  • 2、配置数据库连接

    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://121.199.33.165:3306/mybatis-plus?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    spring.datasource.username=mybatis-plus
    spring.datasource.password=123456
    
  • 3、编写Mapper接口

    /**
    * 继承BaseMapper类即可使用mybatis-plus封装好的crud方法
    * 泛型传入操作的实体类
    */
    @Repository
    public interface UserMapper extends BaseMapper {
    
    }
    
  • 4、在启动类添加扫描mapper接口包

    @MapperScan("com.wt.mapper")
    
  • 5、使用CRUD方法

    具体方法参考官网:https://baomidou.com/guide/crud-interface.html#mapper-crud-接口

    @Autowired
        private UserMapper userMapper;
    
        @Test
        void contextLoads() {
    
            List userList = userMapper.selectList(null);
        }
    
配置日志
# 配置日志,此处使用控制台输出
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

主键生成策略

一、配置主键生成策略

1、全局配置

#全局设置主键生成策略
mybatis-plus.global-config.db-config.id-type=auto

2、局部配置(针对于某一张表配置)

@TableId(type = IdType.AUTO)
private Long id;
二、雪花算法

SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。

64位ID组成:

  • 1 bit:符号位,统一为正数位0
  • 41 bit:表示的是时间戳,单位是毫秒
  • 10 bit:记录工作机器 id,代表的是这个服务最多可以部署在 2^10 台机器上,也就是 1024 台机器
  • 12 bit:这个是用来记录同一个毫秒内产生的不同 id
三、主键生成策略的类型
  • ID_WORKER:根据雪花算法生成19位的数值
  • ID_WORKER_STR:根据雪花算法生成19位的字符串
  • AUTO:采用数据库自增方式。(数据库也需要设置自增)
  • UUID:使用UUID作为主键ID
  • INPUT:手动设置ID
  • ONOE:未设置主键
  • ASSIGN_ID:根据雪花算法生成19位的数值(主键类型为长整形或字符串)
  • ASSIGN_UUID:排除中划线的UUID

自动填充

1、在需要填充的实体类字段加上注解

/**
*FieldFill.INSERT:在插入时进行填充
*FieldFill.UPDATE:在修改时进行填充
*FieldFill.INSERT_UPDATE:在插入和修改时进行填充
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;

@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

2、配置自动填充处理类

@Component	//将配置类交给spring管理
public class MyMetaObjectHandler implements MetaObjectHandler {

    /**
     * 插入时的填充策略
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {

        //设置填充的字段名,值,对象
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);

    }

    /**
     * 更新时的填充策略
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {

        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

乐观锁

一、乐观锁与悲观锁
  • 悲观锁:总是假设最坏的情况,每次去数据库拿数据时都认为别人会修改,所以每次拿数据都会进行上锁,直到操作结束后,才会释放锁,别人才能操作。缺点:每次都要加锁,降低执行效率
  • 乐观锁:总是假设最好的情况,在去数据库拿数据时,认为没人会修改,所以不会上锁,而是在更新操作的时候,判断此期间有没有人去更新过数据,通过版本号或CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量
二、配置乐观锁

1、在实体类版本号字段上加上@Version注解

@Version
private Integer version;

2、配置乐观锁插件

@EnableTransactionManagement	//配置事务管理
@Configuration			//标明是配置类
public class MybatisPlusConfig {

    /**
     * 乐观锁插件(过时写法)
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }

    /**
     * 乐观锁插件(最新版本写法)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {

        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //配置乐观锁
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());

        return mybatisPlusInterceptor;
    }
}

3、测试

@Test
public void testOptimisticLocker2() {
    User user = userMapper.selectById(1350729402602700801L);
    user.setName("张三111");

    User user1 = userMapper.selectById(1350729402602700801L);
    user1.setName("张三222");
    //更新成功
    userMapper.updateById(user1);
    //更新失败,版本号已经被变动
    userMapper.updateById(user);
}

查询操作

  • 根据id主键查询

    User user = userMapper.selectById(1350729402602700801L);
    
  • 根据id集合查询

    ArrayList ids = new ArrayList<>();
    ids.add("1");
    ids.add("2");
    ids.add("3");
    List users = userMapper.selectBatchIds(ids);
    
  • 根据Map条件查询

    HashMap map = new HashMap<>();
    //封装过滤条件
    map.put("name","张三222");
    map.put("age","21");
    List users = userMapper.selectByMap(map);
    

分页查询

1、配置查询分页插件

@EnableTransactionManagement
@Configuration
public class MybatisPlusConfig {

    /**
     * 配置分页插件(过时写法)
     * @return
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

    /**
     * 配置分页插件(最新版本写法)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {

        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //配置分页插件
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());

        return mybatisPlusInterceptor;
    }
}

2、使用分页

/*
 * 参数一:当前页
 * 参数二:每页条数
 */
Page page = new Page<>(1,5);
Page userPage = userMapper.selectPage(page, null);
//分页后数据结果列表
List records = userPage.getRecords();
//数据总数
long total = userPage.getTotal();

删除操作

一、基本删除
//根据id删除
int result = userMapper.deleteById(1L);

//根据id集合删除
ArrayList ids = new ArrayList<>();
ids.add("2");
ids.add("3");
int result2 = userMapper.deleteBatchIds(ids);

//根据Map条件集合删除
HashMap map = new HashMap<>();
map.put("name","张三222");
int result3 = userMapper.deleteByMap(map);

二、逻辑删除

逻辑删除:不真正删除数据,只通过改变逻辑删除字段,让数据不再被查询出来

1、给实体类逻辑删除字段加上注解

@TableLogic
private Integer deleted;

2、逻辑删除插件配置

# 配置mybatis-plus逻辑删除
#全局逻辑删除实体类的字段
mybatis-plus.global-config.db-config.logic-delete-field=deleted
#逻辑已删除的值
mybatis-plus.global-config.db-config.logic-delete-value=1
#逻辑未删除的值
mybatis-plus.global-config.db-config.logic-not-delete-value=0

条件构造器

参考官网:https://mp.baomidou.com/guide/wrapper.html#abstractwrapper

代码生成器

//代码生成器,类为com.baomidou.mybatisplus.generator.AutoGenerator包下
AutoGenerator generator = new AutoGenerator();

//全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
//设置输出路径
gc.setOutputDir(projectPath+"/src/main/java");
gc.setAuthor("wutao");
//是否默认打开输出目录
gc.setOpen(false);
//去掉Service接口的首字母I
gc.setServiceName("%sService");
// gc.setSwagger2(true); 实体属性 Swagger2 注解
//将配置设置到代码生成器中
generator.setGlobalConfig(gc);

//数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://127.0.0.1:3306/mybatis-plus?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("root");
generator.setDataSource(dsc);

//包配置
PackageConfig pc = new PackageConfig();
//设置模块名
pc.setModuleName("demo");
//设置父包名目录
pc.setParent("com.wt");
//设置实体类包名
pc.setEntity("model");
//设置业务层接口包名
pc.setService("service");
//设置业务层实现类包名
pc.setServiceImpl("service.impl");
//设置控制层包名
pc.setController("controller");
//设置持久层接口包名
pc.setMapper("dao");
//设置mapper文件包名
pc.setXml("resources/mapper");
generator.setPackageInfo(pc);

//策略配置
StrategyConfig sc = new StrategyConfig();
//指定要映射的数据库表,可以写多个,多个表名用逗号隔开
sc.setInclude("user");
//设置下划线转驼峰命名
sc.setNaming(NamingStrategy.underline_to_camel);
//设置数据库列名规则,用下划线拼接
sc.setColumnNaming(NamingStrategy.underline_to_camel);
//设置是否生成lombok注解
sc.setEntityLombokModel(true);
//自动填充配置
TableFill create_time = new TableFill("create_time", FieldFill.INSERT);
TableFill update_time = new TableFill("update_time", FieldFill.INSERT_UPDATE);
ArrayList list = new ArrayList<>();
list.add(create_time);
list.add(update_time);
sc.setTableFillList(list);
//配置乐观锁
sc.setVersionFieldName("version");
sc.setRestControllerStyle(true);
//将策略配置设置到代码生成器中
generator.setStrategy(sc);

//执行
generator.execute();