3.2 空值判定
如果查询条件为空还出现在了Sql语句中,就会报错,要先使用null != __ 判断
(1)实体类和测试用例
@Data public class QueryUser extends User{ /** * 定义年龄范围的上限 */ private Integer ageGt; }
@Test public void testNull() { LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); QueryUser user = new QueryUser(); // user.setAge(18); // 设置年龄下限 user.setAgeGt(20); // 设置年龄上限 wrapper.gt(User::getAge,user.getAge()); wrapper.lt(User::getAge,user.getAgeGt()); mapper.selectList(wrapper); }
(2)运行结果
(3)解决方案-在查询之前加入条件判定再查看SQL语句
wrapper.gt(null != user.getAge(), User::getAge, user.getAge()); wrapper.lt(null != user.getAgeGt(), User::getAge, user.getAgeGt());
3.3 条件设置
条件 | 等于 | 范围 | 模糊 |
表达 | eq | lt,le,gt,ge,eq,between | like,likeLeft,likeRight(左右表示百分号的位置) |
通过查看官方文档了解更多查询条件的用法——MyBatis-Plus条件构造器官网链接。
举例:
@Test public void testSelectCon5() { LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); wrapper.between(User::getAge, 19, 25); // 查询age>=19 && age<=25的数据 mapper.selectList(wrapper); wrapper.like(User::getUsername, "s"); // %s% mapper.selectList(wrapper); wrapper.likeRight(User::getPassword, "ll"); // ll% }
3.4 字段映射匹配
情况 | 属性名和字段名不同 | 有些属性不在表中 | 有些字段不参与查询 | 实体类名和表名不同 |
映射@TableFiled | value = “字段名” | exist =false | select = false | @TableName(“”) |
/** * 用户名 */ @TableField("name") // 1.字段名为name private String username; /** * 密码 */ @TableField(select = false) // 3.不参与查询 private String password; /** * 在线状态 */ @TableField(exist = false) // 2.不存在 private Integer online;
四、DML
4.1 id生成策略
id生成策略 | Auto | Input | Assign |
使用 | 数据库定义一个id起始,然后+1 | 用户定义编写一个id | 用雪花算法生成一个Long值,默认策略 |
(1)自定义id自增
@Test public void testId() { User user =new User(); user.setUsername("DemoQ"); user.setPassword("WWER"); user.setAge(20); mapper.insert(user); // 插入一条记录并查看id }
(2)默认生成的Id
(3)自定义Id
@Test public void testId() { User user =new User(); user.setId(20L); user.setUsername("DemoQ"); user.setPassword("WWER"); user.setAge(20); mapper.insert(user); // 插入一条记录并查看id }
可以再yml文件中全局配置id生成策略,这样就不用写@TableId注解,配置表名前缀,不用写@TableName的前缀注解。
# mybatis-plus--banner: false mybatis-plus: global-config: banner: false db-config: id-type: assign_id # 使用默认的id生成策略 table-prefix: tb_ # 设置表名前缀,类名 = 表名-前缀 # 标准日志输出 configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
4.2 多数据操作
这里主要通过两个API,deleteBatchIds(),selectBatchIds()来讲解多数据操作。
@Test public void testMore() { List<Long> list = new ArrayList<>(); list.add(5L); list.add(6L); mapper.selectBatchIds(list); // 批量查询 } @Test public void testMoreDelete() { List<Long> list = new ArrayList<>(); list.add(20L); list.add(27L); mapper.deleteBatchIds(list); // 批量删除 }
4.3 逻辑删除
通过字段(通常叫deleted)标记数据是否可用,不是执行真的删除,而是执行修改。之后查询时,MyBatis-Plus的所有查询操作都只查询没有被逻辑删除的数据。
设置逻辑删除字段 | @TableLogic() | yml配置 |
执行删除操作之后再次查看表中数据:
4.4 乐观锁(update)
步骤:
(1)数据库表中添加version字段,用于标记版本
(2)实体类中添加相应的字段并添加@Version注解
(3)添加拦截器实现动态添加sql语句
@Configuration public class MpConfig { @Bean public MybatisPlusInterceptor interceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 分页拦截器 interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); // 乐观锁拦截器 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } }
(4)模拟乐观锁version自增+1(执行更新操作前必须提前告知version版本)
法一:设置版本
@Test public void testOptimisticLock() { User user = new User(); user.setId(5L); user.setAge(33); user.setVersion(1); mapper.updateById(user); }
法二:通过id得到版本
@Test public void testOptimisticLock2() { User user = mapper.selectById(6); user.setUsername("123"); mapper.updateById(user); }
五、代码生成器
模板+配置=代码生成器
(1)导入模板生成器和模板引擎坐标
<!-- 代码生成器--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.4.1</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.3</version> </dependency>
(2)配置数据库连接信息和其他配置
注意这里配置的数据库信息不是用于增删改查,而是用于创建实体类等。
public class CodeGenerator { public static void main(String[] args) { /** * 基础配置 */ AutoGenerator generator = new AutoGenerator(); DataSourceConfig config = new DataSourceConfig(); // 配置数据库连接相关信息 config.setDbType(DbType.MYSQL); config.setDriverName("com.mysql.cj.jdbc.Driver"); config.setUrl("jdbc:mysql://localhost:3306/mybatis-plus?useSSL=false"); config.setUsername("root"); config.setPassword("123456"); generator.setDataSource(config); /** * 设置全局配置 */ GlobalConfig globalConfig = new GlobalConfig(); globalConfig.setOutputDir(System.getProperty("user.dir") + "/src/main/java"); // 指定生成的代码模板目录 globalConfig.setAuthor("XiaoGuo"); // 设置作者 globalConfig.setOpen(false); // 设置生成代码后是否打开目录 globalConfig.setControllerName("%sController"); // 设置Controller文件名 globalConfig.setFileOverride(true); // 设置文件覆盖 globalConfig.setMapperName("%sMapper"); // 设置mapper层文件名 globalConfig.setIdType(IdType.ASSIGN_ID); // 设置ID生成策略 generator.setGlobalConfig(globalConfig); /** * 设置包名相关配置 */ PackageConfig packageConfig = new PackageConfig(); packageConfig.setParent("com.itxiaoguo"); // 设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径 generator.setPackageInfo(packageConfig); /** * 策略设置 */ StrategyConfig strategyConfig = new StrategyConfig(); strategyConfig.setInclude("tb_user"); // 设置要生成的表名,如果有多个,则叠加 strategyConfig.setTablePrefix("tb_"); // 设置表前缀名,生成的=表名-前缀 strategyConfig.setRestControllerStyle(true); // 生成的controller使用rest风格 strategyConfig.setEntityLombokModel(true); // 实体类使用Lombok注解 strategyConfig.setLogicDeleteFieldName("deleted"); // 设置逻辑删除字段名 strategyConfig.setVersionFieldName("version"); // 设置乐观锁字段名 generator.setStrategy(strategyConfig); /** * 执行生成操作 */ generator.execute(); } }
至此,MyBatis-Plus快速入门结束。