From 86ae9df4824a67d28e6ddae001b69056b79bbc6b Mon Sep 17 00:00:00 2001 From: yexuejc <1107047387@qq.com> Date: Fri, 19 Jan 2024 16:11:52 +0800 Subject: [PATCH] =?UTF-8?q?[feat]=20=E9=9B=86=E6=88=90mybatis-plus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 9 + .../core/config/MplusMetaObjectHandler.java | 96 ++++++ .../web/core/config/MyBatisPlusConfig.java | 55 ++++ .../core/config/RuoyiMetaObjectHandler.java | 14 + .../src/main/resources/application.yml | 4 +- ruoyi-common/pom.xml | 13 + .../ruoyi/common/core/domain/BaseEntity.java | 24 +- .../ruoyi/framework/config/MyBatisConfig.java | 2 + update.md | 275 ++++++++++++++++++ 9 files changed, 482 insertions(+), 10 deletions(-) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MplusMetaObjectHandler.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MyBatisPlusConfig.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/core/config/RuoyiMetaObjectHandler.java create mode 100644 update.md diff --git a/pom.xml b/pom.xml index 91a7a4b..4ffdf31 100644 --- a/pom.xml +++ b/pom.xml @@ -30,6 +30,7 @@ 4.1.2 2.3 0.9.1 + 3.5.5 @@ -45,6 +46,13 @@ import + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + com.alibaba @@ -180,6 +188,7 @@ ruoyi-quartz ruoyi-generator ruoyi-common + mybatis-plus-test pom diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MplusMetaObjectHandler.java b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MplusMetaObjectHandler.java new file mode 100644 index 0000000..dfdf683 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MplusMetaObjectHandler.java @@ -0,0 +1,96 @@ +package com.ruoyi.web.core.config; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import org.apache.ibatis.reflection.MetaObject; + +import java.util.Date; + +/** + * 注入公共字段自动填充,任选注入方式即可 + *

+ * 继承使用 + *

+ *

+ * 继承后重写 {@link #getOperator()}重新注入 Bean + *

+ *
+ *     @author yexuejc
+ * @Bean
+ *     public MyMetaObjectHandler metaObjectHandler() {
+ *         return new MyMetaObjectHandler();
+ *     }
+ * 
+ */ +public class MplusMetaObjectHandler implements MetaObjectHandler { + + /** + * 创建时间 + */ + protected String crtTimeColumn = "createTime"; + /** + * 创建人 + */ + protected String crtByColumn = "createBy"; + /** + * 最后操作时间 + */ + protected String updateTimeColumn = "updateTime"; + /** + * 最后操作人 + */ + protected String updateByColumn = "updateBy"; + + /** + * 设置操作者 + *

+ * 应设置登录账号为操作者,这里由每个工程具体实现 + *

+ *

+ * 返回null时,会查找consumerId作为操作者,找不到会设置默认值 + *
+ * 返回"" 时,会存"" + *

+ * + * @return + */ + protected String getOperator() { + return ""; + } + + @Override + public void insertFill(MetaObject metaObject) { + Object crtTime = metaObject.getValue(crtTimeColumn); + if (crtTime == null) { + this.strictInsertFill(metaObject, crtTimeColumn, Date.class, new Date()); + } + + Object crtBy = metaObject.getValue(crtByColumn); + if (crtBy == null) { + this.strictInsertFill(metaObject, crtByColumn, String.class, getOperator()); + } + + Object mdfyTime = metaObject.getValue(updateTimeColumn); + if (mdfyTime == null) { + this.strictInsertFill(metaObject, updateTimeColumn, Date.class, new Date()); + } + + Object mdfyBy = metaObject.getValue(updateByColumn); + if (mdfyBy == null) { + this.strictInsertFill(metaObject, updateByColumn, String.class, getOperator()); + } + + } + + @Override + public void updateFill(MetaObject metaObject) { + Object mdfyTime = metaObject.getValue(updateTimeColumn); + if (mdfyTime == null) { + this.strictInsertFill(metaObject, updateTimeColumn, Date.class, new Date()); + } + + Object mdfyBy = metaObject.getValue(updateByColumn); + if (mdfyBy == null) { + this.strictInsertFill(metaObject, updateByColumn, String.class, getOperator()); + } + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MyBatisPlusConfig.java b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MyBatisPlusConfig.java new file mode 100644 index 0000000..373048f --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MyBatisPlusConfig.java @@ -0,0 +1,55 @@ +package com.ruoyi.web.core.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * MybatisPlus 配置文件 + * + * @author maxf + * @version 1.0 + * @ClassName MybatisPlusConfig + * @Description + * @date 2018/12/13 11:34 + */ +//Spring boot方式 +@EnableTransactionManagement +@Configuration +public class MybatisPlusConfig { + /** + * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除) + */ + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + //新的分页插件 + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); + //乐观锁插件 + interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); + return interceptor; + } + + @Bean + @ConditionalOnMissingBean + public MetaObjectHandler metaObjectHandler() { + return new MplusMetaObjectHandler(); + } + + /** + * 注入sql注入器 + */ + @Bean + @ConditionalOnMissingBean + public DefaultSqlInjector sqlInjector() { + return new DefaultSqlInjector(); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/RuoyiMetaObjectHandler.java b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/RuoyiMetaObjectHandler.java new file mode 100644 index 0000000..d73e73a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/RuoyiMetaObjectHandler.java @@ -0,0 +1,14 @@ +package com.ruoyi.web.core.config; + +import com.ruoyi.common.utils.SecurityUtils; + +/** + * @author: yexuejc + * @date: 2020-10-13 15:25:28 + */ +public class RuoyiMetaObjectHandler extends MplusMetaObjectHandler { + @Override + protected String getOperator() { + return SecurityUtils.getUsername(); + } +} diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index f7125af..becbb14 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -97,8 +97,8 @@ token: # 令牌有效期(默认30分钟) expireTime: 30 -# MyBatis配置 -mybatis: +# MyBatis配置(plus) +mybatis-plus: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index 38326a1..f75f13f 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -39,6 +39,19 @@ com.github.pagehelper pagehelper-spring-boot-starter + + + + mybatis + org.mybatis + + + + + + + com.baomidou + mybatis-plus-boot-starter diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java index 67269ff..70aa99d 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java @@ -4,6 +4,9 @@ import java.io.Serializable; import java.util.Date; import java.util.HashMap; import java.util.Map; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; @@ -13,32 +16,37 @@ import com.fasterxml.jackson.annotation.JsonInclude; * * @author ruoyi */ -public class BaseEntity implements Serializable -{ +public class BaseEntity implements Serializable { private static final long serialVersionUID = 1L; - /** 搜索值 */ + /** 搜索值 该字段数据库不需要*/ + @TableField(exist = false) @JsonIgnore private String searchValue; - /** 创建者 */ + /** 创建者 新增时自动填充*/ + @TableField(fill = FieldFill.INSERT) private String createBy; - /** 创建时间 */ + /** 创建时间 新增时自动填充*/ + @TableField(fill = FieldFill.INSERT) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; - /** 更新者 */ + /** 更新者 新增和修改时自动填充*/ + @TableField(fill = FieldFill.INSERT_UPDATE) private String updateBy; - /** 更新时间 */ + /** 更新时间 新增和修改时自动填充*/ + @TableField(fill = FieldFill.INSERT_UPDATE) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date updateTime; /** 备注 */ private String remark; - /** 请求参数 */ + /** 请求参数 该字段数据库不需要*/ + @TableField(exist = false) @JsonInclude(JsonInclude.Include.NON_EMPTY) private Map params; diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java index e30fe74..f4ecc7a 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java @@ -11,6 +11,7 @@ import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.boot.autoconfigure.SpringBootVFS; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; @@ -30,6 +31,7 @@ import com.ruoyi.common.utils.StringUtils; * @author ruoyi */ @Configuration +@ConditionalOnProperty(name = "ruoyi.mybatis.enable", matchIfMissing = false) public class MyBatisConfig { @Autowired diff --git a/update.md b/update.md new file mode 100644 index 0000000..b6ad03a --- /dev/null +++ b/update.md @@ -0,0 +1,275 @@ +ruoyi mybatis-plus版 +------------------ +### 改造 +#### 依赖配置 +> 1. [pom.xml](pom.xml) +```xml +3.5.5 + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + +``` +> 2.增加mybatis-plus [ruoyi-admin/pom.xml](ruoyi-admin/pom.xml) +```xml + + + com.github.pagehelper + pagehelper-spring-boot-starter + + + + mybatis + org.mybatis + + + + + + + com.baomidou + mybatis-plus-boot-starter + +``` +#### 代码改修 +> 1.关掉mybatis的配置 [MyBatisConfig.java](ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java) +```java +@Configuration +@ConditionalOnProperty(name = "ruoyi.mybatis.enable", matchIfMissing = false) +public class MyBatisConfig +``` +> 2.追加mybatisPlus的配置,覆盖mybatis的配置: [MybatisPlusConfig.java](ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MybatisPlusConfig.java) +
+点我展开看代码 +

+package com.ruoyi.web.core.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+/**
+ * MybatisPlus 配置文件
+ *
+ * @author maxf
+ * @version 1.0
+ * @ClassName MybatisPlusConfig
+ * @Description
+ * @date 2018/12/13 11:34
+ */
+//Spring boot方式
+@EnableTransactionManagement
+@Configuration
+public class MybatisPlusConfig {
+    /**
+     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
+     */
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor() {
+        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+        //新的分页插件
+        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
+        //乐观锁插件
+        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
+        return interceptor;
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    public MetaObjectHandler metaObjectHandler() {
+        return new MplusMetaObjectHandler();
+    }
+
+    /**
+     * 注入sql注入器
+     */
+    @Bean
+    @ConditionalOnMissingBean
+    public DefaultSqlInjector sqlInjector() {
+        return new DefaultSqlInjector();
+    }
+
+}
+
+
+ +>公共字段的自动填充处理(1):[BaseEntity.java](ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java) +```java + /** 搜索值 该字段数据库不需要*/ + @TableField(exist = false) + @JsonIgnore + private String searchValue; + + /** 创建者 新增时自动填充*/ + @TableField(fill = FieldFill.INSERT) + private String createBy; + + /** 创建时间 新增时自动填充*/ + @TableField(fill = FieldFill.INSERT) + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** 更新者 新增和修改时自动填充*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updateBy; + + /** 更新时间 新增和修改时自动填充*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + /** 备注 */ + private String remark; + + /** 请求参数 该字段数据库不需要*/ + @TableField(exist = false) + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private Map params; +``` + +>公共字段的自动填充处理(2): [MplusMetaObjectHandler.java](ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MplusMetaObjectHandler.java) +
+点我展开看代码 +

+package com.ruoyi.web.core.config;
+
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import org.apache.ibatis.reflection.MetaObject;
+
+import java.util.Date;
+
+/**
+* 注入公共字段自动填充,任选注入方式即可
+* 

+* 继承使用 +*

+*

+* 继承后重写 {@link #getOperator()}重新注入 Bean +*

+*
+*     @author yexuejc
+* @Bean
+*     public MyMetaObjectHandler metaObjectHandler() {
+*         return new MyMetaObjectHandler();
+*     }
+* 
+*/ +public class MplusMetaObjectHandler implements MetaObjectHandler { + + /** + * 创建时间 + */ + protected String crtTimeColumn = "createTime"; + /** + * 创建人 + */ + protected String crtByColumn = "createBy"; + /** + * 最后操作时间 + */ + protected String updateTimeColumn = "updateTime"; + /** + * 最后操作人 + */ + protected String updateByColumn = "updateBy"; + + /** + * 设置操作者 + *

+ * 应设置登录账号为操作者,这里由每个工程具体实现 + *

+ *

+ * 返回null时,会查找consumerId作为操作者,找不到会设置默认值 + *
+ * 返回"" 时,会存"" + *

+ * + * @return + */ + protected String getOperator() { + return ""; + } + + @Override + public void insertFill(MetaObject metaObject) { + Object crtTime = metaObject.getValue(crtTimeColumn); + if (crtTime == null) { + this.strictInsertFill(metaObject, crtTimeColumn, Date.class, new Date()); + } + + Object crtBy = metaObject.getValue(crtByColumn); + if (crtBy == null) { + this.strictInsertFill(metaObject, crtByColumn, String.class, getOperator()); + } + + Object mdfyTime = metaObject.getValue(updateTimeColumn); + if (mdfyTime == null) { + this.strictInsertFill(metaObject, updateTimeColumn, Date.class, new Date()); + } + + Object mdfyBy = metaObject.getValue(updateByColumn); + if (mdfyBy == null) { + this.strictInsertFill(metaObject, updateByColumn, String.class, getOperator()); + } + + } + + @Override + public void updateFill(MetaObject metaObject) { + Object mdfyTime = metaObject.getValue(updateTimeColumn); + if (mdfyTime == null) { + this.strictInsertFill(metaObject, updateTimeColumn, Date.class, new Date()); + } + + Object mdfyBy = metaObject.getValue(updateByColumn); + if (mdfyBy == null) { + this.strictInsertFill(metaObject, updateByColumn, String.class, getOperator()); + } + } +} + +
+
+ +> 4.自动获取操作者的实现(需要注入为bean): [RuoyiMetaObjectHandler.java](ruoyi-admin/src/main/java/com/ruoyi/web/core/config/RuoyiMetaObjectHandler.java) +``` +package com.ruoyi.web.core.config; + +import com.ruoyi.common.utils.SecurityUtils; + +/** + * @author: yexuejc + * @date: 2020-10-13 15:25:28 + */ +public class RuoyiMetaObjectHandler extends MplusMetaObjectHandler { + @Override + protected String getOperator() { + return SecurityUtils.getUsername(); + } +} +``` + +#### 配置 +> mybatis的配置改为mybatis-plus的配置:ruoyi-admin/src/main/resources/application.yml +```properties +# MyBatis配置(plus) +mybatis-plus: + # 搜索指定包别名 + typeAliasesPackage: com.ruoyi.**.domain + # 配置mapper的扫描,找到所有的mapper.xml映射文件 + mapperLocations: classpath*:mapper/**/*Mapper.xml + # 加载全局的配置文件 + configLocation: classpath:mybatis/mybatis-config.xml +``` +### 多出的功能 +* [mybatis-plus-test](mybatis-plus-test) 集成mybatis-plus后的测试demo +> 先创建demo表,[init.sql](mybatis-plus-test/src/main/resources/init.sql);执行参照[UserOrderServiceTest.java](mybatis-plus-test/src/test/java/com/ruoyi/mp/service/UserOrderServiceTest.java) \ No newline at end of file