MyBatisPlus入门,crud扩展,主键生成策略,乐观锁,分页查询,条件构造器,代码自动生成器

    科技2026-02-23  8

    MyBatisPlus

    简介

    mybatisi - plus是MyBatis的一个强大的增强工具包,用于简化开发。这个工具包为MyBatis提供了一些高效、有用、开箱即用的特性,使用它可以有效地节省您的开发时间。

    可以简化CRUD代码

    特性

    无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作。BaseMapper强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求,不用编写简单的CRUD支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用,自动生成代码内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

    快速入门

    导入依赖

    <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatisplus-spring-boot-starter</artifactId> <version>2.1.9</version> </dependency>

    实体类

    @Data public class User { private Integer id; private String name; private Integer age; private String email; }

    Mapper

    @Repository @Mapper public interface UserMapper extends BaseMapper<User> { }

    测试

    @Autowired private UserMapper userMapper; @Test void contextLoads() { List<User> users = userMapper.selectList(null); for (User user : users) { System.out.println(user); } }

    配置日志

    希望了解sql执行

    mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #使用默认的控制台输出

    CRUD扩展

    Insert

    @Test void test2() { userMapper.insert(new User(7,"lyc",32,"2333@qq.com")); contextLoads(); }

    发现并没有问题

    如果不插入id数字

    @Test void test2() { User user = new User(); user.setAge(33); user.setEmail("2333@33.com"); user.setName("lyc2"); userMapper.insert(user); contextLoads(); } }

    mybatis-plus会自动插入一个id

    update

    void test3(){ User lyc = new User((long) 2, "lyc", 33, "2333@qq.com"); //通过条件自动拼接sql //所有的sql都是动态配置 userMapper.updateById(lyc); contextLoads(); }

    自动填充(自动化更改)

    创建时间,修改时间

    gmt_create,gmt_modified

    数据库级别

    ALTER TABLE user ADD COLUMN `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER email, ADD COLUMN `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP AFTER `create_time`;

    更新的时候会自动更改update_time

    代码级别插入

    @TableField(fill = FieldFill.INSERT) private Date createTime; @TableField(fill = FieldFill.UPDATE) private Date updateTime;

    编写自动填充器

    @Slf4j @Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { log.info("start fill"); this.setFieldValByName("createTime",new Date(),metaObject); this.setFieldValByName("updateTime",new Date(),metaObject); } @Override public void updateFill(MetaObject metaObject) { log.info("update fill"); this.setFieldValByName("updateTime",new Date(),metaObject); } }

    逻辑删除

    通过一个字段让它失效,delete=1

    @TableLogic 字段注解

    本质上执行update操作

    查询的时候过滤掉delete字段等于1的字段

    application.yaml

    mybatis-plus: global-config: db-config: logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2) logic-delete-value: 1 # 逻辑已删除值(默认为 1) logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

    主键生成策略

    uuid,自增id,雪花算法,redis生成

    雪花算法

    SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。在分布式系统中的应用十分广泛,且ID 引入了时间戳,基本上保持自增。

    这 64 个 bit 中,其中 1 个 bit 是不用的,然后用其中的 41 bit 作为毫秒数,用 10 bit 作为工作机器 id,12 bit 作为序列号。

    第一个部分,是 1 个 bit:0,这个是无意义的。第二个部分是 41 个 bit:表示的是时间戳。第三个部分是 5 个 bit:表示的是机房 id,10001。第四个部分是 5 个 bit:表示的是机器 id,1 1001。第五个部分是 12 个 bit:表示的序号,就是某个机房某台机器上这一毫秒内同时生成的 id 的序号,0000 00000000。

    SnowFlake算法的优点: (1)高性能高可用:生成时不依赖于数据库,完全在内存中生成。

    (2)容量大:每秒中能生成数百万的自增ID。

    (3)ID自增:存入数据库中,索引效率高。

    SnowFlake算法的缺点:

    依赖与系统时间的一致性,如果系统时间被回调,或者改变,可能会造成id冲突或者重复。

    数据库插入的id是数据库唯一的id

    @TableId(type = IdType.AUTO) private Long id;

    乐观锁

    定义

    意图:

    当要更新一条记录的时候,希望这条记录没有被别人更新

    乐观锁总是认为不会出现问题,无论干什么都不去上锁,如果出现了问题,再次更新值测试

    悲观锁:无论干什么都会出现问题,无论干什么都会上锁再去操作

    实现方式

    取出记录时,获取当前version

    更新时,带上这个version

    执行更新时, set version = newVersion where version = oldVersion

    如果version不对,就更新失败

    @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } update user set name="lyc", version = version +1 where id=2 and version =1; --如果其他线程修改了 version版本发生改变,导致这个线程修改失败,保证了线程的安全

    测试

    void test3(){ User lyc=userMapper.selectById(5l); lyc.setId((long) 5); lyc.setName("xhc332"); if (userMapper.updateById(lyc)>0){ System.out.println("success"); }else { System.out.println("failure"); }; }

    分页查询

    @Configuration @MapperScan("scan.your.mapper.package") public class MybatisPlusConfig { /** * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除) */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2)); return interceptor; } @Bean public ConfigurationCustomizer configurationCustomizer() { return configuration -> configuration.setUseDeprecatedExecutor(false); } }

    测试

    @Test void test4(){ //当前页 页面大小 Page<User> page = new Page<>(1, 5); userMapper.selectPage(page, null); for (User record : page.getRecords()) { System.out.println(record); } }

    条件构造器

    一些复杂的sql可以使用它可以替代

    例:查询name不为空且邮箱不为空,且年龄大于等于12的用户

    @Test void test1(){ //查询name不为空且邮箱不为空,且年龄大于等于12的用户 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.isNotNull("name") .isNotNull("email") .ge("age",12); userMapper.selectList(wrapper).forEach(System.out::println); }

    实际拼接的sql语句

    @Test void test2(){ //名字等于lyc userMapper.selectList(new QueryWrapper<User>().eq("name","lyc")); }

    具体的wrapper可以查看

    https://baomidou.com/guide/wrapper.html#abstractwrapper

    代码自动生成器

    AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

    导入依赖

    <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.4.0</version> </dependency>

    模板引擎

    <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.2</version> </dependency> public class LycCode { public static void main(String[] args) { //构建代码自动生成器对象 AutoGenerator mpg = new AutoGenerator(); //配置策略 //1. 全局配置 GlobalConfig gc = new GlobalConfig(); //获取当前项目目录 String projectPath = System.getProperty("user.dir"); //输出目录 gc.setOutputDir(projectPath+"/src/main/java"); //设置作者 gc.setAuthor("lyc"); //设置swagger2 实体属性注解 gc.setSwagger2(true); //不打开资源管理器 gc.setOpen(false); //不覆盖原来代码 gc.setFileOverride(false); //去除service层前的i gc.setServiceName("%sService"); //主键策略 gc.setIdType(IdType.ID_WORKER); //设置日期类型 gc.setDateType(DateType.ONLY_DATE); //代码构造器设置全局配置 mpg.setGlobalConfig(gc); //2.数据源配置 DataSourceConfig dsc = new DataSourceConfig(); //设置密码 dsc.setPassword("123456"); //设置数据库类型 dsc.setDbType(DbType.MYSQL); //设置连接数据库的url dsc.setUrl(""); //设置驱动的名字 dsc.setDriverName("com.mysql.jdbc.Driver"); //设置用户名 dsc.setUsername("lyc"); //代码构造器设置数据源配置 mpg.setDataSource(dsc); //3.包配置 PackageConfig pc = new PackageConfig(); // pc.setModuleName("blog"); pc.setParent("com.lyc"); mpg.setPackageInfo(pc); //4.策略配置 StrategyConfig strategy = new StrategyConfig(); strategy.setNaming(NamingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!"); //是否启用lombok插件 strategy.setEntityLombokModel(true); //驼峰命名 strategy.setRestControllerStyle(true); //逻辑删除字段 strategy.setLogicDeleteFieldName(); // 公共父类 strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!"); // 写于父类中的公共字段 strategy.setSuperEntityColumns("id"); strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));//设置映射的表 strategy.setControllerMappingHyphenStyle(true); strategy.setTablePrefix(pc.getModuleName() + "_"); mpg.setStrategy(strategy); mpg.setTemplateEngine(new FreemarkerTemplateEngine()); //自动填充字段 TableFill tableFill = new TableFill("gmt_create", FieldFill.INSERT); strategy.setTableFillList(); mpg.setStrategy(strategy); //执行代码构造 mpg.execute(); } }
    Processed: 0.013, SQL: 9