0


springboot 整合 mybatis-plus

一.前言

  1. 1. mybatis-plus是什么
  2. mybatis-plus是一个对mybati框架的拓展框架,它在mybatis框架基础上做了许多的增强,帮助我们快速的进行代码开发。目前企业开发中,使用mybati的项目基本会选择使用mybatis-plus来提升开发效率。
  3. 2.官网地址:MyBatis-Plus 🚀 为简化开发而生

二.项目集成

  1. 1. 项目中集成(示例用的springboot2.x+mysql)
  2. step1.引入依赖
  1. <dependency>
  2. <groupId>com.baomidou</groupId>
  3. <artifactId>mybatis-plus-boot-starter</artifactId>
  4. <version>3.5.7</version>
  5. </dependency>
  1. step2.配置数据源
  1. spring:
  2. datasource:
  3. driver-class-name: com.mysql.cj.jdbc.Driver
  4. url: jdbc:mysql://192.168.**.**:3306/rui
  5. username: root
  6. password: ******
  1. step3.启动类添加注解 @MapperScan 指向mapper接口所在包
  1. @SpringBootApplication
  2. @MapperScan("com.rui.mapper")
  3. @EnableFeignClients(defaultConfiguration = MyFeignConfiguration.class)
  4. public class AdminServerApplication {
  5. public static void main(String[] args) {
  6. SpringApplication.run(AdminServerApplication.class, args);
  7. }
  8. }
  1. step4.定义实体类

  1. step5.编码测试:

(编码测试演示比较接近实际开发的代码,如果只是简单验证,用baseMapper就行了)

以下代码均为mybatis-plus提供的代码生成器生成的,如何使用在后续段落会讲,这里先看一下代码样子,眼熟以下

代码结构:

controller层:

  1. @Slf4j
  2. @RestController
  3. @RequestMapping("/configInfo")
  4. public class ConfigInfoController {
  5. @Autowired
  6. private IConfigInfoService configInfoService;
  7. @GetMapping("/list")
  8. public List<ConfigInfo> listConfigs () {
  9. return configInfoService.list();
  10. }
  11. }

service层:

  1. interface
  1. public interface IConfigInfoService extends IService<ConfigInfo> {
  2. }
  1. impl:

** 注意,这里继承了一个ServiceImpl 它是mybatis-plus提供的类,帮我们完成许DB操作**

  1. @Service
  2. public class ConfigInfoServiceImpl extends ServiceImpl<ConfigInfoMapper, ConfigInfo> implements IConfigInfoService {
  3. }

mapper层:

  1. mapper接口:

** 注意,我们的mapper实现了 BaseMapper ,它是mybatis-plus提供的接口,有常用的CRUD**

  1. public interface ConfigInfoMapper extends BaseMapper<ConfigInfo> {
  2. }
  1. mapper.xml: (其实就是空的,如果后面开始有自定义sql,需要这里写)
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.rui.mapper.ConfigInfoMapper">
  4. </mapper>
  1. 以上操作结束后,启动项目,postMan访问接口,发现可以正常访问数据库:

在测试环节,大家可以发现我的service和mapper都是空的,但是却可以调用list方法访问数据库。

其实,上面的编码中,我们在自己的业务Service中继承了抽象类ServiceImpl,ServiceImpl实现了IService这个接口中的方法,并定义了四个成员变量 baseMapper,entityClass, mapperClass,log,且这四个成员变量都是protected的,因此,在我们的业务Service中,我们可以直接调用IService的方法诸如saveAndUpdate,list,page等,也可以通过this.baseMapper 的方式来获取baseMapper对象,来调用baseMapper的方法

三.使用技巧

1.理解mybatis-plus在代码中做的事情

  1. mybatis-plus为我们提供的**最核心的功能其实就是对MybatisMapper接口的增强**,它**提供了一个BaseMapper**,一个mybatis的**mapper接口继承了BaseMapper的话,就会被mybatis-plus进行增强,实现一系列的常用的数据库操**。使用mybatis-plus最简单的办法其实就是引入mybatis-plus的依赖后,定义好Entity对象(实体对象),然后让mapper继承BaseMapper,最终我们使用baseMaper中的方法来进行开发。
  2. 看一个使用baseMapper的例子:
  3. todo
  4. 但是直接使用baseMaper的话,有许多操作我们还需要自己写代码,比如一些批量操作,如batchSave(批量插入)等。所以,mybatis-plus还提供了ServiceImpl,来帮我们实现这些。
  5. 上面的编码中,我们在自己的业务Service中继承了抽象类ServiceImplServiceImpl实现了IService这个接口中的方法,并定义了四个成员变量 baseMapperentityClass mapperClasslog,且这四个成员变量都是protected的,因此,在我们的业务Service中,我们可以直接调用IService的方法诸如saveAndUpdatelistpage等,也可以通过this.baseMapper 的方式来获取baseMapper对象,来调用baseMapper的方法。

2.使用QueryWrapper进行查询

  1. 以该service为例:![](https://img-blog.csdnimg.cn/direct/d08e307ac06e4882814576f3ac23b805.png)
  2. QueryWrapper是我们工作中每天都啊哟使用的,场景非常多,我列出一些常见的场景,方便大家查阅

1.1. 新增

  1. ConfigInfo configInfo = mockData();
  2. this.baseMapper.insert(configInfo);

1.2. 删除

  1. LambdaQueryWrapper<ConfigInfo> configInfoQueryWrapper = new LambdaQueryWrapper<>();
  2. configInfoQueryWrapper.eq(ConfigInfo::getId, 500L);
  3. this.baseMapper.delete(configInfoQueryWrapper);

1.3. 修改

  1. // 方法1 根据id更新,直接传入对象
  2. ConfigInfo configInfo = mockData();
  3. this.baseMapper.updateById(configInfo);
  4. //方法2 使用wrapper更新 set代表要修改的字段 eq是条件为相等的isi
  5. UpdateWrapper<ConfigInfo> configInfoUpdateWrapper = Wrappers.update();
  6. configInfoUpdateWrapper.set("appName","chengxuyuanA");
  7. configInfoUpdateWrapper.set("groupId", "groupA");
  8. configInfoUpdateWrapper.eq("id", 500L);
  9. this.baseMapper.update(configInfoUpdateWrapper);

1.4. 查询

  1. 列表查询
  2. 简单查询(简单的条件查询)
  1. // 查润groupId 为 5001的数据
  2. LambdaQueryWrapper<ConfigInfo> configInfoQueryWrapper = new LambdaQueryWrapper<>();
  3. configInfoQueryWrapper.eq(ConfigInfo::getGroupId, "5001");
  4. List<ConfigInfo> res = this.baseMapper.selectList(configInfoQueryWrapper);
  1. 复杂查询 (场景太多了,我就用一个包含 and or in between order by sql来表示一下用法)
  1. // select *
  2. // from config_info
  3. // where app_name like '%app%'
  4. // and id between 1 and 50
  5. // or (src_ip in ('1.0.1.1', '196.123.1.1', '0.0.0.0') and effect is not null)
  6. LambdaQueryWrapper<ConfigInfo> configInfoQueryWrapper = new LambdaQueryWrapper<>();
  7. configInfoQueryWrapper.like(ConfigInfo::getAppName, "app")
  8. .between(ConfigInfo::getId, 1, 50);
  9. configInfoQueryWrapper.or(w->w.in(ConfigInfo::getSrcIp,srcips).isNotNull(ConfigInfo::getEffect));
  1. 分组聚合(其实这个一般不会用,考虑性能和优化,聚合的东西一般自己写sql
  1. LambdaQueryWrapper<ConfigInfo> configInfoQueryWrapper = new LambdaQueryWrapper<>();
  2. configInfoQueryWrapper.groupBy(ConfigInfo::getGroupId);
  3. Long res = this.baseMapper.selectCount(configInfoQueryWrapper);
  1. 分页查询
  1. Page page = new Page();
  2. page.setCurrent(1);
  3. page.setSize(10);
  4. LambdaQueryWrapper<ConfigInfo> configInfoQueryWrapper = new LambdaQueryWrapper<>();
  5. configInfoQueryWrapper.eq(ConfigInfo::getGroupId, "5001");
  6. IPage<ConfigInfo> pageData = this.page(page, configInfoQueryWrapper);

3.自定义sql查询

  1. 3.1.使用自定义sql
  2. 和使用mybatis完全一样,这里不赘述了
  3. 3.2.对自定义sql分页
  4. interface
  1. IPage<ConfigRation> selectUserPage(Page page, @Param("configration") ConfigRation configrationVo);
  1. mybatis的正常使用,但是在第一个参数加上一个Page入参

4.字段映射及一些注解使用技巧

普通映射
  1. 默认不需要注解,只要把数据库的字段的_去掉,换成小驼峰就行了
  2. 如果需要对象属性名和数据库字段名称不同,可以用如下注解:
  1. @TableField(value = "data_Source")
  2. private String dataType;
  1. java对象的属性在数据库中不存在
  1. @TableField(exist = false)
  2. @Schema(description = "是否绑定告警通知规则,true是。false否")
  3. private Boolean isBindNoticeRule;
枚举映射

枚举注解@EnumValue,需要在枚举对象和java的实体类上都加:

  1. public enum GenderEnum {
  2. MALE(0, "男"),
  3. FEMALE(1, "女");
  4. @EnumValue
  5. private final int code;
  6. private final String desc;
  7. GenderEnum(int code, String desc) {
  8. this.code = code;
  9. this.desc = desc;
  10. }
  11. }
  1. @TableName("user")
  2. public class User {
  3. @TableId
  4. private Long id;
  5. @TableField("gender")
  6. @EnumValue
  7. private GenderEnum gender;
  8. // 省略其他属性和方法
  9. }
逻辑删除注解

逻辑删除需要进行一些配置:

step1:增加配置

  1. mybatis-plus:
  2. global-config:
  3. db-config:
  4. logic-delete-field: deleted # 全局逻辑删除字段名
  5. logic-delete-value: 1 # 逻辑已删除值
  6. logic-not-delete-value: 0 # 逻辑未删除值

step2:在实体类中使用

  1. @TableLogic

注解

  1. public class User {
  2. // 其他字段...
  3. @TableLogic
  4. private Integer deleted;
  5. }
多数据源注解

多数据源支持需要一个包 dynamic-datasource

step1:maven增加依赖

  1. <dependency>
  2. <groupId>com.baomidou</groupId>
  3. <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
  4. <version>${version}</version>
  5. </dependency>

step2:数据源配置:

  1. spring:
  2. datasource:
  3. dynamic:
  4. primary: master
  5. strict: false
  6. datasource:
  7. master:
  8. url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
  9. username: root
  10. password: 123456
  11. driver-class-name: com.mysql.jdbc.Driver
  12. slave_1:
  13. url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
  14. username: root
  15. password: 123456
  16. driver-class-name: com.mysql.jdbc.Driver
  17. slave_2:
  18. url: ENC(xxxxx)
  19. username: ENC(xxxxx)
  20. password: ENC(xxxxx)
  21. driver-class-name: com.mysql.jdbc.Driver

step3:**使用

  1. @DS

切换数据源**

  1. @Service
  2. @DS("slave")
  3. public class UserServiceImpl implements UserService {
  4. @Autowired
  5. private JdbcTemplate jdbcTemplate;
  6. @Override
  7. @DS("slave_1")
  8. public List selectByCondition() {
  9. return jdbcTemplate.queryForList("select * from user where age >10");
  10. }
  11. }
字段忽略注解
  1. @TableField(exist = false)
  2. private String companyname;

四.常用插件

1.插件介绍

  1. 介绍两个插件DataPermissionInterceptor PaginationInnerInterceptor
  2. DataPermissionInterceptor
  3. 我们在开发中,很多项目有多租户,多组织的需求,不同租户和组织能看到的数据内容不同。假如业务数据我们用一个字段tenent_id区分不同租户的数据,那么我们希望开发者在编码时候,不需要刻意关注这个字段,正常写业务逻辑就好,有一个统一的拦截器能帮助我们在调用数据库时候把 tenent_id = {user_tenent_id} 这段sql加到查询语句中,DataPermissionInterceptor就是帮我们做这个事情的。
  4. 实际开发中,基本涉及到多组织,多租户的项目都会使用这个插件。如果大家在开发中发现使用了mybatis-plus的项目默认拼接了一些sql,可以尝试搜索DataPermissionInterceptor来找一下加的地方。
  5. PaginationInnerInterceptor
  6. 分页插件, 对于单一数据库类型来说,都建议配置该值,避免每次分页都去抓取数据库类型,使用方法很简单,直接new PaginationInnerInterceptor(dataType就好)

2.实战使用

step1: 注册拦截器,加入了上面介绍的俩插件

  1. @Configuration
  2. public class MybatisAutoConfiguration implements WebMvcConfigurer {
  3. @Bean
  4. public MybatisPlusInterceptor mybatisPlusInterceptor(@Autowired(required = false) DataPermissionHandler dataPermissionHandler) {
  5. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  6. if (dataPermissionHandler != null) {
  7. interceptor.addInnerInterceptor(new DataPermissionInterceptor(dataPermissionHandler));
  8. }
  9. interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL));
  10. return interceptor;
  11. }
  12. }

step2:DataPermissionHandler编码

  1. public class DataPermissionHandler extends MultiDataPermissionHandler {
  2. @Override
  3. public Expression getSqlSegment(Table table, Expression where, String mappedStatementId) {
  4. // 在此处编写自定义数据权限逻辑
  5. try {
  6. String sqlSegment = "..."; // 数据权限相关的 SQL 片段
  7. return CCJSqlParserUtil.parseCondExpression(sqlSegment);
  8. } catch (JSQLParserException e) {
  9. e.printStackTrace();
  10. return null;
  11. }
  12. }
  13. }

五.使用代码生成器

关于代码生成器

  1. 代码生成器在工作中其实很常用,所以我觉得不了解的道友还是需要了解一下。

1.代码生成器配置

  1. 我使用的mybatis-plus3.5.7,低于3.5版本的话,可能略有不同
  2. step1:引入两个依赖包:
  1. <dependency>
  2. <groupId>com.baomidou</groupId>
  3. <artifactId>mybatis-plus-generator</artifactId>
  4. <version>3.5.7</version>
  5. </dependency>
  6. <!-- freemarker模板 -->
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-freemarker</artifactId>
  10. <version>3.1.2</version>
  11. </dependency>
  1. step2:创建一个java类,用来生成代码,我一般喜欢在项目中建一个dev文件夹,放一些开发工具
  2. 结构如图:![](https://img-blog.csdnimg.cn/direct/b8d459469dd54681b4a8413c97f276e3.png)

代码:

  1. public class CodeGenerator {
  2. public static void main(String[] args) {
  3. FastAutoGenerator.create("jdbc:mysql://192.168.**.**:3306/rui",
  4. "root",
  5. "******")
  6. .globalConfig(builder -> builder
  7. .author("rui")
  8. .outputDir(Paths.get(System.getProperty("user.dir")) +
  9. "/services/admin-server" +
  10. "/src/main/java")
  11. .commentDate("yyyy-MM-dd")
  12. )
  13. .packageConfig(builder -> builder
  14. .parent("com.rui")
  15. .entity("entity")
  16. .mapper("mapper")
  17. .service("service")
  18. .serviceImpl("service.impl")
  19. .xml("mapper.xml")
  20. )
  21. .strategyConfig(builder -> builder
  22. // 要生成代码的表名称,不加下面这行就是全库生成
  23. .addInclude("config_info")
  24. .entityBuilder()
  25. .enableLombok()
  26. )
  27. .templateEngine(new FreemarkerTemplateEngine())
  28. .execute();
  29. }
  30. }

2.代码生成器使用

  1. 直接右键执行即可,执行后就会在项目中生成对应文件。默认的模板controllerservice中是没有方法的,可以自己配置一下模板,放一些和前端交互的CRUD

本文转载自: https://blog.csdn.net/jike920203/article/details/139981337
版权归原作者 普通程序员A 所有, 如有侵权,请联系我们删除。

“springboot 整合 mybatis-plus”的评论:

还没有评论