ruoyi-vue整合mybatis-plus

807 阅读5分钟

ruyi-vue版本

Application Version: 3.8.7
Spring Boot Version: 2.5.15
gitee地址:gitee.com/y_project/R…

整合mybatis-plus

修改父级pom.xml

  1. 引入mybatis-plus依赖
<mybatis-plus.version>3.5.2</mybatis-plus.version>
<!-- mybatis-plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>${mybatis-plus.version}</version>
</dependency>
  1. 分页插件排除不需要的依赖
<!-- pagehelper 分页插件 -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>${pagehelper.boot.version}</version>
    <exclusions>
        <exclusion>
            <groupId>mybatis.spring</groupId>
            <artifactId>org.mybatis</artifactId>
        </exclusion>
        <exclusion>
            <groupId>mybatis</groupId>
            <artifactId>org.mybatis</artifactId>
        </exclusion>
    </exclusions>
</dependency>
  1. 引入lombok依赖
<lombok.version>1.18.12</lombok.version>
<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
</dependency>

ruoyi-framework模块

  1. 添加mybatis-plus和lombok依赖
<!-- mybatis-plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>

<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
  1. mybatis-plus配置

先删除原有的MybatisConfig文件,新增MybatisPlusConfig

@Configuration
public class MybatisPlusConfig {
    static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
    @Autowired
    private Environment env;

    public static String setTypeAliasesPackage(String typeAliasesPackage) {
        ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
        MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
        List<String> allResult = new ArrayList<String>();
        try {
            for (String aliasesPackage : typeAliasesPackage.split(",")) {
                List<String> result = new ArrayList<String>();
                aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
                        + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
                Resource[] resources = resolver.getResources(aliasesPackage);
                if (resources != null && resources.length > 0) {
                    MetadataReader metadataReader = null;
                    for (Resource resource : resources) {
                        if (resource.isReadable()) {
                            metadataReader = metadataReaderFactory.getMetadataReader(resource);
                            try {
                                result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
                            } catch (ClassNotFoundException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
                if (result.size() > 0) {
                    HashSet<String> hashResult = new HashSet<String>(result);
                    allResult.addAll(hashResult);
                }
            }
            if (allResult.size() > 0) {
                typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
            } else {
                throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return typeAliasesPackage;
    }

    public Resource[] resolveMapperLocations(String[] mapperLocations) {
        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
        List<Resource> resources = new ArrayList<Resource>();
        if (mapperLocations != null) {
            for (String mapperLocation : mapperLocations) {
                try {
                    Resource[] mappers = resourceResolver.getResources(mapperLocation);
                    resources.addAll(Arrays.asList(mappers));
                } catch (IOException e) {
                    // ignore
                }
            }
        }
        return resources.toArray(new Resource[resources.size()]);
    }

    /**
     * 新版配置
     *
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //能够添加很多拦截器实现
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        //乐观锁拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}
  1. 数据库元数据自动处理
  • 创建mybatisplus目录

image.png

  • 创建数据处理器
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    public static final String CREATE_BY = "createBy";
    public static final String CREATE_TIME = "createTime";
    public static final String UPDATE_BY = "updateBy";
    public static final String UPDATE_TIME = "updateTime";
    public static final String DELETED = "delFlag";

    /**
     * 插入时的填充策略
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        // 起始版本 3.3.0(推荐使用)
        this.setFieldValByName(CREATE_BY, SecurityUtils.getUsername(), metaObject);
        this.setFieldValByName(CREATE_TIME, formatDate(metaObject.getSetterType(CREATE_TIME)), metaObject);
        this.setFieldValByName(UPDATE_BY, SecurityUtils.getUsername(), metaObject);
        this.setFieldValByName(UPDATE_TIME, formatDate(metaObject.getSetterType(CREATE_TIME)), metaObject);
        this.setFieldValByName(DELETED, "0", metaObject);
    }

    /**
     * 更新时的填充策略
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName(UPDATE_BY, SecurityUtils.getUsername(), metaObject);
        this.setFieldValByName(UPDATE_TIME, formatDate(metaObject.getSetterType(CREATE_TIME)), metaObject);
    }


    /**
     * 处理特殊日期
     *
     * @param setterType 参数类型
     * @return 日期类型
     */
    private Object formatDate(Class<?> setterType) {
        if (Date.class.equals(setterType)) {
            return new Date();
        } else if (LocalDateTime.class.equals(setterType)) {
            return LocalDateTime.now();
        } else if (Long.class.equals(setterType)) {
            return System.currentTimeMillis();
        }
        return null;
    }
}

ruoyi-common模块

  1. 添加mybatis-plus和lombok依赖
<!-- mybatis-plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>

<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
  1. 自定义Entity实体类

image.png

@Data
public class MyBaseEntity implements Serializable
{
   private static final long serialVersionUID = 1L;

   /** 逻辑删除 */
   @TableLogic
   @TableField(fill = FieldFill.INSERT)
   private String delFlag;

   /** 创建者 */
   @TableField(fill = FieldFill.INSERT)
   private String createBy;

   /** 创建时间 */
   @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
   @TableField(fill = FieldFill.INSERT)
   private Date createTime;

   /** 更新者 */
   @TableField(fill = FieldFill.INSERT_UPDATE)
   private String updateBy;

   /** 更新时间 */
   @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
   @TableField(fill = FieldFill.INSERT_UPDATE)
   private Date updateTime;

   /** 备注 */
   private String remark;

   /** 请求参数 */
   @JsonInclude(JsonInclude.Include.NON_EMPTY)
   @TableField(exist = false)
   private Map<String, Object> params;


   public Map<String, Object> getParams()
   {
       if (params == null)
       {
           params = new HashMap<>();
       }
       return params;
   }

   public void setParams(Map<String, Object> params)
   {
       this.params = params;
   }
}
  1. 修改GenConstants类

主要是为了系统代码自动生成时,排除delFlag字段

public class GenConstants
{
    /** 单表(增删改查) */
    public static final String TPL_CRUD = "crud";

    /** 树表(增删改查) */
    public static final String TPL_TREE = "tree";

    /** 主子表(增删改查) */
    public static final String TPL_SUB = "sub";

    /** 树编码字段 */
    public static final String TREE_CODE = "treeCode";

    /** 树父编码字段 */
    public static final String TREE_PARENT_CODE = "treeParentCode";

    /** 树名称字段 */
    public static final String TREE_NAME = "treeName";

    /** 上级菜单ID字段 */
    public static final String PARENT_MENU_ID = "parentMenuId";

    /** 上级菜单名称字段 */
    public static final String PARENT_MENU_NAME = "parentMenuName";

    /** 数据库字符串类型 */
    public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" };

    /** 数据库文本类型 */
    public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" };

    /** 数据库时间类型 */
    public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };

    /** 数据库数字类型 */
    public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
            "bit", "bigint", "float", "double", "decimal" };

    /** 页面不需要编辑字段 */
    public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };

    /** 页面不需要显示的列表字段 */
    public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by",
            "update_time" };

    /** 页面不需要查询字段 */
    public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by",
            "update_time", "remark" };

    /** Entity基类字段 */
    public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark", "delFlag" };

    /** Tree基类字段 */
    public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" };

    /** 文本框 */
    public static final String HTML_INPUT = "input";

    /** 文本域 */
    public static final String HTML_TEXTAREA = "textarea";

    /** 下拉框 */
    public static final String HTML_SELECT = "select";

    /** 单选框 */
    public static final String HTML_RADIO = "radio";

    /** 复选框 */
    public static final String HTML_CHECKBOX = "checkbox";

    /** 日期控件 */
    public static final String HTML_DATETIME = "datetime";

    /** 图片上传控件 */
    public static final String HTML_IMAGE_UPLOAD = "imageUpload";

    /** 文件上传控件 */
    public static final String HTML_FILE_UPLOAD = "fileUpload";

    /** 富文本控件 */
    public static final String HTML_EDITOR = "editor";

    /** 字符串类型 */
    public static final String TYPE_STRING = "String";

    /** 整型 */
    public static final String TYPE_INTEGER = "Integer";

    /** 长整型 */
    public static final String TYPE_LONG = "Long";

    /** 浮点型 */
    public static final String TYPE_DOUBLE = "Double";

    /** 高精度计算类型 */
    public static final String TYPE_BIGDECIMAL = "BigDecimal";

    /** 时间类型 */
    public static final String TYPE_DATE = "Date";

    /** 模糊查询 */
    public static final String QUERY_LIKE = "LIKE";

    /** 相等查询 */
    public static final String QUERY_EQ = "EQ";

    /** 需要 */
    public static final String REQUIRE = "1";
}

ruoyi-generator模块


替换resources下的vm,目录结构

image.png

gitee地址:gitee.com/chaunceyzer…

mybatis-plus配置


application.yml先注释掉原有的mybatis配置,添加mybatis-plus配置
# MyBatis配置
#mybatis:
  # 搜索指定包别名
  #typeAliasesPackage: com.ruoyi.**.domain
  # 配置mapper的扫描,找到所有的mapper.xml映射文件
  #mapperLocations: classpath*:mapper/**/*Mapper.xml
  # 加载全局的配置文件
  #configLocation: classpath:mybatis/mybatis-config.xml
# MyBatis Plus配置
mybatis-plus:
  # 不支持多包, 如有需要可在注解配置 或 提升扫包等级
  # 例如 com.**.**.mapper
  mapperPackage: com.ruoyi.**.mapper
  # 对应的 XML 文件位置
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # 实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: com.ruoyi.**.domain
  # 启动时是否检查 MyBatis XML 文件的存在,默认不检查
  checkConfigLocation: false
  configuration:
    # 自动驼峰命名规则(camel case)映射
    mapUnderscoreToCamelCase: true
    # MyBatis 自动映射策略
    # NONE:不启用 PARTIAL:只对非嵌套 resultMap 自动映射 FULL:对所有 resultMap 自动映射
    autoMappingBehavior: PARTIAL
    # MyBatis 自动映射时未知列或未知属性处理策
    # NONE:不做处理 WARNING:打印相关警告 FAILING:抛出异常和详细信息
    autoMappingUnknownColumnBehavior: NONE
    # 更详细的日志输出 会有性能损耗 org.apache.ibatis.logging.stdout.StdOutImpl
    # 关闭日志记录 (可单纯使用 p6spy 分析) org.apache.ibatis.logging.nologging.NoLoggingImpl
    # 默认日志输出 org.apache.ibatis.logging.slf4j.Slf4jImpl
    logImpl: org.apache.ibatis.logging.slf4j.Slf4jImpl
  global-config:
    # 是否打印 Logo banner
    banner: false
    dbConfig:
      # 主键类型
      # AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
      idType: ASSIGN_ID
      # 逻辑已删除值
      logicDeleteValue: 1
      # 逻辑未删除值
      logicNotDeleteValue: 0
      # 字段验证策略之 insert,在 insert 的时候的字段验证策略
      # IGNORED 忽略 NOT_NULL 非NULL NOT_EMPTY 非空 DEFAULT 默认 NEVER 不加入 SQL
      insertStrategy: NOT_NULL
      # 字段验证策略之 update,在 update 的时候的字段验证策略
      updateStrategy: NOT_NULL
      # 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件
      where-strategy: NOT_NULL