【JAVA】MyBatisPlus 短命女 2024-04-06 09:22 39阅读 0赞 **目录** 【MyBatisPlus】 【SpringBoot整合MyBatisPlus】 【使用】 【标准数据层开发】 【标准数据层CRUD功能】 【MP分页查询功能】 【DQL编程控制】 【条件查询】 【查询投影】 【查询条件】 【字段映射与表名映射】 【DML编程控制】 【id生成策略控制】 【多记录操作】 【逻辑删除】 【乐观锁】 【使用】 【快速开发】 【代码生成器】 【模板】 -------------------- ## 【MyBatisPlus】 ## **【概述】** MyBatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提高效率 **【官网】** [MyBatis-Plus (baomidou.com)][MyBatis-Plus _baomidou.com] **【特性】** * 无侵入:只做增强不做改变,不会对现有工程产生影响 * 强大的 CRUD 操作:内置通用 Mapper,少量配置即可实现单表CRUD 操作 * 支持 Lambda:编写查询条件无需担心字段写错 * 支持主键自动生成 * 内置分页插件 ### 【SpringBoot整合MyBatisPlus】 ### #### 【使用】 #### 1、创建新模块,选择Spring初始化,并配置模块相关基础信息 ![1b3c10eae7ff4ce3b44dbc0bf190c36f.png][] 2、选择当前模块需要使用的技术(仅保留JDBC) ![5c85b2b927cf4d1a9393bf02edd6c0e8.png][] 3、手动添加MyBatisPlus坐标 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.1</version> </dependency> 4、设置Jdbc参数(application.yml) spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/db1?serverTimzone=UTC username: root password: root 5、制作实体类与数据源 public class User { private Long id; private String name; private String password; private Integer age; private String tel; } 6、定义数据接口,继承BaseMapper<User> @Mapper public interface UserDao extends BaseMapper<User> { } 7、测试类注入dao接口,测试功能 @SpringBootTest class Mybatisplus01DemoApplicationTests { @Autowired private UserDao userDao; @Test void contextLoads() { List<User> userList = userDao.selectList(null); System.out.println(userList); } } ### 【标准数据层开发】 ### #### 【标准数据层CRUD功能】 #### <table style="width:517px;"> <tbody> <tr> <td style="text-align:center;width:65px;"><strong>功能</strong></td> <td style="text-align:center;width:285px;"><strong>自定义接口</strong></td> <td style="text-align:center;width:166px;"><strong>MP接口</strong></td> </tr> <tr> <td style="text-align:center;width:65px;"><strong>新增</strong></td> <td style="text-align:center;width:285px;">boolean add(T t)</td> <td style="text-align:center;width:166px;">int insert(T t)</td> </tr> <tr> <td style="text-align:center;width:65px;"><strong>删除</strong></td> <td style="text-align:center;width:285px;">boolean delete(int id)</td> <td style="text-align:center;width:166px;">int deleteById(Serializable id)</td> </tr> <tr> <td style="text-align:center;width:65px;"><strong>修改</strong></td> <td style="text-align:center;width:285px;">boolean update(T t)</td> <td style="text-align:center;width:166px;">int updateById(T t)</td> </tr> <tr> <td style="text-align:center;width:65px;"><strong>根据id查询</strong></td> <td style="text-align:center;width:285px;">T getById(int id)</td> <td style="text-align:center;width:166px;">T selectById(Serializable id)</td> </tr> <tr> <td style="text-align:center;width:65px;"><strong>查询全部</strong></td> <td style="text-align:center;width:285px;">List<T> getAll( )</td> <td style="text-align:center;width:166px;">List<T> selectList</td> </tr> <tr> <td style="text-align:center;width:65px;"><strong>分页查询</strong></td> <td style="text-align:center;width:285px;">PageInfo<T> getAll(int page, int size)</td> <td style="text-align:center;width:166px;"><span style="color:#be191c;">IPage</span><T> selectPage(IPage<T> page)</td> </tr> <tr> <td style="text-align:center;width:65px;"><strong>按条件查询</strong></td> <td style="text-align:center;width:285px;">List<T> getAll(Codition condition)</td> <td style="text-align:center;width:166px;"><span style="color:#be191c;">IPage</span><T> selectPage(Wrapper<T> queryWrapper)</td> </tr> </tbody> </table> **【Lombok】** Lombok,一个Java类库,提供了一组注解,简化POJO实体类开发(坐标) <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> 或 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> <scope>provided</scope> </dependency> **【常用注解】:@Data** @Data public class User { private Long id; private String name; private String password; private Integer age; private String tel; } **【注意】** * 当前实体类在编译期设置对应的get/set方法,无参/无参构造方法,toString方法,hashCode方法,equals方法等 * @Data不包含构造方法 #### 【MP分页查询功能】 #### 1、设置分页拦截器作为Spring管理的bean @Configuration public class MpConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { //定义Mp拦截器 MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); //添加具体的拦截器 mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return mybatisPlusInterceptor; } } 2、执行分页查询 @Test void testGetByPage(){ IPage page=new Page(1,5); userDao.selectPage(page,null); System.out.println("当前页码值"+page.getCurrent()); System.out.println("每页显示数"+page.getSize()); System.out.println("一共多少页"+page.getPages()); System.out.println("一共多少条数据"+page.getTotal()); System.out.println("数据"+page.getRecords()); } **【开启日志】** #开启mp的日志(输出到控制台) mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl ### 【DQL编程控制】 ### #### 【条件查询】 #### MyBatisPlus将书写复杂的SQL查询条件进行了封装,使用编程的形式完成查询条件的组合 **【启用条件查询】** QueryWrapper<User> qw = new QueryWrapper<User>(); List<User> userList = userDao.selectList(null); System.out.println(userList); **【设置条件查询——常规链式格式】** QueryWrapper<User> qw = new QueryWrapper<User>();//查询年龄大于等于18岁,小于65岁的用户 qw.lt("age",65).ge("age",18); List<User> userList = userDao.selectList(qw); System.out.println(userList); **【设置条件查询——lambda表达式链式格式——组合查询条件】** LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>(); //10到13之间(and) lqw.lt(User::getAge, 13).gt(User::getAge, 10); //小于10,大于13(或者) lqw.lt(User::getAge, 10).or().gt(User::getAge, 13); List<User> userList = userDao.selectList(lqw); System.out.println(userList); **【null值处理——条件参数控制】** UserQuery uq=new UserQuery(); //null值判定 LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>(); lqw.lt(null!=uq.getAge2(), User::getAge, uq.getAge2()); lqw.gt(null!=uq.getAge(), User::getAge, uq.getAge()); List<User> userList = userDao.selectList(lqw); System.out.println(userList); #### 【查询投影】 #### * 查询结果包含模型类中部分属性 //查询结果包含模型类中部分属性 LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>(); lqw.select(User::getId, User::getName, User::getAge); List<User> userList = userDao.selectList(lqw); System.out.println(userList); * 查询结果包含模型中未定义的属性 //查询结果包含模型类中未定义的属性 QueryWrapper<User> qw = new QueryWrapper<User>(); qw.select("count(*) as count,tel"); qw.groupBy("tel"); List<Map<String, Object>> userList = userDao.selectMaps(qw); System.out.println(userList); #### 【查询条件】 #### * 范围匹配(> 、 = 、between) * 模糊匹配(like) * 空判定(null) * 包含性匹配(in) * 分组(group) * 排序(order) **【eq匹配】** LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>(); //等同于 lqw.eq(User::getName, "lisi").eq(User::getPassword, "123"); User LoginUser = userDao.selectOne(lqw); System.out.println(LoginUser); **【le ge匹配 或 between匹配】** LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>(); //范围查询 lt le gt ge eq between lqw.between(User::getAge,10,20); List<User> LoginUser = userDao.selectList(lqw); System.out.println(LoginUser); **【非全文检索:like】** LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>(); //模糊查询 lqw.like(User::getName,"z"); List<User> LoginUser = userDao.selectList(lqw); System.out.println(LoginUser); #### 【字段映射与表名映射】 #### 1、表字段与编码属性设计不同步 **【@TableField】** * 名称:@TableField * 类型:**属性注解** * 作用:设置当前属性对应的数据库表中的字段关系 * 属性: * value:设置数据库表字段名称 例: public class User { @TableField(value="pwd") private String password; } 2、编码中添加了数据库中未定义的属性 **【@TableField】** * 名称:@TableField * 类型:**属性注解** * 作用:设置当前属性对应的数据库表中的字段关系 * 属性: * exist:设置属性在数据库表字段中是否存在,默认为true,此属性无法与value合并使用 例: public class User { @TableField(exist = false) private Integer online; } 3、采用默认查询开放了更多的字段查看权限 **【@TableField】** * 名称:@TableField * 类型:**属性注解** * 作用:设置当前属性对应的数据库表中的字段关系 * 属性: * select:设置属性是否参与查询,此属性与select()映射配置不冲突 例: public class User { @TableField(value="pwd",select = false) private String password; } 4、表名与编码开发设计不同步 **【@TableName】** * 名称:@TableName * 类型:**类注解** * 作用:设置当前类对应与数据库表关系 * 属性: * value:设置数据库名称 例: @TableName("tbl_user") public class User { private Long id; } ### 【DML编程控制】 ### #### 【id生成策略控制】 #### * 名称:@TableId * 类型:**属性注解** * 位置:模型类中用于表示主键的属性定义上方 * 作用:设置当前类中主键属性的生成策略 * 属性: * value:设置数据库主键名称 * type:设置主键属性的生成策略,值参照IdType枚举值 例: public class User { @TableId(type = IdType.AUTO) private Long id; } **【生成策略类型】** * AUTO(0):使用数据库id自增策略控制id生成 * NONE(1):不设置id生成策略 * INPUT(2):用户手工输入id * ASSIGN\_ID(3):雪花算法生成id(可兼容数值型与字符串型) * ASSIGN\_UUID(4):以UUID生成算法作为id生成策略 **【id生成策略全局配置】** mybatis-plus: global-config: db-config: id-type: assign_id #自增策略 table-prefix: tb_ #表名的前缀 #### 【多记录操作】 #### * 按照主键删除多条记录 List<Long> ids= Arrays.asList(new Long[]{2,3}); userDao.deleteBatchIds(ids); * 按照主键查询多条记录 List<Long> ids= Arrays.asList(new Long[]{2,3}); List<User> userList = userDao.selectBatchIds(ids); #### 【逻辑删除】 #### **【概述】** 为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,数据保留在数据库中 **【使用】** 1、数据库表中添加逻辑删除标记字段(默认值设置为0 ) ![a2b78b8811014756b16f5fc5d147f241.png][] 2、实体类中添加对应字段,并设定当前字段为逻辑删除标记字段 public class User { private Long id; //逻辑删除字段 @TableLogic private Integer deleted; } **【注意】** 属性不能为delete 3、配置逻辑删除字面值 mybatis-plus: global-config: db-config: logic-delete-field: deleted logic-not-delete-value: 0 logic-delete-value: 1 ### 【乐观锁】 ### #### 【使用】 #### 1、数据库表中添加所标记字段 ![8f44b9c3286e45aaa18415d2b86933eb.png][] 2、实体类中添加对应字段,并设定当前字段为逻辑删除标记字段 public class User { private Long id; //乐观锁 @Version private Integer version; } 3、配置乐观锁拦截器实现锁机制对应的动态SQL语句拼装 @Configuration public class MpConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { //定义Mp拦截器 MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); //添加乐观锁拦截器 mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return mybatisPlusInterceptor; } } 4、使用乐观锁机制在修改前必须啊先获取到对应数据的version即可正常进行 @Test void testUpdate() { //多用户修改 User user = userDao.selectById(3L); User user2 = userDao.selectById(3L); user2.setName("zhangsan666"); userDao.updateById(user2); user.setName("zhangsan888"); userDao.updateById(user); } 执行修改前先执行查询语句 SELECT id,name,age,tel,deleted,version FROM tbl_user WHERE id=? 执行修改时使用version字段作为乐观锁检查依据 UPDATE tbl_user SET name=?, age=?, tel=?, version=? WHERE id=? AND version=? ## 【快速开发】 ## ### 【代码生成器】 ### #### 【模板】 #### MyBatisPlus提供 数据库相关配置:读取数据库获取信息 开发者自定义配置:手工配置 例: public class CodeGenerator { public static void main(String[] args) { //1.获取代码生成器的对象 AutoGenerator autoGenerator = new AutoGenerator(); //设置数据库相关配置 DataSourceConfig dataSource = new DataSourceConfig(); dataSource.setDriverName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/db1?serverTimezone=UTC"); dataSource.setUsername("root"); dataSource.setPassword("root"); autoGenerator.setDataSource(dataSource); //设置全局配置 GlobalConfig globalConfig = new GlobalConfig(); globalConfig.setOutputDir(System.getProperty("user.dir")+"/mybatisplus_04_generator/src/main/java"); //设置代码生成位置 globalConfig.setOpen(false); //设置生成完毕后是否打开生成代码所在的目录 globalConfig.setAuthor("黑马程序员"); //设置作者 globalConfig.setFileOverride(true); //设置是否覆盖原始生成的文件 globalConfig.setMapperName("%sDao"); //设置数据层接口名,%s为占位符,指代模块名称 globalConfig.setIdType(IdType.ASSIGN_ID); //设置Id生成策略 autoGenerator.setGlobalConfig(globalConfig); //设置包名相关配置 PackageConfig packageInfo = new PackageConfig(); packageInfo.setParent("com.example"); //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径 packageInfo.setEntity("domain"); //设置实体类包名 packageInfo.setMapper("dao"); //设置数据层包名 autoGenerator.setPackageInfo(packageInfo); //策略设置 StrategyConfig strategyConfig = new StrategyConfig(); strategyConfig.setInclude("mybatisplus_user"); //设置当前参与生成的表名,参数为可变参数 strategyConfig.setTablePrefix("mybatisplus_"); //设置数据库表的前缀名称,模块名 = 数据库表名 - 前缀名 例如: User = tbl_user - tbl_ strategyConfig.setRestControllerStyle(true); //设置是否启用Rest风格 strategyConfig.setVersionFieldName("version"); //设置乐观锁字段名 strategyConfig.setLogicDeleteFieldName("deleted"); //设置逻辑删除字段名 strategyConfig.setEntityLombokModel(true); //设置是否启用lombok autoGenerator.setStrategy(strategyConfig); //2.执行生成操作 autoGenerator.execute(); } } [MyBatis-Plus _baomidou.com]: https://baomidou.com/ [1b3c10eae7ff4ce3b44dbc0bf190c36f.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/06/bedbc273b48f4c2d9b17565ec5a7bb34.png [5c85b2b927cf4d1a9393bf02edd6c0e8.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/06/37cf70f5e7064d00a1eb2fa923c6b2c2.png [a2b78b8811014756b16f5fc5d147f241.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/06/adc813d01c404259bea839357ac3e5b0.png [8f44b9c3286e45aaa18415d2b86933eb.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/06/ea19cf496bb6432384062a24a926977a.png
还没有评论,来说两句吧...