Mybatis-Plus学习笔记

    科技2022-08-18  110

                                            Mybatis-Plus学习笔记

    特性:

    无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

    环境搭建所需要的依赖:

    <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> </dependencies>

    然后在spring boot配置文件中配置好数据源以及mybatis-plus配置:

    如:

    mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

    注意:导入mybatis-Plus后不要在导入任何的mybatis以来了

    应用:

        创建与数据库表中相对性的JavaBean实体对象,如果表中字段带有下划线例如user_name,对象属性以驼峰形式来接,mybatis-plus,会自动进行匹配。

        编写对应的mapper接口,要继承BaseMapper<T>,这个类中已经实现了我们常用的CRUD操作,只调用即可,而且也不用再写相对应的对象Mapper.xml了,Sql语句我们也不用管理了,下面是BaseMapper<T>中一些方法的使用:

    1.测试查询:

    @Test public void selectTest(){ List<User> users = userMapper.selectList(null); users.forEach(System.out::println); } //查询案例:查询批量用户 @Test public void testSelectBatchIds(){ List<User> users = userMapper.selectBatchIds(Arrays.asList(21, 22, 23)); users.forEach(System.out::println); } //查询案例:按条件查询 @Test public void testSelectBatchId(){ HashMap<String, Object> map = new HashMap<>(); map.put("name", "熊大"); map.put("age", 16); List<User> users = userMapper.selectByMap(map); users.forEach(System.out::println); } //分页查询 @Test public void testPaginationInterceptor(){ Page<User> page = new Page<>(1,2); userMapper.selectPage(page, null); System.out.println(page.getTotal()); page.getRecords().forEach(System.out::println); } //查询案例:查询批量用户 @Test public void testSelectBatchIds(){ List<User> users = userMapper.selectBatchIds(Arrays.asList(21, 22, 23)); users.forEach(System.out::println); } 注意再分页查询的时候,需要配置一个分页查询组件,一般会专门编写一个配置类来管理mybatis=plus所需要的组件: @Bean//分页组件 public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false // paginationInterceptor.setOverflow(false); // 设置最大单页限制数量,默认 500 条,-1 不受限制 // paginationInterceptor.setLimit(500); // 开启 count 的 join 优化,只针对部分 left join paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true)); return paginationInterceptor; }

    2.测试插入;

    @Test public void insertTest(){ User user = new User(); user.setAge(16); user.setName("小明"); user.setEmail("13029228@qq.com"); int insert = userMapper.insert(user); System.out.println(insert); }

    3 .测试更新:需要添加乐观锁插件

    意图:

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

    乐观锁实现方式:

    取出记录时,获取当前version更新时,带上这个version执行更新时, set version = newVersion where version = oldVersion如果version不对,就更新失败

    乐观锁配置需要2步 记得两步

    插件配置

    1spring boot:

    @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); }

    2.注解实体字段 @Version 必须要!

    @Version private Integer version;

    特别说明:

    支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime整数类型下 newVersion = oldVersion + 1newVersion 会回写到 entity 中仅支持 updateById(id) 与 update(entity, wrapper) 方法在 update(entity, wrapper) 方法下, wrapper 不能复用!!! int id = 100; int version = 2; User u = new User(); u.setId(id); u.setVersion(version); u.setXXX(xxx); if(userService.updateById(u)){ System.out.println("Update successfully"); }else{ System.out.println("Update failed due to modified by others"); }

    示例SQL原理

    update tbl_user set name = 'update',version = 3 where id = 100 and version = 2

    4.删除(逻辑删除)

    说明:

    只对自动注入的sql起效:

    插入: 不作限制查找: 追加where条件过滤掉已删除数据,且使用 wrapper.entity 生成的where条件会忽略该字段更新: 追加where条件防止更新到已删除数据,且使用 wrapper.entity 生成的where条件会忽略该字段删除: 转变为 更新

    例如:

    删除: update user set deleted=1 where id = 1 and deleted=0查找: select id,name,deleted from user where deleted=0

    字段类型支持说明:

    支持所有数据类型(推荐使用 Integer,Boolean,LocalDateTime)如果数据库字段使用datetime,逻辑未删除值和已删除值支持配置为字符串null,另一个值支持配置为函数来获取值如now()

    附录:

    逻辑删除是为了方便数据恢复和保护数据本身价值等等的一种方案,但实际就是删除。如果你需要频繁查出来看就不应使用逻辑删除,而是以一个状态去表示。

    用法:

    步骤1: 配置com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig

    例: application.yml 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)

    步骤2: 实体类字段上加上@TableLogic注解

    @TableLogic private Integer deleted;

    另外;

    QueryWrapper<User> wrapper = new QueryWrapper<>();能够对查询条件做一些筛选

    用法:

    //条件查询 @Test void contextLoads() { //查询name不为空并且邮箱也不为空,而且年龄大于等于10 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.isNotNull("name") .isNotNull("email"); wrapper.between("age", 12, 22); List<User> users = userMapper.selectList(wrapper); users.forEach(System.out::println); } //模糊查询 @Test void test(){ QueryWrapper<User> wrapper = new QueryWrapper<>(); //LikeRight 表示%在右边 wrapper.notLike("name", "熊") //%熊% .likeRight("age", 1);//1% List<Map<String, Object>> maps = userMapper.selectMaps(wrapper); maps.forEach(System.out::println); } /** * ==> Preparing: SELECT id,name,age,email,create_time,update_time,version,deleted FROM user WHERE deleted=0 AND (name NOT LIKE ? AND age LIKE ?) * ==> Parameters: %熊%(String), 1%(String) * <== Columns: id, name, age, email, create_time, update_time, version, deleted * <== Row: 23, 翠花, 16, 17029228@qq.com, 2020-10-05 11:03:03, 2020-10-05 14:27:40, 1, 0 * <== Row: 24, 小明, 16, 13029228@qq.com, 2020-10-05 11:04:16, 2020-10-05 11:04:16, 1, 0 * <== Row: 29, 小李, 15, , 2020-10-05 15:33:14, 2020-10-05 15:33:19, 1, 0 * <== Total: 3 */ //子查询 @Test void test1(){ QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.inSql("id","select id from user where id>17"); List<Object> objects = userMapper.selectObjs(wrapper); objects.forEach(System.out::println); }

     

     

    Processed: 0.024, SQL: 9