您现在的位置是:首页 >技术杂谈 >Spring Boot + Mybtis-plus集成网站首页技术杂谈

Spring Boot + Mybtis-plus集成

刘凌枫羽 2024-06-17 11:27:04
简介Spring Boot + Mybtis-plus集成


需求分析

Spring Boot和MyBatis-Plus是目前使用最广泛的Java web开发框架和ORM框架,它们可以很好地协同工作,提供高效和稳定的系统开发和数据操作。以下是对Spring Boot + MyBatis-Plus集成需求分析的一个概述

  1. 配置文件:
    首先需要在Spring Boot的启动文件中,配置MyBatis-Plus相关的配置,以及数据库连接信息、驱动等。MyBatis-Plus在Spring Boot的启动文件中可以通过注解或者XML文件进行配置。
  2. 定义实体类:
    需要定义Java实体类,其字段对应数据库表的字段。可以使用注解的方式定义类和字段与数据库表和字段的对应关系。
  3. 定义Mapper类和XML文件:
    使用MyBatis-Plus的Mapper类,定义DAO层的CRUD操作。可以使用MyBatis-Plus提供的通用Mapper类,简化Mapper类的开发。同时,需要定义Mapper类对应的XML文件,与Mapper类一一对应和映射。
  4. 配置分页和缓存:
    需要对分页和缓存进行配置。可以使用MyBatis-Plus提供的分页插件和缓存插件,对分页和缓存进行管理和优化。
  5. 配置事务:

在操作数据库时需要开启事务支持,以保证数据的完整性和一致性。可以在Spring Boot的启动文件中配置事务管理器,操作DAO层的每个方法都会被包裹在一个事务中,以保证事务的一致性。

通过对以上需求的分析和处理,可以高效、快速地开发出高质量和可靠性的系统。同时,MyBatis-Plus可以提供ORM框架的中间件的支持,简化了数据操作和管理的复杂性。

Maven 相关依赖

主要引入了如下依赖:

  1. mybatis-plus-boot-starter依赖
  2. mybatis-plus-generator依赖
  3. freemarker依赖
  4. mysql-connector-java依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

配置文件

主要配置如下:

  1. 配置mybatisplus日志
  2. 配置数据库
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl #mybatis日志配置
spring:
  datasource: #配置数据库
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        master:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://127.0.0.1:3306/数据库名称?useUnicode=true&useSSL=false&characterEncoding=utf8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&autoReconnect=true&failOverReadOnly=false
          username: root
          password: 123456

相关流程

MybatisPlus配置

主要做了如下操作:

  1. 通过@MapperScan注解声明扫描路径
  2. 注入自定义配置Bean
    1. 添加租户配置
      1. 重写获取租户方法
      2. 重写忽略租户方法
    2. 分页插件配置
    3. 数据库类型配置
    4. 分页溢出处理
    5. 乐观锁
@Configuration
@MapperScan("com.llfy.saapp.page.*.mapper")
public class MybatisPlusConfig {

    /**
     * MybatisPlus配置
     * @return MybatisPlusInterceptor
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
            @Override
            public Expression getTenantId() {
                return new StringValue(Objects.requireNonNull(SecurityContextUtils.getTenantId()));
            }

            @Override
            public boolean ignoreTable(String tableName) {
                return Arrays.stream(IgnoreTableList.getIgnoreTableList())
                        .collect(Collectors.toList()).contains(tableName);
            }
        }));
        //分页插件
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        //数据库类型
        paginationInnerInterceptor.setDbType(DbType.MYSQL);
        //分页溢出处理
        paginationInnerInterceptor.setOverflow(true);
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        //乐观锁
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }

}

自动补全参数配置

主要做了如下操作:

  1. 实现MetaObjectHandler()接口
  2. 声明常量
  3. 实现新增:触发的方法insertFill,该方法通过参数上的注解@TableField(fill = FieldFill.INSERT)触发
    1. 新增数据时回填创建时间为当前时间
    2. 新增时回填创建人为当前上下文中的用户
  4. 实现修改:触发方法updateFill,该方法通过参数上的注解@TableField(fill = FieldFill.INSERT_UPDATE)触发
    1. 修改数据时回填修改时间为当前时间
    2. 修改时回填修改人为当前上下文中的用户
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    private static final String CREATE_TIME = "createTime";
    private static final String CREATE_USER = "createUser";
    private static final String UPDATE_TIME = "updateTime";
    private static final String UPDATE_USER = "updateUser";
    private static final String DELETE_TIME = "deleteTime";
    private static final String DELETE_USER = "deleteUser";
    private static final String IS_DELETE = "isDelete";

    public static final String IS_EXPIRED = "isExpired";

    public static final String IS_LOCKED = "isLocked";

    public static final String IS_CREDENTIALS_EXPIRED = "isCredentialsExpired";

    public static final String IS_DISABLE = "isDisable";

    public static final String EXPIRED_TIME = "expiredTime";

    public static final String LOCKED_TIME = "lockedTime";

    public static final String CREDENTIALS_EXPIRED_TIME = "credentialsExpiredTime";

    public static final String DISABLE_TIME = "disableTime";

    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, CREATE_TIME, Date.class, new Date());
        this.strictInsertFill(
                metaObject,
                CREATE_USER,
                String.class,
                SecurityContextUtils.getUserId());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, UPDATE_TIME, Date.class, new Date());
        this.strictUpdateFill(
                metaObject,
                UPDATE_USER,
                String.class,
                SecurityContextUtils.getUserId());
        String gson = new Gson().toJson(metaObject.getOriginalObject());
        JSONObject jsonObject = JSONObject.parseObject(gson);
        //删除状态变更
        if (jsonObject.containsKey(IS_DELETE) && jsonObject.getBoolean(IS_DELETE)) {
            this.strictUpdateFill(metaObject, DELETE_TIME, Date.class, new Date());
            this.strictUpdateFill(
                    metaObject,
                    DELETE_USER,
                    String.class,
                    SecurityContextUtils.getUserId());
        }
        //用户过期状态变更
        if (jsonObject.containsKey(IS_EXPIRED) && jsonObject.getBoolean(IS_EXPIRED)) {
            this.strictUpdateFill(metaObject, EXPIRED_TIME, Date.class, new Date());
        }
        //用户锁定状态变更
        if (jsonObject.containsKey(IS_LOCKED) && jsonObject.getBoolean(IS_LOCKED)) {
            this.strictUpdateFill(metaObject, LOCKED_TIME, Date.class, new Date());
        }
        //用户凭证过期状态变更
        if (jsonObject.containsKey(IS_CREDENTIALS_EXPIRED)
                && jsonObject.getBoolean(IS_CREDENTIALS_EXPIRED)) {
            this.strictUpdateFill(metaObject, CREDENTIALS_EXPIRED_TIME, Date.class, new Date());
        }
        //用户禁用状态变更
        if (jsonObject.containsKey(IS_DISABLE) && jsonObject.getBoolean(IS_DISABLE)) {
            this.strictUpdateFill(metaObject, DISABLE_TIME, Date.class, new Date());
        }
    }
}

逻辑删除注解

逻辑删除:在实体使用注解@TableLogic中标注字段,例如

public class MenuInfo extends Model<MenuInfo> {
    @ApiModelProperty(value = "删除状态 0-不删除 1-删除")
    @TableLogic
    private Boolean isDelete;
}

乐观锁注解

逻辑删除:在实体使用注解@Version中标注字段,例如

public class MenuInfo extends Model<MenuInfo> {
    @ApiModelProperty(value = "乐观锁")
    @Version
    private Integer version;
}

关于mybatis详细的使用方法请转至Mybatis-Plus官网阅读


在这里插入图片描述

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。