diff --git a/.gitignore b/.gitignore
index 2a2237645ffd36e5a9133cd9bc91a335f5c307a8..3f6cead8ce1981e9673315f9e20df71e2b16e7bd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,6 @@
# Ignore Gradle project-specific cache directory
.gradle
*.iml
-application.properties
application-*.properties
.DS_Store
diff --git a/README.md b/README.md
index f71bb37f7717edff5bb5684dde47e195201ec910..0c368225d1045dcfa1a585c3abc00df6a30d6a42 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,6 @@
-> 可以告别常规SQL和CRUD了!diboot新用户: [看视频快速了解diboot](https://www.bilibili.com/video/BV17V411r7Cc) 、 [手把手跟我来体验](https://www.diboot.com/guide/newer/bootstrap.html)
+> 用上diboot,告别常规SQL和CRUD,写的更少,性能更好!
+
+> 新用户指南: [手把手来体验](https://www.diboot.com/guide/newer/bootstrap.html) 、[看视频了解我](https://www.bilibili.com/video/BV17V411r7Cc) 、[如何做到高性能](https://www.bilibili.com/video/BV1tL411p7CD)
# diboot - 基础组件化繁为简,高效工具以简驭繁
@@ -14,46 +16,39 @@

-spring boot版本目前实现: core高效内核 + devtools开发助理 + IAM身份认证、file文件处理、scheduler定时任务等基础组件 + diboot-*-admin基础后台。
-
-> [spring cloud版本,移步这里->](https://github.com/dibo-software/diboot-cloud)
+> [diboot-cloud 微服务版本,看这里->](https://www.diboot.com/ent/service.html)
-> [diboot-workflow 工作流授权](https://www.diboot.com/ent/service.html)
+> [diboot-workflow 工作流版本,看这里->](https://www.diboot.com/ent/service.html)
## diboot基础组件
-### 1、 diboot-core: 精简优化内核
-高效精简内核,重构查询方式(拆解关联查询,程序中Join),简化开发,主要实现:
-#### 1). 单表CRUD无SQL
- > 基于Mybatis-Plus实现(Mybatis-Plus具备通用Mapper方案和灵活的查询构造器)
-#### 2). 关联绑定无SQL(注解自动绑定)
- > 扩展实现了多表关联查询的无SQL方案,只需要一个简单注解@Bind*,就可以实现关联对象(含字段、字段集合、实体、实体集合等)的数据绑定,且实现方案是将关联查询拆解为单表查询,保障最佳性能。
-#### 3). 数据字典无SQL(注解自动绑定)
- > 通过@BindDict注解实现数据字典(枚举)的存储值value与显示值name的转换。
-#### 4). 跨表查询无SQL(自动构建QueryWrapper与查询)
- > @BindQuery注解绑定字段查询方式及关联表,自动构建QueryWrapper,并动态执行单表或Join联表查询。
-#### 5). BaseService扩展增强,支持常规的单表及关联开发场景接口
- > createEntityAndRelatedEntities、getValuesOfField、exists、getKeyValueList、getViewObject*等接口
-#### 6). 其他常用工具类、状态码、异常处理的最佳实践封装
- > JsonResult、字符串处理、常用校验、BeanUtils、DateUtils等
-
-基于diboot-core 2.x版本的CRUD和简单关联的常规功能实现,代码量比传统Mybatis项目减少80%+),且实现更高效更易维护。
+### 1、 diboot-core: 精简优化内核:写的更少,性能更好
+主要特性:
+* 单表CRUD无SQL
+* 关联绑定无SQL(注解自动绑定)
+* 数据字典无SQL(注解自动绑定)
+* 跨表查询无SQL(自动构建QueryWrapper与查询)
+* BaseService扩展增强,支持常规的单表及关联开发场景接口
+* 其他常用工具类、状态码、异常处理的更优实践封装
+
+基于diboot-core的CRUD和常规关联的功能实现,代码量比传统Mybatis项目减少80%+,且性能更好更易维护。
> 详细文档: [diboot-core文档](https://www.diboot.com/guide/diboot-core/%E7%AE%80%E4%BB%8B.html).
### 2、IAM 身份认证基础组件 及 配套VUE前端框架(diboot-antd-admin、diboot-element-admin)
* 开箱即用的RBAC角色权限模型与预置组织人员岗位模型
-* 基于JWT的认证授权,支持申请token、刷新token
+* 基于JWT的认证授权,支持申请token、刷新token、无状态认证
* 简化的BindPermission注解,支持兼容shiro的简化权限绑定与自动鉴权
-* 简化的Log注解记录操作日志
* 自动提取需要验证的后端接口, 借助前端功能方便绑定前后端菜单按钮权限
-* 支持基于注解的数据权限实现
+* 无缝适配redis,引入redis依赖即可启用shiro的redis缓存
+* 支持基于注解的数据权限实现、简化的Log注解记录操作日志等
* 支持灵活的扩展能力(扩展多种登录方式、灵活替换用户实体类、自定义缓存等)
> 详细文档: [diboot-iam文档](https://www.diboot.com/guide/diboot-iam/%E4%BB%8B%E7%BB%8D.html).
### 3、diboot-file 文件相关处理组件
* EasyExcel轻量封装,支持Java注解校验与@ExcelBind*注解实现字典及关联字段的name-value转换,并提供完善的校验错误提示
-* 封装常用的文件本地存储、上传下载、图片压缩水印等常用处理
+* 文件存储接口化,预置本地存储,简单扩展OSS、分布式存储等实现
+* 封装常用的文件上传下载、图片压缩水印等常用处理
> 详细文档: [diboot-file文档](https://www.diboot.com/guide/diboot-file/%E4%BB%8B%E7%BB%8D.html).
### 4、diboot-scheduler 定时任务组件
@@ -67,22 +62,18 @@ spring boot版本目前实现: core高效内核 + devtools开发助理 + IAM身
* 支持多通道的消息通知发送
## devtools开发助理
+* 极简易用(引入依赖jar,配置参数后,即可随应用启动运行)
+* 功能强大(数据结构与代码同步、前后端代码一键生成、前端面板组件编排)
+* 配置灵活(可按需配置生成代码路径及启用`Lombok`、`Swagger`等)
+* 代码标准(devtools标准化了数据结构定义与代码实现,降低维护成本)
+* 支持多库(MySQL、MariaDB、ORACLE、SQLServer、PostgreSQL)
-* 使用很简单(UI界面操作,引入依赖配置参数后,即可随Spring boot/Spring cloud本地项目启动运行)
-* 功能很强大:
- * 单表与关联场景CRUD导入导出的完整功能全自动生成,无需手写代码
- * 结合前端面板组件编排能力,覆盖更多场景的自动化生成
- * 数据结构变更与代码联动同步,自动记录变更SQL、维护索引
- * 一键生成代码&非覆盖式更新本地后端代码
-* 配置很灵活(可按需配置生成代码路径,是否启用`Lombok`、`Swagger`等)
-* SQL与代码很标准(devtools标准化了数据结构定义与代码实现)
-* 支持多数据库(MySQL、MariaDB、ORACLE、SQLServer、PostgreSQL)
> 详细文档: [diboot-devtools文档](https://www.diboot.com/guide/diboot-devtools/%E4%BB%8B%E7%BB%8D.html).
## 捐助支持
-感谢所有捐助的朋友为开源事业的发展做出的努力。
+感谢每一位支持diboot的粉丝朋友。
## 技术交流
如遇diboot相关技术问题,欢迎加群交流:
diff --git a/diboot-core-starter/pom.xml b/diboot-core-starter/pom.xml
index e976c435a63f84e533b2eb5f6ffae537682aa8f1..f29cb0149786f63f503a5fc237848b45dd9d15fc 100644
--- a/diboot-core-starter/pom.xml
+++ b/diboot-core-starter/pom.xml
@@ -7,11 +7,11 @@
com.diboot
diboot-root
- 2.2.1
+ 2.3.0
diboot-core-spring-boot-starter
- 2.2.1
+ 2.3.0
jar
diboot core starter project
@@ -41,6 +41,12 @@
${diboot.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+ provided
+
org.springframework.boot
@@ -52,6 +58,5 @@
junit
test
-
-
\ No newline at end of file
+
diff --git a/diboot-core-starter/src/main/java/com/diboot/core/starter/CoreAutoConfiguration.java b/diboot-core-starter/src/main/java/com/diboot/core/starter/CoreAutoConfig.java
similarity index 98%
rename from diboot-core-starter/src/main/java/com/diboot/core/starter/CoreAutoConfiguration.java
rename to diboot-core-starter/src/main/java/com/diboot/core/starter/CoreAutoConfig.java
index 5b7f665a615546903ab76db151b440b01c5156a8..ea83aa3efed062ed02c20d70ec2f56a71deb0530 100644
--- a/diboot-core-starter/src/main/java/com/diboot/core/starter/CoreAutoConfiguration.java
+++ b/diboot-core-starter/src/main/java/com/diboot/core/starter/CoreAutoConfig.java
@@ -55,8 +55,8 @@ import java.util.TimeZone;
@EnableConfigurationProperties(CoreProperties.class)
@ComponentScan(basePackages = {"com.diboot.core"})
@MapperScan(basePackages = {"com.diboot.core.mapper"})
-public class CoreAutoConfiguration implements WebMvcConfigurer {
- private static final Logger log = LoggerFactory.getLogger(CoreAutoConfiguration.class);
+public class CoreAutoConfig implements WebMvcConfigurer {
+ private static final Logger log = LoggerFactory.getLogger(CoreAutoConfig.class);
@Value("${spring.jackson.date-format:"+D.FORMAT_DATETIME_Y4MDHMS+"}")
private String defaultDatePattern;
diff --git a/diboot-core-starter/src/main/java/com/diboot/core/starter/CoreProperties.java b/diboot-core-starter/src/main/java/com/diboot/core/starter/CoreProperties.java
index 9a2624367be7fc1150cfeb60b59d7ca60c7a8e40..57f5a3f9c1a33bef1d8fed2bbe84a37af3c99caf 100644
--- a/diboot-core-starter/src/main/java/com/diboot/core/starter/CoreProperties.java
+++ b/diboot-core-starter/src/main/java/com/diboot/core/starter/CoreProperties.java
@@ -25,7 +25,14 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
*/
@ConfigurationProperties(prefix = "diboot.core")
public class CoreProperties {
-
+ /**
+ * 每页记录数量
+ */
+ private int pageSize = 20;
+ /**
+ * 每批次数量
+ */
+ private int batchSize = 1000;
/**
* 是否初始化,默认true自动安装SQL
*/
@@ -38,4 +45,21 @@ public class CoreProperties {
public void setInitSql(boolean initSql) {
this.initSql = initSql;
}
+
+ public void setBatchSize(int batchSize) {
+ this.batchSize = batchSize;
+ }
+
+ public int getBatchSize() {
+ return batchSize;
+ }
+
+ public void setPageSize(int pageSize) {
+ this.pageSize = pageSize;
+ }
+
+ public int getPageSize() {
+ return pageSize;
+ }
+
}
diff --git a/diboot-core-starter/src/main/java/com/diboot/core/starter/RedisAutoConfig.java b/diboot-core-starter/src/main/java/com/diboot/core/starter/RedisAutoConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..055868addb8e6907921978a750b83cc437beffdc
--- /dev/null
+++ b/diboot-core-starter/src/main/java/com/diboot/core/starter/RedisAutoConfig.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015-2020, www.dibo.ltd (service@dibo.ltd).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.diboot.core.starter;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.ser.FilterProvider;
+import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
+import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnResource;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
+import org.springframework.data.redis.core.RedisOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * Redis 自动配置
+ *
+ * @author wind
+ * @version v2.3.0
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnClass(RedisOperations.class)
+@ConditionalOnResource(resources = "org/springframework/data/redis")
+public class RedisAutoConfig {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public RedisTemplate redisTemplate(LettuceConnectionFactory connectionFactory) {
+ //... 初始化RedisTemplate
+ RedisTemplate redisTemplate = new RedisTemplate<>();
+
+ StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+ // 用StringRedisSerializer 序列化和反序列化key值
+ redisTemplate.setKeySerializer(stringRedisSerializer);
+ redisTemplate.setHashKeySerializer(stringRedisSerializer);
+
+ // 用Jackson2JsonRedisSerializer 序列化和反序列化value值
+ redisTemplate.setValueSerializer(jackson2JsonRedisSerializer());
+ redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer());
+
+ redisTemplate.setConnectionFactory(connectionFactory);
+ redisTemplate.afterPropertiesSet();
+ return redisTemplate;
+ }
+
+ private Jackson2JsonRedisSerializer jackson2JsonRedisSerializer() {
+ Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.setVisibility(PropertyAccessor.ALL , JsonAutoDetect.Visibility.ANY);
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES , false);
+ objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS , false);
+ objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator() , ObjectMapper.DefaultTyping.NON_FINAL);
+ objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+
+ FilterProvider filterProvider = new SimpleFilterProvider().addFilter("rewrite-bean" , SimpleBeanPropertyFilter.serializeAllExcept("realmNames"));
+ objectMapper.setFilterProvider(filterProvider);
+ jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
+ return jackson2JsonRedisSerializer;
+ }
+
+}
diff --git a/diboot-core-starter/src/main/resources/META-INF/spring.factories b/diboot-core-starter/src/main/resources/META-INF/spring.factories
index b949e883423492888b2e8a5ed4fd3b6943581e62..0b873c6f86ec3d04ab044bd2daf34b7ac36d5d69 100644
--- a/diboot-core-starter/src/main/resources/META-INF/spring.factories
+++ b/diboot-core-starter/src/main/resources/META-INF/spring.factories
@@ -1 +1 @@
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.diboot.core.starter.CoreAutoConfiguration
\ No newline at end of file
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.diboot.core.starter.CoreAutoConfig
\ No newline at end of file
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/binder/TestDictBinder.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/TestDictBinder.java
new file mode 100644
index 0000000000000000000000000000000000000000..e95c94498177c131e8f0bb70248df0d53253de20
--- /dev/null
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/TestDictBinder.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2015-2020, www.dibo.ltd (service@dibo.ltd).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package diboot.core.test.binder;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.diboot.core.binding.Binder;
+import com.diboot.core.util.BeanUtils;
+import com.diboot.core.util.JSON;
+import com.diboot.core.util.V;
+import diboot.core.test.StartupApplication;
+import diboot.core.test.binder.entity.User;
+import diboot.core.test.binder.service.UserService;
+import diboot.core.test.binder.vo.UserVO;
+import diboot.core.test.config.SpringMvcConfig;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+/**
+ * 测试字典绑定
+ * @author mazc@dibo.ltd
+ * @version v2.0
+ * @date 2021/06/18
+ */
+@RunWith(SpringRunner.class)
+@ContextConfiguration(classes = {SpringMvcConfig.class})
+@SpringBootTest(classes = {StartupApplication.class})
+public class TestDictBinder {
+
+ @Autowired
+ UserService userService;
+
+ @Test
+ public void testBinder(){
+ // 加载测试数据
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.in(User::getId, 1001L, 1002L);
+ List userList = userService.getEntityList(queryWrapper);
+ // 自动绑定
+ List voList = Binder.convertAndBindRelations(userList, UserVO.class);
+ // 验证绑定结果
+ Assert.assertTrue(V.notEmpty(voList));
+ for(UserVO vo : voList){
+ // 验证直接关联和通过中间表间接关联的绑定
+ Assert.assertNotNull(vo.getGenderLabel());
+ System.out.println(JSON.stringify(vo));
+ }
+ // 单个entity接口测试
+ UserVO singleVO = BeanUtils.convert(userList.get(1), UserVO.class);
+ Binder.bindRelations(singleVO);
+ // 验证直接关联和通过中间表间接关联的绑定
+ Assert.assertNotNull(singleVO.getGenderLabel());
+ System.out.println(JSON.stringify(singleVO));
+ }
+
+}
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/binder/TestFieldBinder.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/TestFieldBinder.java
index a9d813aaeadb9bc9a9070e55371be554ee16c5b7..634caa1e5f70020418591a79a5ed5d8674756fb5 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/binder/TestFieldBinder.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/TestFieldBinder.java
@@ -100,6 +100,22 @@ public class TestFieldBinder {
}
}
+ @Test
+ public void testBinderWithEscCol(){
+ // 加载测试数据
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.in(User::getId, 1001L, 1002L);
+ List userList = userService.getEntityList(queryWrapper);
+ // 自动绑定
+ List voList = Binder.convertAndBindRelations(userList, UserEscVO.class);
+ if(V.notEmpty(voList)){
+ for(UserEscVO vo : voList){
+ Assert.assertNotNull(vo.getDeptCharacter());
+ Assert.assertNotNull(vo.getDeptName());
+ Assert.assertNotNull(vo.getOrgName());
+ }
+ }
+ }
@Test
public void testDictVoBind(){
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/binder/dto/DepartmentDTO.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/dto/DepartmentDTO.java
index 4e947950ab3d414b727c87510a165adac0f212d3..be0c98a076f92bac71ddaf84af5a97e05bf277c8 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/binder/dto/DepartmentDTO.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/dto/DepartmentDTO.java
@@ -15,6 +15,7 @@
*/
package diboot.core.test.binder.dto;
+import com.baomidou.mybatisplus.annotation.TableField;
import com.diboot.core.binding.data.CheckpointType;
import com.diboot.core.binding.data.DataAccessCheckpoint;
import com.diboot.core.binding.query.BindQuery;
@@ -28,6 +29,7 @@ import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
+import java.util.List;
/**
* Department DTO
@@ -65,6 +67,13 @@ public class DepartmentDTO implements Serializable {
@BindQuery(comparison = Comparison.LT, field = "createTime")
private Date createTimeEnd;
+ @BindQuery(field = "parent_id", comparison = Comparison.IN)
+ private List parentIds;
+
+ @BindQuery(comparison = Comparison.LIKE)
+ @TableField("`character`")
+ private String character;
+
public Date getCreateTimeEnd(){
return D.nextDay(createTime);
}
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/binder/dto/UserDTO.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/dto/UserDTO.java
index 3a5b4f07d7f4e52bcfdaf4d00c78cb660c6a2a6f..5cb77e15c825ed0a741f6066f4128bd9d40cd774 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/binder/dto/UserDTO.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/dto/UserDTO.java
@@ -23,6 +23,9 @@ import diboot.core.test.binder.entity.Organization;
import diboot.core.test.binder.entity.Role;
import diboot.core.test.binder.entity.User;
import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
import java.util.List;
@@ -32,7 +35,8 @@ import java.util.List;
* @version v2.0
* @date 2018/12/27
*/
-@Data
+@Getter
+@Setter
public class UserDTO extends User {
// 字段关联
@@ -45,7 +49,7 @@ public class UserDTO extends User {
// 通过中间表关联Entity
@BindQuery(comparison = Comparison.ENDSWITH, entity = Organization.class, field = "name",
- condition = "this.department_id=department.id AND department.org_id=id AND parent_id=0", strategy = Strategy.INCLUDE_EMPTY_STRING)
+ condition = "this.department_id=department.id AND department.org_id=id AND parent_id=0", strategy = Strategy.INCLUDE_EMPTY)
private String orgName;
// LEFT JOIN department r2m ON self.department_id = r2m.id
// LEFT JOIN organization r1 ON r2m.org_id=r2.id
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/binder/entity/Department.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/entity/Department.java
index 90d9b8f235efce9ecda9aae68e803893bebd5e6f..2715d376641ffbfe1339679f807d9a8ad7f98229 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/binder/entity/Department.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/entity/Department.java
@@ -44,4 +44,7 @@ public class Department extends BaseEntity {
@BindQuery(comparison = Comparison.CONTAINS)
@TableField
private String name;
+
+ @TableField("`character`")
+ private String character;
}
\ No newline at end of file
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/binder/entity/MyBaseEntity.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/entity/MyBaseEntity.java
index 44cf0cfd921750e66a02ddcf159c42dcbc2fa7ec..d602552db1b8e2d221378dda59a4d0fa533eabb4 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/binder/entity/MyBaseEntity.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/entity/MyBaseEntity.java
@@ -35,8 +35,4 @@ public abstract class MyBaseEntity implements Serializable {
updateStrategy = FieldStrategy.NOT_NULL)
private LocalDateTime updateTs;
-
- @Version
- private Integer version;
-
}
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/binder/entity/User.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/entity/User.java
index f264cfa93469badbcc4f3aef9d9660dbcbba36ad..53fdff2297c296ffeb066ace3e48e7fc09fa8232 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/binder/entity/User.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/entity/User.java
@@ -53,4 +53,7 @@ public class User extends BaseEntity {
@JsonFormat(pattern = D.FORMAT_DATE_Y4MD)
private LocalDateTime localDatetime;
+
+ @TableField("`character`")
+ private String character;
}
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/binder/mapper/DbGoodsGoodsInfoMapper.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/mapper/DbGoodsGoodsInfoMapper.java
index 3e2eb470374af7b46b3207823aa663a36d72f70b..58b23154f8a2acd3985aebff498b475343c4f969 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/binder/mapper/DbGoodsGoodsInfoMapper.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/mapper/DbGoodsGoodsInfoMapper.java
@@ -2,7 +2,6 @@ package diboot.core.test.binder.mapper;
import com.diboot.core.mapper.BaseCrudMapper;
import diboot.core.test.binder.entity.DbGoodsGoodsInfo;
-import diboot.core.test.binder.entity.DbPurchaseFormPlan;
import org.apache.ibatis.annotations.Mapper;
/**
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/binder/mapper/DbPurchaseFormPlanMapper.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/mapper/DbPurchaseFormPlanMapper.java
index ac4d71e21ed922ffadc3d9cfc4dcf740cfbcd677..376ccccda4758fb755b8314103144c8d13e91d1e 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/binder/mapper/DbPurchaseFormPlanMapper.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/mapper/DbPurchaseFormPlanMapper.java
@@ -1,6 +1,5 @@
package diboot.core.test.binder.mapper;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.diboot.core.mapper.BaseCrudMapper;
import diboot.core.test.binder.entity.DbPurchaseFormPlan;
import org.apache.ibatis.annotations.Mapper;
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/binder/mapper/DbPurchaseRelPlanGoodsMapper.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/mapper/DbPurchaseRelPlanGoodsMapper.java
index c1856cb611d1fd5f759189c4d78fe84fde89e40d..00d1eff9be0a5c3d2a5c3a4932f60fca585042fe 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/binder/mapper/DbPurchaseRelPlanGoodsMapper.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/mapper/DbPurchaseRelPlanGoodsMapper.java
@@ -1,7 +1,6 @@
package diboot.core.test.binder.mapper;
import com.diboot.core.mapper.BaseCrudMapper;
-import diboot.core.test.binder.entity.DbPurchaseFormPlan;
import diboot.core.test.binder.entity.DbPurchaseRelPlanGoods;
import org.apache.ibatis.annotations.Mapper;
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/binder/service/DbPurchaseFormPlanSvc.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/service/DbPurchaseFormPlanSvc.java
index 7438ac748ea12ff0d87ff4b8f344c06b48aa010b..1685a39dabda92e33c2426eaa0d7bb401755fcf4 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/binder/service/DbPurchaseFormPlanSvc.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/service/DbPurchaseFormPlanSvc.java
@@ -1,6 +1,5 @@
package diboot.core.test.binder.service;
-import com.baomidou.mybatisplus.extension.service.IService;
import com.diboot.core.service.BaseService;
import diboot.core.test.binder.entity.DbPurchaseFormPlan;
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/binder/service/impl/DbPurchaseFormPlanSvcImpl.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/service/impl/DbPurchaseFormPlanSvcImpl.java
index 4e3276408c186acad47e4749154a0c5646e5b444..02396ca4b7dff56b119454e4a0af4060fb2ec3b9 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/binder/service/impl/DbPurchaseFormPlanSvcImpl.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/service/impl/DbPurchaseFormPlanSvcImpl.java
@@ -15,7 +15,6 @@
*/
package diboot.core.test.binder.service.impl;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.diboot.core.service.impl.BaseServiceImpl;
import diboot.core.test.binder.entity.DbPurchaseFormPlan;
import diboot.core.test.binder.mapper.DbPurchaseFormPlanMapper;
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/binder/vo/DeepBindVO.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/vo/DeepBindVO.java
index 760e7c8e42574f104fd51dd03f599552a1c6b6d0..bac3e46431ccaf3724499a789ceeb1230bb75589 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/binder/vo/DeepBindVO.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/vo/DeepBindVO.java
@@ -45,7 +45,7 @@ public class DeepBindVO extends Department{
@BindEntity(entity = Organization.class, condition = "this.org_id=id", deepBind = true) // AND ...
private OrganizationVO organizationVO;
- @BindEntityList(entity = Department.class, condition = "this.id=parent_id AND this.name IS NOT NULL", deepBind = true) // AND ...
+ @BindEntityList(entity = Department.class, condition = "parent_id=this.id AND this.name IS NOT NULL", deepBind = true) // AND ...
private List children;
}
\ No newline at end of file
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/binder/vo/OrganizationVO.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/vo/OrganizationVO.java
index 9aaeaee51bfe53069faf947fa92cef27a1433c28..1be1d3ca8400c0353254bb93e8b33d4950663ee1 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/binder/vo/OrganizationVO.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/vo/OrganizationVO.java
@@ -15,7 +15,6 @@
*/
package diboot.core.test.binder.vo;
-import com.baomidou.mybatisplus.annotation.TableField;
import com.diboot.core.binding.annotation.BindDict;
import com.diboot.core.binding.annotation.BindEntity;
import com.diboot.core.binding.annotation.BindField;
diff --git a/diboot-iam-starter/src/main/java/com/diboot/iam/util/AnnotationUtils.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/vo/SimpleDictionaryVO.java
similarity index 52%
rename from diboot-iam-starter/src/main/java/com/diboot/iam/util/AnnotationUtils.java
rename to diboot-core-starter/src/test/java/diboot/core/test/binder/vo/SimpleDictionaryVO.java
index 64f74c15eceaf35ee8c8985b9421a8ab8d0d3060..a5ec9e4551cc23eee90590f86ef54cdd97c7c7e8 100644
--- a/diboot-iam-starter/src/main/java/com/diboot/iam/util/AnnotationUtils.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/vo/SimpleDictionaryVO.java
@@ -13,16 +13,31 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-package com.diboot.iam.util;
+package diboot.core.test.binder.vo;
+
+import com.diboot.core.binding.annotation.BindEntityList;
+import com.diboot.core.entity.Dictionary;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+
+import java.util.List;
/**
- * 注解相关工具类
- * @author mazc@dibo.ltd
- * @version v2.0
- * @date 2019/12/23
- * @see com.diboot.core.util.AnnotationUtils
+ * 数据字典的简化VO测试类
*/
-@Deprecated
-public class AnnotationUtils extends com.diboot.core.util.AnnotationUtils {
+@Getter
+@Setter
+@Accessors(chain = true)
+public class SimpleDictionaryVO {
+
+ private Long id;
+
+ private String type;
+
+ private String sortId;
+
+ @BindEntityList(entity= Dictionary.class, condition="this.type=type AND this.id=parent_id", orderBy = "sort_id:ASC")
+ private List children;
-}
\ No newline at end of file
+}
diff --git a/diboot-iam-starter/src/main/java/com/diboot/iam/annotation/process/ApiPermissionCache.java b/diboot-core-starter/src/test/java/diboot/core/test/binder/vo/UserEscVO.java
similarity index 37%
rename from diboot-iam-starter/src/main/java/com/diboot/iam/annotation/process/ApiPermissionCache.java
rename to diboot-core-starter/src/test/java/diboot/core/test/binder/vo/UserEscVO.java
index aab2962606c9fe311ae0da57774977eec24cfa96..91433ef56ef24cfaa6511a3c32d04a4525dd6356 100644
--- a/diboot-iam-starter/src/main/java/com/diboot/iam/annotation/process/ApiPermissionCache.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/binder/vo/UserEscVO.java
@@ -13,53 +13,35 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-package com.diboot.iam.annotation.process;
+package diboot.core.test.binder.vo;
-import com.diboot.iam.cache.IamCacheManager;
-
-import java.util.List;
+import com.diboot.core.binding.annotation.BindField;
+import diboot.core.test.binder.entity.Department;
+import diboot.core.test.binder.entity.Organization;
+import diboot.core.test.binder.entity.User;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
/**
- * 注解相关缓存
- * {@link IamCacheManager}
+ *
+ *
* @author mazc@dibo.ltd
* @version v2.0
- * @date 2019/12/30
+ * @date 2019/06/22
*/
-@Deprecated
-public class ApiPermissionCache {
-
- /**
- * 读取缓存permission
- * {@link IamCacheManager#getPermissionCode(String)}
- * @param requestMethodAndUrl
- * @return
- */
- @Deprecated
- public static String getPermissionCode(String requestMethodAndUrl){
- return IamCacheManager.getPermissionCode(requestMethodAndUrl);
- }
+@Getter
+@Setter
+@Accessors(chain = true)
+public class UserEscVO extends User {
+ private static final long serialVersionUID = -5566013299475080343L;
- /**
- * 读取缓存permission
- * {@link IamCacheManager#getPermissionCode(String, String)}
- * @param requestMethod
- * @param url
- * @return
- */
- @Deprecated
- public static String getPermissionCode(String requestMethod, String url){
- return IamCacheManager.getPermissionCode(requestMethod, url);
- }
+ @BindField(entity= Department.class, field="character", condition="this.department_id=id")
+ private String deptCharacter;
- /**
- * 返回全部ApiPermissionVO
- * {@link IamCacheManager#getApiPermissionVoList()}
- * @return
- */
- @Deprecated
- public static List getApiPermissionVoList(){
- return IamCacheManager.getApiPermissionVoList();
- }
+ @BindField(entity = Department.class, field="name", condition="this.`character`=`character`")
+ private String deptName;
-}
\ No newline at end of file
+ @BindField(entity = Organization.class, field="name", condition="this.`character`=department.`character` AND department.org_id=id")
+ private String orgName;
+}
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/query/TestIssue72.java b/diboot-core-starter/src/test/java/diboot/core/test/query/TestIssue72.java
index 3b9db32275a975a4dda5f90a6902ed553a08513a..712e11437948e853b87aed69e3a599a84ec6cf78 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/query/TestIssue72.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/query/TestIssue72.java
@@ -4,11 +4,11 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.binding.QueryBuilder;
import com.diboot.core.vo.Pagination;
import diboot.core.test.StartupApplication;
+import diboot.core.test.binder.dto.PurchaseFormPlanQueryDto;
+import diboot.core.test.binder.entity.DbPurchaseFormPlan;
import diboot.core.test.binder.service.DbPurchaseFormPlanSvc;
import diboot.core.test.binder.vo.DbPurchaseFormPlanVO;
import diboot.core.test.config.SpringMvcConfig;
-import diboot.core.test.binder.entity.DbPurchaseFormPlan;
-import diboot.core.test.binder.dto.PurchaseFormPlanQueryDto;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/query/TestJoinQuery.java b/diboot-core-starter/src/test/java/diboot/core/test/query/TestJoinQuery.java
index c122fbe84a37c77fa9e18a84dfd97664a31a6e48..29ea1103abc5d10e565d45bed09c8a343ee5fb9a 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/query/TestJoinQuery.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/query/TestJoinQuery.java
@@ -61,11 +61,28 @@ public class TestJoinQuery {
Department example = departmentService.list(null).get(0);
DepartmentDTO departmentDTO = new DepartmentDTO();
departmentDTO.setCreateTime(example.getCreateTime());
+ departmentDTO.setCharacter(example.getCharacter());
QueryWrapper queryWrapper = QueryBuilder.toQueryWrapper(departmentDTO);
List list = departmentService.list(queryWrapper);
Assert.assertTrue(list.size() >= 1);
}
+ @Test
+ public void testInQuery(){
+ List parentIds = new ArrayList<>();
+ DepartmentDTO departmentDTO = new DepartmentDTO();
+ departmentDTO.setParentIds(parentIds);
+ QueryWrapper queryWrapper = QueryBuilder.toQueryWrapper(departmentDTO);
+ System.out.println(queryWrapper.getExpression());
+ List list = Binder.joinQueryList(queryWrapper, Department.class);
+ Assert.assertTrue(list.size() > 1);
+
+ parentIds.add(10001L);
+ queryWrapper = QueryBuilder.toQueryWrapper(departmentDTO);
+ list = Binder.joinQueryList(queryWrapper, Department.class);
+ Assert.assertTrue(list.size() > 0);
+ }
+
@Test
public void testSingleTableQuery(){
Department entity = new Department();
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/service/BaseServiceTest.java b/diboot-core-starter/src/test/java/diboot/core/test/service/BaseServiceTest.java
index 690317cfa6623ae1d968f42d5fc2d9a42399155c..a429db4acb5f01616719f49ad5121b1154fd1b5a 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/service/BaseServiceTest.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/service/BaseServiceTest.java
@@ -32,8 +32,12 @@ import com.diboot.core.util.*;
import com.diboot.core.vo.*;
import diboot.core.test.StartupApplication;
import diboot.core.test.binder.entity.CcCityInfo;
+import diboot.core.test.binder.entity.Department;
+import diboot.core.test.binder.entity.User;
import diboot.core.test.binder.entity.UserRole;
+import diboot.core.test.binder.service.DepartmentService;
import diboot.core.test.binder.service.UserService;
+import diboot.core.test.binder.vo.SimpleDictionaryVO;
import diboot.core.test.config.SpringMvcConfig;
import org.junit.Assert;
import org.junit.Test;
@@ -63,6 +67,9 @@ public class BaseServiceTest {
@Autowired
UserService userService;
+ @Autowired
+ DepartmentService departmentService;
+
@Test
public void testGet(){
// 查询总数
@@ -100,6 +107,10 @@ public class BaseServiceTest {
List> mapList = dictionaryService.getMapList(null, new Pagination());
Assert.assertTrue(mapList.size() > 0 && mapList.size() <= BaseConfig.getPageSize());
+ List userIds = Arrays.asList(1001L, 1002L);
+ Map id2NameMap = userService.getId2NameMap(userIds, User::getUsername);
+ Assert.assertTrue(id2NameMap != null);
+ Assert.assertTrue(id2NameMap.get(1001) != null);
}
@Test
@@ -243,6 +254,23 @@ public class BaseServiceTest {
Assert.assertTrue(V.isEmpty(dictionaryList2));
}
+ @Test
+ public void testEscInService(){
+ LambdaQueryWrapper queryWrapper = new QueryWrapper()
+ .lambda().isNotNull(Department::getCharacter);
+ List departments = departmentService.list(queryWrapper);
+ Assert.assertTrue(departments != null);
+ Department dept = (Department) departments.get(0);
+ Assert.assertTrue(dept.getCharacter() != null);
+
+ LambdaQueryWrapper queryWrapperUser = new QueryWrapper()
+ .lambda().isNotNull(User::getCharacter);
+ List users = userService.getEntityList(queryWrapperUser);
+ Assert.assertTrue(users != null);
+ User user = (User) users.get(0);
+ Assert.assertTrue(user.getCharacter() != null);
+ }
+
@Test
public void testJsonResult(){
Map map = new HashMap();
@@ -262,6 +290,12 @@ public class BaseServiceTest {
public void testExist(){
boolean exists = dictionaryService.exists(Dictionary::getType, "GENDER");
Assert.assertTrue(exists);
+
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("type", "GENDER");
+ queryWrapper.eq("item_value", "F");
+ exists = dictionaryService.exists(queryWrapper);
+ Assert.assertTrue(exists);
}
@Test
@@ -340,6 +374,17 @@ public class BaseServiceTest {
List keyValues = dictionaryService.getKeyValueList("GENDER");
Assert.assertTrue(keyValues.size() >= 2);
+
+ }
+
+ @Test
+ public void testSimpleDictVo(){
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("parent_id", 0).eq("type", "GENDER");
+
+ List simpleVOList = dictionaryService.getViewObjectList(queryWrapper, null, SimpleDictionaryVO.class);
+ Assert.assertTrue(simpleVOList.size() == 1);
+ Assert.assertTrue(simpleVOList.get(0).getChildren().size() >= 2);
}
/**
diff --git a/diboot-core-starter/src/test/java/diboot/core/test/util/BeanUtilsTest.java b/diboot-core-starter/src/test/java/diboot/core/test/util/BeanUtilsTest.java
index fbec8cd46ccdf27a56d7ff1a08258fe42ad4a194..aa0b856d4ae553c7ae25c396c60eccd4c692fc49 100644
--- a/diboot-core-starter/src/test/java/diboot/core/test/util/BeanUtilsTest.java
+++ b/diboot-core-starter/src/test/java/diboot/core/test/util/BeanUtilsTest.java
@@ -16,14 +16,26 @@
package diboot.core.test.util;
import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.diboot.core.binding.cache.BindingCacheManager;
import com.diboot.core.entity.Dictionary;
+import com.diboot.core.service.DictionaryService;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.JSON;
import com.diboot.core.vo.DictionaryVO;
+import com.sun.management.OperatingSystemMXBean;
+import diboot.core.test.StartupApplication;
import diboot.core.test.binder.entity.User;
+import diboot.core.test.config.SpringMvcConfig;
import org.junit.Assert;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+import java.lang.management.ManagementFactory;
import java.lang.reflect.Field;
import java.util.*;
@@ -33,7 +45,32 @@ import java.util.*;
* @version v2.0
* @date 2019/06/02
*/
+@RunWith(SpringRunner.class)
+@ContextConfiguration(classes = {SpringMvcConfig.class})
+@SpringBootTest(classes = {StartupApplication.class})
public class BeanUtilsTest {
+ private static OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
+
+ @Autowired
+ private DictionaryService dictionaryService;
+
+ @Test
+ public void testFields(){
+ List fields = BindingCacheManager.getFields(Dictionary.class);
+ Assert.assertTrue(fields.size() > 0);
+ long start = System.currentTimeMillis();
+ for(int i=0; i<10000; i++){
+ Class> dict = BeanUtils.getGenericityClass(dictionaryService, 1);
+ }
+ long end = System.currentTimeMillis() - start;
+ System.out.println(" takes "+ end);
+ start = System.currentTimeMillis();
+ for(int i=0; i<10000; i++){
+ Class> dict = ((IService)dictionaryService).getEntityClass();
+ }
+ end = System.currentTimeMillis() - start;
+ System.out.println(" takes "+ end);
+ }
@Test
public void testCopyBean(){
diff --git a/diboot-core-starter/src/test/resources/application.properties b/diboot-core-starter/src/test/resources/application.properties
new file mode 100644
index 0000000000000000000000000000000000000000..a030edc62bf22ce836fdd1a28da8dbe7026ad0a9
--- /dev/null
+++ b/diboot-core-starter/src/test/resources/application.properties
@@ -0,0 +1,21 @@
+server.port=8080
+server.servlet.context-path=/api
+
+#datasource config
+spring.datasource.url=jdbc:mysql://localhost:3306/playground?characterEncoding=utf8&serverTimezone=GMT%2B8
+spring.datasource.username=diboot
+spring.datasource.password=123456
+spring.datasource.hikari.maximum-pool-size=5
+spring.datasource.hikari.driver-class-name=com.mysql.cj.jdbc.Driver
+
+spring.main.allow-bean-definition-overriding=true
+
+mybatis-plus.global-config.mapper-locations=classpath*:mapper/*Mapper.xml
+mybatis-plus.global-config.db-config.logic-delete-value=1
+mybatis-plus.global-config.db-config.logic-not-delete-value=0
+
+logging.level.root=DEBUG
+logging.level.org.apache=info
+logging.level.org.hibernate.validator=info
+logging.level.org.springframework=info
+logging.level.com.zaxxer.hikari=info
\ No newline at end of file
diff --git a/diboot-core-starter/src/test/resources/init-mysql.sql b/diboot-core-starter/src/test/resources/init-mysql.sql
index 24b760a4602df20a056c6d6fc0f45e763f2f6471..a7cd2f657b745eb311024eb931e6a21336ef044b 100644
--- a/diboot-core-starter/src/test/resources/init-mysql.sql
+++ b/diboot-core-starter/src/test/resources/init-mysql.sql
@@ -25,6 +25,7 @@ create table department
org_id bigint not null comment '单位ID',
name varchar(50) not null comment '名称',
extdata varchar(100) null comment '扩展字段',
+ `character` varchar(100) null comment '关键字',
is_deleted tinyint(1) default 0 not null comment '已删除',
create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间'
)
@@ -59,6 +60,7 @@ create table user
username varchar(20) null,
gender varchar(20) null,
birthdate date null,
+ `character` varchar(100) null comment '关键字',
is_deleted tinyint(1) default 0 null,
create_time timestamp default CURRENT_TIMESTAMP null comment '创建时间',
local_datetime datetime null comment '本地时间'
@@ -83,6 +85,8 @@ create table cc_city_info
CREATE TABLE `db_goods_goods_info` (
`goods_id` bigint DEFAULT NULL,
`goods_nm` varchar(10) DEFAULT NULL,
+ `create_ts` timestamp default CURRENT_TIMESTAMP null,
+ `update_ts` timestamp null,
`is_del` tinyint DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -90,24 +94,28 @@ CREATE TABLE `db_purchase_rel_plan_goods` (
`rel_id` bigint DEFAULT NULL,
`purchase_form_plan_id` bigint DEFAULT NULL,
`goods_id` bigint DEFAULT NULL,
+ `create_ts` timestamp default CURRENT_TIMESTAMP null,
+ `update_ts` timestamp null,
`is_del` tinyint DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `db_purchase_form_plan` (
`purchase_form_plan_id` bigint DEFAULT NULL,
`name` varchar(100) DEFAULT NULL,
- `is_del` tinyint DEFAULT '0'
+ `is_del` tinyint DEFAULT '0',
+ `create_ts` timestamp default CURRENT_TIMESTAMP null,
+ `update_ts` timestamp null
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 初始化样例数据
-INSERT INTO department (id, parent_id, org_id, name) VALUES (10001, 0, 100001, '产品部'), (10002, 10001, 100001, '研发组'), (10003, 10001, 100001, '测试组'),
+INSERT INTO department (id, parent_id, org_id, name, `character`) VALUES (10001, 0, 100001, '产品部', 'CP'), (10002, 10001, 100001, '研发组', 'YF'), (10003, 10001, 100001, '测试组', 'CS'),
(10004, 10001, 100001, 'UI组'), (10005, 10003, 100001, '自动化测试'), (10006, 10003, 100001, '功能测试');
INSERT INTO dictionary (id, parent_id, app_module, type, item_name, item_value) VALUES (1, 0, '', 'GENDER', '性别', null), (2, 1, '', 'GENDER', '男', 'M'), (3, 1, '', 'GENDER', '女', 'F');
INSERT INTO organization (id, parent_id, name, telphone, manager_id) VALUES (100001, 0, '苏州帝博', '0512-62988949', 1001), (100002, 0, '成都帝博', null, null);
INSERT INTO role (id, name, code) VALUES (101, '管理员', 'ADMIN'), (102, '操作员', 'OPERATOR');
-INSERT INTO user (id, department_id, username, gender) VALUES (1001, 10002, '张三', 'M'), (1002, 10002, '李四', 'F');
+INSERT INTO user (id, department_id, username, gender, `character`) VALUES (1001, 10002, '张三', 'M', 'ZS'), (1002, 10002, '李四', 'F', 'LS');
INSERT INTO user_role (user_type, user_id, role_id) VALUES ('SysUser', 1001, 101),('SysUser', 1001, 102),('OrgUser', 1002, 102);
INSERT INTO cc_city_info (id, parent_id, region_id, region_name) VALUES (10000, 0, 10000, '江苏省'), (10010, 10000, 10010, '苏州市'), (10020, 10010, 10020, '园区');
INSERT INTO db_goods_goods_info (goods_id, goods_nm, is_del) VALUES(1001, 'abcde', 0), (1002, 'abcd', 0);
INSERT INTO db_purchase_rel_plan_goods(rel_id, purchase_form_plan_id, goods_id, is_del)VALUES(1, 1, 1001, 0), (2, 1, 1002, 0);
-INSERT INTO db_purchase_form_plan(plan_id, name, is_del)VALUES(1, '5月份采购计划', 0);
+INSERT INTO db_purchase_form_plan(purchase_form_plan_id, name, is_del)VALUES(1, '5月份采购计划', 0);
diff --git a/diboot-core/pom.xml b/diboot-core/pom.xml
index a0a717661b989c0f96bc1a99119ecabdb06c97ed..9a77620ab27b5cac92064fcdd2ae88e302d0cb86 100644
--- a/diboot-core/pom.xml
+++ b/diboot-core/pom.xml
@@ -7,11 +7,11 @@
com.diboot
diboot-root
- 2.2.1
+ 2.3.0
diboot-core
- 2.2.1
+ 2.3.0
jar
diboot core project
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/QueryBuilder.java b/diboot-core/src/main/java/com/diboot/core/binding/QueryBuilder.java
index 73e55b0607a7a44258fcaa6ae34db107db77270d..aff890937ae58a3396c4c65ab9efecc15517a029 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/QueryBuilder.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/QueryBuilder.java
@@ -21,7 +21,6 @@ import com.baomidou.mybatisplus.core.conditions.ISqlSegment;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.segments.NormalSegmentList;
-import com.diboot.core.binding.cache.BindingCacheManager;
import com.diboot.core.binding.parser.ParserCache;
import com.diboot.core.binding.query.BindQuery;
import com.diboot.core.binding.query.Comparison;
@@ -155,11 +154,17 @@ public class QueryBuilder {
continue;
}
Object value = entry.getValue();
- // 处理空字符串""
- if(value instanceof String && S.isEmpty((String)value)){
- if(query != null && query.strategy().equals(Strategy.IGNORE_EMPTY_STRING)){
+ if(query != null && query.strategy().equals(Strategy.IGNORE_EMPTY)){
+ // 处理空字符串""
+ if(value instanceof String && S.isEmpty((String)value)){
continue;
}
+ if(value instanceof Collection){
+ Collection valueList = (Collection)value;
+ if(valueList.size() == 0){
+ continue;
+ }
+ }
}
// 对比类型
Comparison comparison = Comparison.EQ;
@@ -251,15 +256,20 @@ public class QueryBuilder {
}
}
// 支持逗号分隔的字符串
- else if(value instanceof String && ((String) value).contains(",")){
- Object[] valueArray = ((String) value).split(",");
+ else if(value instanceof String && ((String) value).contains(Cons.SEPARATOR_COMMA)){
+ Object[] valueArray = ((String) value).split(Cons.SEPARATOR_COMMA);
wrapper.between(columnName, valueArray[0], valueArray[1]);
}
else{
wrapper.ge(columnName, value);
}
break;
+ // 不等于
+ case NOT_EQ:
+ wrapper.ne(columnName, value);
+ break;
default:
+ break;
}
}
return wrapper;
@@ -297,7 +307,6 @@ public class QueryBuilder {
private static LinkedHashMap extractNotNullValues(DTO dto, Collection fields){
LinkedHashMap resultMap = new LinkedHashMap<>();
Class> dtoClass = dto.getClass();
-
// 转换
List declaredFields = BeanUtils.extractAllFields(dtoClass);
for (Field field : declaredFields) {
@@ -328,7 +337,7 @@ public class QueryBuilder {
} catch (IllegalAccessException e) {
log.error("通过反射获取属性值出错:{}", e.getMessage());
} catch (NoSuchMethodException e) {
- log.warn("通过反射获取属性方法不存在:{}", e.getMessage());
+ log.debug("通过反射获取属性方法不存在:{}", e.getMessage());
} catch (InvocationTargetException e) {
log.warn("通过反射执行属性方法出错:{}", e.getMessage());
}
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/binder/BaseBinder.java b/diboot-core/src/main/java/com/diboot/core/binding/binder/BaseBinder.java
index 5b60d061d94bf2a7eb85866e0928676ffca20792..ea53148c87b1ef074b7383ccb557381040a36bb7 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/binder/BaseBinder.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/binder/BaseBinder.java
@@ -19,6 +19,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.diboot.core.binding.cache.BindingCacheManager;
+import com.diboot.core.binding.helper.ResultAssembler;
import com.diboot.core.binding.parser.MiddleTable;
import com.diboot.core.binding.parser.PropInfo;
import com.diboot.core.config.BaseConfig;
@@ -92,7 +93,7 @@ public abstract class BaseBinder {
this.annoObjPropInfo = BindingCacheManager.getPropInfoByClass(voList.get(0).getClass());
}
this.queryWrapper = new QueryWrapper<>();
- this.referencedEntityClass = BeanUtils.getGenericityClass(referencedService, 1);
+ this.referencedEntityClass = referencedService.getEntityClass();
this.refObjPropInfo = BindingCacheManager.getPropInfoByClass(this.referencedEntityClass);
// 列集合
this.annoObjJoinCols = new ArrayList<>(8);
@@ -256,6 +257,11 @@ public abstract class BaseBinder {
}
}
+ /**
+ * 简化select列,仅select必需列
+ */
+ protected abstract void simplifySelectColumns();
+
/**
* 获取EntityList
* @param queryWrapper
@@ -308,16 +314,7 @@ public abstract class BaseBinder {
* @return
*/
protected Object getValueIgnoreKeyCase(Map map, String key){
- if(key == null){
- return null;
- }
- if(map.containsKey(key)){
- return map.get(key);
- }
- if(map.containsKey(key.toUpperCase())){
- return map.get(key.toUpperCase());
- }
- return null;
+ return ResultAssembler.getValueIgnoreKeyCase(map, key);
}
/**
@@ -344,10 +341,10 @@ public abstract class BaseBinder {
* 注解宿主对象的列名转换为字段名
* @return
*/
- public List getAnnoObjJoinFlds(){
- List fields = new ArrayList<>(annoObjJoinCols.size());
- for(String col : annoObjJoinCols){
- fields.add(toAnnoObjField(col));
+ public String[] getAnnoObjJoinFlds(){
+ String[] fields = new String[annoObjJoinCols.size()];
+ for(int i=0; i extends BaseBinder {
}
// 直接关联Entity
if(middleTable == null){
+ simplifySelectColumns();
// @BindEntity(entity = Department.class, condition="this.department_id=id AND this.type=type")
// Department department;
super.buildQueryWrapperJoinOn();
@@ -109,6 +112,7 @@ public class EntityBinder extends BaseBinder {
Map valueEntityMap = new HashMap<>();
Map middleTableResultMap = middleTable.executeOneToOneQuery(trunkObjCol2ValuesMap);
if(V.notEmpty(middleTableResultMap)){
+ simplifySelectColumns();
// 提取entity主键值集合
Collection refObjValues = middleTableResultMap.values().stream().distinct().collect(Collectors.toList());
// 构建查询条件
@@ -145,21 +149,26 @@ public class EntityBinder extends BaseBinder {
*/
private Map buildMatchKey2EntityMap(List list){
Map key2TargetMap = new HashMap<>(list.size());
- List joinOnValues = new ArrayList<>(refObjJoinCols.size());
+ StringBuilder sb = new StringBuilder();
for(T entity : list){
- joinOnValues.clear();
- for(String refObjJoinOnCol : refObjJoinCols){
+ sb.setLength(0);
+ for(int i=0; i 0){
+ sb.append(Cons.SEPARATOR_COMMA);
+ }
+ sb.append(pkValue);
}
- String matchKey = S.join(joinOnValues);
-
+ // 查找匹配Key
+ String matchKey = sb.toString();
Object target = entity;
if(target instanceof Map == false){
target = cloneOrConvertBean(entity);
}
key2TargetMap.put(matchKey, target);
}
+ sb.setLength(0);
return key2TargetMap;
}
@@ -178,4 +187,15 @@ public class EntityBinder extends BaseBinder {
return BeanUtils.convert(value, annoObjectFieldClass);
}
}
+
+ /**
+ * 简化select列,仅select必需列
+ */
+ @Override
+ protected void simplifySelectColumns(){
+ if(!referencedEntityClass.getName().equals(annoObjectFieldClass.getName())){
+ queryWrapper = (QueryWrapper) ServiceAdaptor.optimizeSelect(queryWrapper, referencedEntityClass, annoObjectFieldClass);
+ }
+ }
+
}
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/binder/EntityListBinder.java b/diboot-core/src/main/java/com/diboot/core/binding/binder/EntityListBinder.java
index 0a89ab54391ac340558632e3381e4bf8e66f73ea..d42e3c3f3115d6f36a4ae371cbcddeadfc79fdce 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/binder/EntityListBinder.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/binder/EntityListBinder.java
@@ -67,6 +67,7 @@ public class EntityListBinder extends EntityBinder {
}
Map valueEntityListMap = new HashMap<>();
if(middleTable == null){
+ super.simplifySelectColumns();
super.buildQueryWrapperJoinOn();
//处理orderBy,附加排序
this.appendOrderBy();
@@ -87,6 +88,7 @@ public class EntityListBinder extends EntityBinder {
if(V.isEmpty(middleTableResultMap)){
return;
}
+ super.simplifySelectColumns();
// 收集查询结果values集合
List entityIdList = extractIdValueFromMap(middleTableResultMap);
// 构建查询条件
@@ -128,14 +130,19 @@ public class EntityListBinder extends EntityBinder {
*/
private Map buildMatchKey2EntityListMap(List list){
Map key2TargetListMap = new HashMap<>(list.size());
- List joinOnValues = new ArrayList<>(refObjJoinCols.size());
+ StringBuilder sb = new StringBuilder();
for(T entity : list){
- joinOnValues.clear();
- for(String refObjJoinOnCol : refObjJoinCols){
+ sb.setLength(0);
+ for(int i=0; i 0){
+ sb.append(Cons.SEPARATOR_COMMA);
+ }
+ sb.append(pkValue);
}
- String matchKey = S.join(joinOnValues);
+ // 查找匹配Key
+ String matchKey = sb.toString();
// 获取list
List entityList = key2TargetListMap.get(matchKey);
if(entityList == null){
@@ -148,6 +155,7 @@ public class EntityListBinder extends EntityBinder {
}
entityList.add(target);
}
+ sb.setLength(0);
return key2TargetListMap;
}
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/binder/FieldBinder.java b/diboot-core/src/main/java/com/diboot/core/binding/binder/FieldBinder.java
index 50a7c4423ccb21af627271034776dc50b0c54860..94507cba02a011a879b56fb34e6319177ca0c54e 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/binder/FieldBinder.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/binder/FieldBinder.java
@@ -16,8 +16,7 @@
package com.diboot.core.binding.binder;
import com.baomidou.mybatisplus.extension.service.IService;
-import com.diboot.core.binding.cache.BindingCacheManager;
-import com.diboot.core.binding.parser.PropInfo;
+import com.diboot.core.config.Cons;
import com.diboot.core.exception.BusinessException;
import com.diboot.core.util.*;
import org.slf4j.Logger;
@@ -71,11 +70,11 @@ public class FieldBinder extends BaseBinder {
*/
public FieldBinder link(String fromDoField, String toVoField){
if(annoObjectSetterPropNameList == null){
- annoObjectSetterPropNameList = new ArrayList<>();
+ annoObjectSetterPropNameList = new ArrayList<>(8);
}
annoObjectSetterPropNameList.add(toVoField);
if(referencedGetterFieldNameList == null){
- referencedGetterFieldNameList = new ArrayList<>();
+ referencedGetterFieldNameList = new ArrayList<>(8);
}
referencedGetterFieldNameList.add(fromDoField);
return this;
@@ -96,7 +95,7 @@ public class FieldBinder extends BaseBinder {
}
// 直接关联
if(middleTable == null){
- this.buildSelectColumns();
+ this.simplifySelectColumns();
super.buildQueryWrapperJoinOn();
// 获取匹配结果的mapList
List> mapList = getMapList(queryWrapper);
@@ -124,7 +123,7 @@ public class FieldBinder extends BaseBinder {
}
// 收集查询结果values集合
Collection refObjValues = middleTableResultMap.values().stream().distinct().collect(Collectors.toList());
- this.buildSelectColumns();
+ this.simplifySelectColumns();
// 构建查询条件
String refObjJoinOnCol = refObjJoinCols.get(0);
queryWrapper.in(refObjJoinOnCol, refObjValues);
@@ -187,13 +186,17 @@ public class FieldBinder extends BaseBinder {
* @return
*/
private String buildMatchKey(Object annoObject){
- List joinOnValues = new ArrayList<>(annoObjJoinCols.size());
- for(String annoJoinOn : annoObjJoinCols){
+ StringBuilder sb = new StringBuilder();
+ for(int i=0; i 0){
+ sb.append(Cons.SEPARATOR_COMMA);
+ }
+ sb.append(val);
}
- return S.join(joinOnValues);
+ return sb.toString();
}
/**
@@ -203,7 +206,8 @@ public class FieldBinder extends BaseBinder {
* @return
*/
private String buildMatchKey(Object annoObject, Map middleTableResultMap){
- List joinOnValues = new ArrayList<>(middleTable.getTrunkObjColMapping().size());
+ StringBuilder sb = new StringBuilder();
+ boolean appendComma = false;
for(Map.Entry entry : middleTable.getTrunkObjColMapping().entrySet()){
String getterField = toAnnoObjField(entry.getKey());
String fieldValue = BeanUtils.getStringProperty(annoObject, getterField);
@@ -212,17 +216,29 @@ public class FieldBinder extends BaseBinder {
Object value = middleTableResultMap.get(fieldValue);
fieldValue = String.valueOf(value);
}
- joinOnValues.add(fieldValue);
+ if(appendComma){
+ sb.append(Cons.SEPARATOR_COMMA);
+ }
+ sb.append(fieldValue);
+ if(appendComma == false){
+ appendComma = true;
+ }
}
// 查找匹配Key
- return S.join(joinOnValues);
+ return sb.toString();
}
- protected void buildSelectColumns(){
- List selectColumns = new ArrayList<>();
+ @Override
+ protected void simplifySelectColumns() {
+ List selectColumns = new ArrayList<>(8);
selectColumns.addAll(refObjJoinCols);
- for(String referencedGetterField : referencedGetterFieldNameList){
- selectColumns.add(toRefObjColumn(referencedGetterField));
+ if(V.notEmpty(referencedGetterFieldNameList)){
+ for(String referencedGetterField : referencedGetterFieldNameList){
+ String refObjCol = toRefObjColumn(referencedGetterField);
+ if(!selectColumns.contains(refObjCol)){
+ selectColumns.add(refObjCol);
+ }
+ }
}
queryWrapper.select(S.toStringArray(selectColumns));
}
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/binder/FieldListBinder.java b/diboot-core/src/main/java/com/diboot/core/binding/binder/FieldListBinder.java
index 8197290014610d98d70b3505fb2fda146a76102d..425ab3e303866fe7085af71139035f5feb36cefa 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/binder/FieldListBinder.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/binder/FieldListBinder.java
@@ -16,9 +16,9 @@
package com.diboot.core.binding.binder;
import com.baomidou.mybatisplus.extension.service.IService;
+import com.diboot.core.config.Cons;
import com.diboot.core.exception.BusinessException;
import com.diboot.core.util.BeanUtils;
-import com.diboot.core.util.S;
import com.diboot.core.util.V;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,9 +60,9 @@ public class FieldListBinder extends FieldBinder {
return;
}
Map valueEntityListMap = new HashMap<>();
- super.buildSelectColumns();
// 直接关联
if(middleTable == null){
+ super.simplifySelectColumns();
super.buildQueryWrapperJoinOn();
// 查询entity列表: List
List list = getEntityList(queryWrapper);
@@ -84,6 +84,7 @@ public class FieldListBinder extends FieldBinder {
if(V.isEmpty(middleTableResultMap)){
return;
}
+ super.simplifySelectColumns();
// 收集查询结果values集合
List entityIdList = extractIdValueFromMap(middleTableResultMap);
// 构建查询条件
@@ -127,16 +128,20 @@ public class FieldListBinder extends FieldBinder {
if(V.isEmpty(fromList) || V.isEmpty(valueMatchMap)){
return;
}
- List fieldValues = new ArrayList<>(annoObjJoinCols.size());
+ StringBuilder sb = new StringBuilder();
try{
for(E object : fromList){
- fieldValues.clear();
- for(String annoObjJoinCol : annoObjJoinCols){
- String fieldValue = BeanUtils.getStringProperty(object, toAnnoObjField(annoObjJoinCol));
- fieldValues.add(fieldValue);
+ sb.setLength(0);
+ for(int i=0; i0){
+ sb.append(Cons.SEPARATOR_COMMA);
+ }
+ sb.append(val);
}
// 查找匹配Key
- String matchKey = S.join(fieldValues);
+ String matchKey = sb.toString();
List entityList = valueMatchMap.get(matchKey);
if(entityList != null){
// 赋值
@@ -146,6 +151,7 @@ public class FieldListBinder extends FieldBinder {
}
}
}
+ sb.setLength(0);
}
catch (Exception e){
log.warn("设置属性值异常", e);
@@ -163,18 +169,24 @@ public class FieldListBinder extends FieldBinder {
if(V.isEmpty(fromList) || V.isEmpty(valueMatchMap)){
return;
}
- List fieldValues = new ArrayList<>(trunkObjColMapping.size());
+ StringBuilder sb = new StringBuilder();
try{
for(E object : fromList){
- fieldValues.clear();
+ boolean appendComma = false;
+ sb.setLength(0);
for(Map.Entry entry :trunkObjColMapping.entrySet()){
String getterField = toAnnoObjField(entry.getKey());
String fieldValue = BeanUtils.getStringProperty(object, getterField);
- fieldValues.add(fieldValue);
+ if(appendComma){
+ sb.append(Cons.SEPARATOR_COMMA);
+ }
+ sb.append(fieldValue);
+ if(appendComma == false){
+ appendComma = true;
+ }
}
// 查找匹配Key
- String matchKey = S.join(fieldValues);
- List entityList = valueMatchMap.get(matchKey);
+ List entityList = valueMatchMap.get(sb.toString());
if(entityList != null){
// 赋值
for(int i = 0; i< annoObjectSetterPropNameList.size(); i++){
@@ -196,14 +208,18 @@ public class FieldListBinder extends FieldBinder {
*/
private Map buildMatchKey2FieldListMap(List list){
Map key2TargetListMap = new HashMap<>(list.size());
- List joinOnValues = new ArrayList<>(refObjJoinCols.size());
+ StringBuilder sb = new StringBuilder();
for(T entity : list){
- joinOnValues.clear();
- for(String refObjJoinOnCol : refObjJoinCols){
+ sb.setLength(0);
+ for(int i=0; i 0){
+ sb.append(Cons.SEPARATOR_COMMA);
+ }
+ sb.append(fldValue);
}
- String matchKey = S.join(joinOnValues);
+ String matchKey = sb.toString();
// 获取list
List entityList = key2TargetListMap.get(matchKey);
if(entityList == null){
@@ -212,6 +228,7 @@ public class FieldListBinder extends FieldBinder {
}
entityList.add(entity);
}
+ sb.setLength(0);
return key2TargetListMap;
}
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/cache/BindingCacheManager.java b/diboot-core/src/main/java/com/diboot/core/binding/cache/BindingCacheManager.java
index 1ad590922eef6cfebf3f34e6110790f9e11eb1aa..f3df6bf607be09e13dc2b77fc355c95d1515039a 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/cache/BindingCacheManager.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/cache/BindingCacheManager.java
@@ -23,17 +23,17 @@ import com.diboot.core.binding.parser.PropInfo;
import com.diboot.core.cache.StaticMemoryCacheManager;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.ContextHelper;
+import com.diboot.core.util.S;
import com.diboot.core.util.V;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.context.annotation.Primary;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
/**
* CacheManager
@@ -63,6 +63,14 @@ public class BindingCacheManager {
* Entity类的SimpleName-Entity Class的缓存key
*/
private static final String CACHE_NAME_ENTITYNAME_CLASS = "NAME_CLASS";
+ /**
+ * 类-fields缓存
+ */
+ private static final String CACHE_NAME_CLASS_FIELDS = "CLASS_FIELDS";
+ /**
+ * 类- name-field Map缓存
+ */
+ private static final String CACHE_NAME_CLASS_NAME2FLDMAP = "CLASS_NAME2FLDMAP";
private static StaticMemoryCacheManager getCacheManager(){
if(cacheManager == null){
@@ -70,7 +78,9 @@ public class BindingCacheManager {
CACHE_NAME_CLASS_ENTITY,
CACHE_NAME_TABLE_ENTITY,
CACHE_NAME_CLASS_PROP,
- CACHE_NAME_ENTITYNAME_CLASS);
+ CACHE_NAME_ENTITYNAME_CLASS,
+ CACHE_NAME_CLASS_FIELDS,
+ CACHE_NAME_CLASS_NAME2FLDMAP);
}
return cacheManager;
}
@@ -168,6 +178,50 @@ public class BindingCacheManager {
return null;
}
+ /**
+ * 获取class的fields
+ * @param beanClazz
+ * @return
+ */
+ public static List getFields(Class> beanClazz){
+ List fields = getCacheManager().getCacheObj(CACHE_NAME_CLASS_FIELDS, beanClazz.getName(), List.class);
+ if(fields == null){
+ fields = initClassFields(beanClazz, null);
+ getCacheManager().putCacheObj(CACHE_NAME_CLASS_FIELDS, beanClazz.getName(), fields);
+ }
+ return fields;
+ }
+
+ /**
+ * 获取class中包含指定注解的的fields
+ * @param beanClazz
+ * @return
+ */
+ public static List getFields(Class> beanClazz, Class extends Annotation> annotation){
+ String key = S.join(beanClazz.getName(), annotation.getClass().getName());
+ List fields = getCacheManager().getCacheObj(CACHE_NAME_CLASS_FIELDS, key, List.class);
+ if(fields == null){
+ fields = initClassFields(beanClazz, annotation);
+ getCacheManager().putCacheObj(CACHE_NAME_CLASS_FIELDS, key, fields);
+ }
+ return fields;
+ }
+
+ /**
+ * 获取class的fields
+ * @param beanClazz
+ * @return
+ */
+ public static Map getFieldsMap(Class> beanClazz){
+ Map fieldsMap = getCacheManager().getCacheObj(CACHE_NAME_CLASS_NAME2FLDMAP, beanClazz.getName(), Map.class);
+ if(fieldsMap == null){
+ List fields = getFields(beanClazz);
+ fieldsMap = BeanUtils.convertToStringKeyObjectMap(fields, "name");
+ getCacheManager().putCacheObj(CACHE_NAME_CLASS_NAME2FLDMAP, beanClazz.getName(), fieldsMap);
+ }
+ return fieldsMap;
+ }
+
/**
* 初始化
*/
@@ -248,8 +302,44 @@ public class BindingCacheManager {
*/
private static PropInfo initPropInfoCache(Class> beanClazz) {
PropInfo propInfoCache = new PropInfo(beanClazz);
- cacheManager.putCacheObj(CACHE_NAME_CLASS_PROP, beanClazz.getName(), propInfoCache);
+ getCacheManager().putCacheObj(CACHE_NAME_CLASS_PROP, beanClazz.getName(), propInfoCache);
return propInfoCache;
}
+ /**
+ * 初始化fields
+ * @param beanClazz
+ * @return
+ */
+ private static List initClassFields(Class> beanClazz, Class extends Annotation> annotation){
+ List fieldList = new ArrayList<>();
+ Set fieldNameSet = new HashSet<>();
+ loopFindFields(beanClazz, annotation, fieldList, fieldNameSet);
+ return fieldList;
+ }
+
+ /**
+ * 循环向上查找fields
+ * @param beanClazz
+ * @param annotation
+ * @param fieldList
+ * @param fieldNameSet
+ */
+ private static void loopFindFields(Class> beanClazz, Class extends Annotation> annotation, List fieldList, Set fieldNameSet){
+ if(beanClazz == null) {
+ return;
+ }
+ Field[] fields = beanClazz.getDeclaredFields();
+ if(V.notEmpty(fields)){ //被重写属性,以子类override的为准
+ Arrays.stream(fields).forEach((field)->{
+ if(!fieldNameSet.contains(field.getName()) &&
+ (annotation == null || field.getAnnotation(annotation) != null)){
+ fieldList.add(field);
+ fieldNameSet.add(field.getName());
+ }
+ });
+ }
+ loopFindFields(beanClazz.getSuperclass(), annotation, fieldList, fieldNameSet);
+ }
+
}
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/copy/AcceptAnnoCopier.java b/diboot-core/src/main/java/com/diboot/core/binding/copy/AcceptAnnoCopier.java
index 9125db2184cd511070fc923bb8bf9aa893492d6e..e27ff1545e9f7360ca26935e713e0fedb60988f0 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/copy/AcceptAnnoCopier.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/copy/AcceptAnnoCopier.java
@@ -37,7 +37,7 @@ public class AcceptAnnoCopier {
/**
* 注解缓存
*/
- private static Map> CLASS_ACCEPT_ANNO_CACHE_MAP = new ConcurrentHashMap<>();
+ private static final Map> CLASS_ACCEPT_ANNO_CACHE_MAP = new ConcurrentHashMap<>();
// 下标
private static final int IDX_TARGET_FIELD = 0, IDX_SOURCE_FIELD = 1, IDX_OVERRIDE = 2;
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/data/DataAccessAnnoCache.java b/diboot-core/src/main/java/com/diboot/core/binding/data/DataAccessAnnoCache.java
index 469a69afe79d0c2e019f169c1caa140179dc26d0..54735985a8cadd22fe74f8cff5c25c3d32497189 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/data/DataAccessAnnoCache.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/data/DataAccessAnnoCache.java
@@ -38,7 +38,7 @@ public class DataAccessAnnoCache {
/**
* 注解缓存
*/
- private static Map DATA_PERMISSION_ANNO_CACHE = new ConcurrentHashMap<>();
+ private static final Map DATA_PERMISSION_ANNO_CACHE = new ConcurrentHashMap<>();
/**
* 是否有检查点注解
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/helper/ResultAssembler.java b/diboot-core/src/main/java/com/diboot/core/binding/helper/ResultAssembler.java
index 074084cbe0aaca9acf768d34bf4a0322687534b9..a09a1a4b530e517b8ab6b58afb4b2a612fa2f19e 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/helper/ResultAssembler.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/helper/ResultAssembler.java
@@ -15,6 +15,7 @@
*/
package com.diboot.core.binding.helper;
+import com.diboot.core.config.Cons;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.S;
import com.diboot.core.util.V;
@@ -39,25 +40,29 @@ public class ResultAssembler {
* @param valueMatchMap
* @param
*/
- public static void bindPropValue(String setterFieldName, List fromList, List getterFields, Map valueMatchMap){
+ public static void bindPropValue(String setterFieldName, List fromList, String[] getterFields, Map valueMatchMap){
if(V.isEmpty(fromList) || V.isEmpty(valueMatchMap)){
return;
}
- List fieldValues = new ArrayList<>(getterFields.size());
+ StringBuilder sb = new StringBuilder();
try{
for(E object : fromList){
- fieldValues.clear();
- for(String getterField : getterFields){
- String fieldValue = BeanUtils.getStringProperty(object, getterField);
- fieldValues.add(fieldValue);
+ sb.setLength(0);
+ for(int i=0; i 0){
+ sb.append(Cons.SEPARATOR_COMMA);
+ }
+ sb.append(fieldValue);
}
// 查找匹配Key
- String matchKey = S.join(fieldValues);
+ String matchKey = sb.toString();
if(valueMatchMap.containsKey(matchKey)){
// 赋值
BeanUtils.setProperty(object, setterFieldName, valueMatchMap.get(matchKey));
}
}
+ sb.setLength(0);
}
catch (Exception e){
log.warn("设置属性值异常, setterFieldName="+setterFieldName, e);
@@ -76,10 +81,11 @@ public class ResultAssembler {
if(V.isEmpty(fromList) || V.isEmpty(valueMatchMap)){
return;
}
- List fieldValues = new ArrayList<>(trunkObjColMapping.size());
+ StringBuilder sb = new StringBuilder();
try{
for(E object : fromList){
- fieldValues.clear();
+ boolean appendComma = false;
+ sb.setLength(0);
for(Map.Entry entry :trunkObjColMapping.entrySet()){
//转换为字段名
String getterField = col2FieldMapping.get(entry.getKey());
@@ -87,16 +93,22 @@ public class ResultAssembler {
getterField = S.toLowerCaseCamel(entry.getKey());
}
String fieldValue = BeanUtils.getStringProperty(object, getterField);
- fieldValues.add(fieldValue);
+ if(appendComma){
+ sb.append(Cons.SEPARATOR_COMMA);
+ }
+ sb.append(fieldValue);
+ if(appendComma == false){
+ appendComma = true;
+ }
}
// 查找匹配Key
- String matchKey = S.join(fieldValues);
+ String matchKey = sb.toString();
if(valueMatchMap.containsKey(matchKey)){
// 赋值
BeanUtils.setProperty(object, setterFieldName, valueMatchMap.get(matchKey));
}
}
- fieldValues.clear();
+ sb.setLength(0);
}
catch (Exception e){
log.warn("设置属性值异常, setterFieldName="+setterFieldName, e);
@@ -118,15 +130,22 @@ public class ResultAssembler {
// 获取valueName
String valueName = branchObjColMapping.entrySet().iterator().next().getKey();
// 合并list为map
- Map resultMap = new HashMap<>();
- List fieldValues = new ArrayList<>(trunkObjColMapping.size());
+ Map resultMap = new HashMap<>(resultSetMapList.size());
+ StringBuilder sb = new StringBuilder();
for(Map row : resultSetMapList){
- fieldValues.clear();
+ boolean appendComma = false;
+ sb.setLength(0);
for(Map.Entry entry : trunkObjColMapping.entrySet()){
- Object keyObj = row.containsKey(entry.getValue())? row.get(entry.getValue()) : row.get(entry.getValue().toUpperCase());
- fieldValues.add(S.valueOf(keyObj));
+ Object keyObj = getValueIgnoreKeyCase(row, entry.getValue());
+ if(appendComma){
+ sb.append(Cons.SEPARATOR_COMMA);
+ }
+ sb.append(S.valueOf(keyObj));
+ if(appendComma == false){
+ appendComma = true;
+ }
}
- String matchKeys = S.join(fieldValues);
+ String matchKeys = sb.toString();
Object valueObj = row.containsKey(valueName)? row.get(valueName) : row.get(valueName.toUpperCase());
resultMap.put(matchKeys, valueObj);
}
@@ -149,14 +168,21 @@ public class ResultAssembler {
String valueName = branchObjColMapping.entrySet().iterator().next().getKey();
// 合并list为map
Map resultMap = new HashMap<>();
- List fieldValues = new ArrayList<>(trunkObjColMapping.size());
+ StringBuilder sb = new StringBuilder();
for(Map row : resultSetMapList){
- fieldValues.clear();
+ boolean appendComma = false;
+ sb.setLength(0);
for(Map.Entry entry : trunkObjColMapping.entrySet()){
- Object keyObj = row.containsKey(entry.getValue())? row.get(entry.getValue()) : row.get(entry.getValue().toUpperCase());
- fieldValues.add(S.valueOf(keyObj));
+ Object keyObj = getValueIgnoreKeyCase(row, entry.getValue());
+ if(appendComma){
+ sb.append(Cons.SEPARATOR_COMMA);
+ }
+ sb.append(S.valueOf(keyObj));
+ if(appendComma == false){
+ appendComma = true;
+ }
}
- String matchKeys = S.join(fieldValues);
+ String matchKeys = sb.toString();
Object valueObj = row.containsKey(valueName)? row.get(valueName) : row.get(valueName.toUpperCase());
if(valueObj != null){
List valueList = resultMap.get(matchKeys);
@@ -167,7 +193,29 @@ public class ResultAssembler {
valueList.add(valueObj);
}
}
+ sb.setLength(0);
return resultMap;
}
+
+ /**
+ * 从map中取值,如直接取为null尝试转换大写后再取,以支持ORACLE等大写命名数据库
+ * @param map
+ * @param key
+ * @return
+ */
+ public static Object getValueIgnoreKeyCase(Map map, String key){
+ if(map == null || key == null){
+ return null;
+ }
+ key = S.removeEsc(key);
+ if(map.containsKey(key)){
+ return map.get(key);
+ }
+ if(map.containsKey(key.toUpperCase())){
+ return map.get(key.toUpperCase());
+ }
+ return null;
+ }
+
}
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/helper/ServiceAdaptor.java b/diboot-core/src/main/java/com/diboot/core/binding/helper/ServiceAdaptor.java
index da3ffe915415db5aa0858a5794bf522e1c7badfa..b4c092227765738797c35995fac88af23756f1a3 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/helper/ServiceAdaptor.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/helper/ServiceAdaptor.java
@@ -15,16 +15,25 @@
*/
package com.diboot.core.binding.helper;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
+import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
+import com.diboot.core.binding.cache.BindingCacheManager;
import com.diboot.core.config.Cons;
import com.diboot.core.service.BaseService;
import com.diboot.core.util.ContextHelper;
+import com.diboot.core.util.S;
+import com.diboot.core.util.V;
import com.diboot.core.vo.Pagination;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
/**
* Service适配器
@@ -86,7 +95,7 @@ public class ServiceAdaptor {
IPage page = convertToIPage(pagination, entityClass);
page = iService.page(page, queryWrapper);
// 如果重新执行了count进行查询,则更新pagination中的总数
- if(page.isSearchCount()){
+ if(page.searchCount()){
pagination.setTotalCount(page.getTotal());
}
return page.getRecords();
@@ -118,7 +127,38 @@ public class ServiceAdaptor {
pagination.setDefaultCreateTimeOrderBy();
}
}
- return (Page)pagination.toPage();
+ return pagination.toPage();
+ }
+
+ /**
+ * 基于VO提取最小集select字段
+ * @param queryWrapper
+ * @param voClass
+ */
+ public static Wrapper optimizeSelect(Wrapper queryWrapper, Class entityClass, Class> voClass){
+ if(!(queryWrapper instanceof QueryWrapper) || queryWrapper.getSqlSelect() != null){
+ return queryWrapper;
+ }
+ List allColumns = TableInfoHelper.getTableInfo(entityClass).getFieldList();
+ if(V.isEmpty(allColumns)){
+ return queryWrapper;
+ }
+ List columns = new ArrayList<>();
+ String pk = ContextHelper.getIdColumnName(entityClass);
+ if(V.notEmpty(pk)){
+ columns.add(pk);
+ }
+ Map fieldsMap = BindingCacheManager.getFieldsMap(voClass);
+ for(TableFieldInfo col : allColumns){
+ if(fieldsMap.containsKey(col.getField().getName()) && V.notEmpty(col.getColumn())){
+ columns.add(col.getSqlSelect());
+ }
+ }
+ // select全部列,不特殊处理
+ if(allColumns.size() == columns.size()){
+ return queryWrapper;
+ }
+ return ((QueryWrapper)queryWrapper).select(S.toStringArray(columns));
}
}
\ No newline at end of file
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/parser/BaseConditionManager.java b/diboot-core/src/main/java/com/diboot/core/binding/parser/BaseConditionManager.java
index 5fed0f77146e6891a417b1a47c95e681c0ed81d9..7e4add5eeac6e9af923fcbb579e56284a206559c 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/parser/BaseConditionManager.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/parser/BaseConditionManager.java
@@ -40,7 +40,7 @@ public class BaseConditionManager {
/**
* 表达式缓存Map
*/
- private static Map> expressionParseResultMap = new ConcurrentHashMap<>();
+ private static final Map> expressionParseResultMap = new ConcurrentHashMap<>();
/**
* 获取解析后的Expression列表
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/parser/ConditionManager.java b/diboot-core/src/main/java/com/diboot/core/binding/parser/ConditionManager.java
index 5bdc8297f7b67857ff0db98d42ff3ae6dfdcc51d..45dd384de2f7c55286bab72648b021c670b30e5f 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/parser/ConditionManager.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/parser/ConditionManager.java
@@ -74,7 +74,13 @@ public class ConditionManager extends BaseConditionManager{
String annoColumn = removeLeftAlias(express.getLeftExpression().toString());
if(express.getRightExpression() instanceof Column){
String entityColumn = removeLeftAlias(express.getRightExpression().toString());
- binder.joinOn(annoColumn, entityColumn);
+ // xx=this.yy,翻转
+ if(isCurrentObjColumn(express.getRightExpression().toString()) && !isCurrentObjColumn(express.getLeftExpression().toString())){
+ binder.joinOn(entityColumn, annoColumn);
+ }
+ else{
+ binder.joinOn(annoColumn, entityColumn);
+ }
}
else{
binder.andEQ(annoColumn, express.getRightExpression().toString());
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/parser/ConditionParser.java b/diboot-core/src/main/java/com/diboot/core/binding/parser/ConditionParser.java
index bf165e2eead6b74422dd0702e16fc51f736dab34..5a06d734a4f4632ae23bd9a3f4d634c211dbcea8 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/parser/ConditionParser.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/parser/ConditionParser.java
@@ -40,7 +40,7 @@ public class ConditionParser implements ExpressionVisitor,ItemsListVisitor {
}
private List errorMsgList = null;
- private List expressList = new ArrayList<>();
+ private List expressList = new ArrayList<>(8);
/**
* 添加错误信息
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/parser/EntityInfoCache.java b/diboot-core/src/main/java/com/diboot/core/binding/parser/EntityInfoCache.java
index 98e3b02c4371f6c16d6192e34e6f6cfa273bec31..c14782d17b8f5c346d6c68138ead4f629e20e993 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/parser/EntityInfoCache.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/parser/EntityInfoCache.java
@@ -90,6 +90,17 @@ public class EntityInfoCache implements Serializable {
return this.propInfo.getColumnToFieldMap().get(columnName);
}
+ /**
+ * 根据列名获取字段
+ * @return
+ */
+ public String getColumnByField(String fieldName){
+ if(this.propInfo == null || V.isEmpty(this.propInfo.getFieldToColumnMap())){
+ return null;
+ }
+ return this.propInfo.getFieldToColumnMap().get(fieldName);
+ }
+
/**
* 获取ID列
* @return
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/parser/MiddleTable.java b/diboot-core/src/main/java/com/diboot/core/binding/parser/MiddleTable.java
index 7fac48963b5d2371ed2afa8be0da26b85227705f..b62a85761200a2cfaf7edc552a85ef510be2f271 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/parser/MiddleTable.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/parser/MiddleTable.java
@@ -23,7 +23,6 @@ import com.diboot.core.binding.helper.ResultAssembler;
import com.diboot.core.config.BaseConfig;
import com.diboot.core.config.Cons;
import com.diboot.core.exception.BusinessException;
-import com.diboot.core.util.ContextHelper;
import com.diboot.core.util.S;
import com.diboot.core.util.SqlExecutor;
import com.diboot.core.util.V;
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/parser/ParserCache.java b/diboot-core/src/main/java/com/diboot/core/binding/parser/ParserCache.java
index 066c7c1f1f53c182349840f2341bdf3765a2a29c..7637147fa704be065f693245631eebbeeb20f91a 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/parser/ParserCache.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/parser/ParserCache.java
@@ -22,12 +22,10 @@ import com.diboot.core.binding.query.BindQuery;
import com.diboot.core.binding.query.dynamic.AnnoJoiner;
import com.diboot.core.exception.BusinessException;
import com.diboot.core.util.BeanUtils;
-import com.diboot.core.util.ContextHelper;
import com.diboot.core.util.S;
import com.diboot.core.util.V;
import com.diboot.core.vo.Status;
import lombok.extern.slf4j.Slf4j;
-import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.core.annotation.AnnotationUtils;
import java.lang.annotation.Annotation;
@@ -48,15 +46,11 @@ public class ParserCache {
/**
* VO类-绑定注解缓存
*/
- private static Map allVoBindAnnotationCacheMap = new ConcurrentHashMap<>();
- /**
- * 表及相关信息的缓存
- */
- private static Map tableToLinkageCacheMap = new ConcurrentHashMap<>();
+ private static final Map allVoBindAnnotationCacheMap = new ConcurrentHashMap<>();
/**
* dto类-BindQuery注解的缓存
*/
- private static Map> dtoClassBindQueryCacheMap = new ConcurrentHashMap<>();
+ private static final Map> dtoClassBindQueryCacheMap = new ConcurrentHashMap<>();
/**
* 获取指定class对应的Bind相关注解
@@ -97,39 +91,6 @@ public class ParserCache {
return group;
}
- /**
- * 初始化Table的相关对象信息
- */
- @Deprecated
- private static void initTableToLinkageCacheMap(){
- if(tableToLinkageCacheMap.isEmpty()){
- SqlSessionFactory sqlSessionFactory = ContextHelper.getBean(SqlSessionFactory.class);
- Collection> mappers = sqlSessionFactory.getConfiguration().getMapperRegistry().getMappers();
- if(V.notEmpty(mappers)){
- mappers.forEach(m->{
- Type[] types = m.getGenericInterfaces();
- try{
- if(types != null && types.length > 0 && types[0] != null){
- ParameterizedType genericType = (ParameterizedType) types[0];
- Type[] superTypes = genericType.getActualTypeArguments();
- if(superTypes != null && superTypes.length > 0 && superTypes[0] != null){
- String entityClassName = superTypes[0].getTypeName();
- if(entityClassName.length() > 1){
- Class> entityClass = Class.forName(entityClassName);
- TableLinkage linkage = new TableLinkage(entityClass, m);
- tableToLinkageCacheMap.put(linkage.getTable(), linkage);
- }
- }
- }
- }
- catch (Exception e){
- log.warn("解析mapper异常", e);
- }
- });
- }
- }
- }
-
/**
* 是否有is_deleted列
* @return
@@ -143,17 +104,6 @@ public class ParserCache {
return null;
}
- /**
- * 获取table相关信息
- * @return
- */
- @Deprecated
- public static TableLinkage getTableLinkage(String table){
- initTableToLinkageCacheMap();
- TableLinkage linkage = tableToLinkageCacheMap.get(table);
- return linkage;
- }
-
/**
* 获取entity对应的表名
* @param entityClass
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/parser/PropInfo.java b/diboot-core/src/main/java/com/diboot/core/binding/parser/PropInfo.java
index 6346f0721358c85d8dbb9de19fcdf6ac1a006edb..4d1816abbefcfefa33f0a44f2d3a97b19d4259b5 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/parser/PropInfo.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/parser/PropInfo.java
@@ -9,6 +9,7 @@ import com.diboot.core.util.V;
import lombok.Getter;
import lombok.Setter;
+import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
@@ -24,7 +25,8 @@ import java.util.Map;
*/
@Getter
@Setter
-public class PropInfo {
+public class PropInfo implements Serializable {
+ private static final long serialVersionUID = 5921667308129991326L;
private String idColumn;
@@ -73,7 +75,7 @@ public class PropInfo {
}
// 主键
TableId tableId = fld.getAnnotation(TableId.class);
- if(tableId != null){
+ if(tableId != null && this.idColumn == null){
if (V.notEmpty(tableId.value())){
columnName = tableId.value();
}
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/parser/TableLinkage.java b/diboot-core/src/main/java/com/diboot/core/binding/parser/TableLinkage.java
deleted file mode 100644
index 2e6c312faab789fea7904f8f1f50bed87c4e582b..0000000000000000000000000000000000000000
--- a/diboot-core/src/main/java/com/diboot/core/binding/parser/TableLinkage.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2015-2020, www.dibo.ltd (service@dibo.ltd).
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.diboot.core.binding.parser;
-
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.diboot.core.config.Cons;
-import com.diboot.core.util.BeanUtils;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.io.Serializable;
-import java.lang.reflect.Field;
-
-/**
- * table的相关线索信息(已废弃,请换用 EntityInfoCache)
- * @author mazc@dibo.ltd
- * @version v2.1
- * @date 2020/06/02
- */
-@Getter @Setter
-@Deprecated
-public class TableLinkage implements Serializable {
- private static final long serialVersionUID = 4416187849283913895L;
-
- public TableLinkage(Class> entityClass, Class> mapperClass){
- this.entityClass = entityClass;
- this.mapperClass = mapperClass;
- this.table = ParserCache.getEntityTableName(entityClass);
- // 初始化是否有is_deleted
- Field field = BeanUtils.extractField(entityClass, Cons.FieldName.deleted.name());
- if(field != null){
- TableField tableField = field.getAnnotation(TableField.class);
- if(tableField != null && tableField.exist() == true){
- this.hasDeleted = true;
- }
- }
- }
-
- private String table;
- /**
- * 表对应的entity类
- */
- private Class> entityClass;
-
- /**
- * 表对应的mapper类
- */
- private Class> mapperClass;
-
- /**
- * 是否有逻辑删除字段
- */
- private boolean hasDeleted = false;
-
-}
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/query/BindQuery.java b/diboot-core/src/main/java/com/diboot/core/binding/query/BindQuery.java
index e409e689116d7488ba3de195d2a5c721cc63075a..830dbad7be65ac883af8b8b9b80485f0232dbc2c 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/query/BindQuery.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/query/BindQuery.java
@@ -63,5 +63,5 @@ public @interface BindQuery {
* 查询处理策略:默认忽略空字符串
* @return
*/
- Strategy strategy() default Strategy.IGNORE_EMPTY_STRING;
+ Strategy strategy() default Strategy.IGNORE_EMPTY;
}
\ No newline at end of file
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/query/Comparison.java b/diboot-core/src/main/java/com/diboot/core/binding/query/Comparison.java
index cfe1f846555e4b8f4d538946010ccd871cccc20c..5d8d8bd0401f0e1bdd27a3d82a843be7db9db2cc 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/query/Comparison.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/query/Comparison.java
@@ -37,5 +37,7 @@ public enum Comparison {
BETWEEN, //介于-之间
BETWEEN_BEGIN, //介于之后
- BETWEEN_END //介于之前
+ BETWEEN_END, //介于之前
+
+ NOT_EQ, //不等于
}
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/query/Strategy.java b/diboot-core/src/main/java/com/diboot/core/binding/query/Strategy.java
index 6238507d96ad4cce5d1e1cb36f9696ce75ce926c..6301481dac6f559f3109fe909430c2e2b22f01bf 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/query/Strategy.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/query/Strategy.java
@@ -24,11 +24,11 @@ package com.diboot.core.binding.query;
*/
public enum Strategy {
/**
- * 忽略空字符串""
+ * 忽略空字符串"",空集合等
*/
- IGNORE_EMPTY_STRING,
+ IGNORE_EMPTY,
/**
- * 包含空字符串""参与查询
+ * 包含空字符串""空集合等参与查询
*/
- INCLUDE_EMPTY_STRING
+ INCLUDE_EMPTY,
}
\ No newline at end of file
diff --git a/diboot-core/src/main/java/com/diboot/core/binding/query/dynamic/DynamicSqlProvider.java b/diboot-core/src/main/java/com/diboot/core/binding/query/dynamic/DynamicSqlProvider.java
index 31a41e92ceed45eb5a798c62fc349491854c214a..a882c31085a300b1aef3bb8e227df388e129687b 100644
--- a/diboot-core/src/main/java/com/diboot/core/binding/query/dynamic/DynamicSqlProvider.java
+++ b/diboot-core/src/main/java/com/diboot/core/binding/query/dynamic/DynamicSqlProvider.java
@@ -21,12 +21,12 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.diboot.core.binding.QueryBuilder;
import com.diboot.core.binding.parser.ParserCache;
import com.diboot.core.config.BaseConfig;
+import com.diboot.core.config.Cons;
import com.diboot.core.util.S;
import com.diboot.core.util.V;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.jdbc.SQL;
-import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -141,12 +141,15 @@ public class DynamicSqlProvider {
*/
private String formatSqlSelect(String sqlSelect){
String[] columns = S.split(sqlSelect);
- List selects = new ArrayList<>(columns.length);
- for(String column : columns){
- column = S.removeDuplicateBlank(column).trim();
- selects.add("self."+S.toSnakeCase(column));
+ StringBuilder sb = new StringBuilder();
+ for(int i=0; i0){
+ sb.append(Cons.SEPARATOR_COMMA);
+ }
+ sb.append("self."+S.toSnakeCase(column));
}
- return S.join(selects);
+ return sb.toString();
}
/**
diff --git a/diboot-core/src/main/java/com/diboot/core/config/BaseConfig.java b/diboot-core/src/main/java/com/diboot/core/config/BaseConfig.java
index c6646bcacc1fae2f22c6846500cdf5367dc403f5..5546e7859fb745d8d8b34a23a5f6b449a92f4df6 100644
--- a/diboot-core/src/main/java/com/diboot/core/config/BaseConfig.java
+++ b/diboot-core/src/main/java/com/diboot/core/config/BaseConfig.java
@@ -83,7 +83,7 @@ public class BaseConfig {
*/
public static int getCutLength(){
if(cutLength == null){
- cutLength = PropertiesUtils.getInteger("system.default.cutLength");
+ cutLength = PropertiesUtils.getInteger("diboot.core.cutLength");
if(cutLength == null){
cutLength = 20;
}
@@ -98,7 +98,7 @@ public class BaseConfig {
*/
public static int getPageSize() {
if(pageSize == null){
- pageSize = PropertiesUtils.getInteger("system.pagination.pageSize");
+ pageSize = PropertiesUtils.getInteger("diboot.core.pageSize");
if(pageSize == null){
pageSize = 20;
}
@@ -113,7 +113,7 @@ public class BaseConfig {
*/
public static int getBatchSize() {
if(batchSize == null){
- batchSize = PropertiesUtils.getInteger("system.batch.size");
+ batchSize = PropertiesUtils.getInteger("diboot.core.batchSize");
if(batchSize == null){
batchSize = 1000;
}
diff --git a/diboot-core/src/main/java/com/diboot/core/config/Cons.java b/diboot-core/src/main/java/com/diboot/core/config/Cons.java
index 4cdd6c01f0f1c9290df27f1c4cedb088effb1a42..7aedd93ccf1248b6b7e08eaa7f2d85fe97b76f51 100644
--- a/diboot-core/src/main/java/com/diboot/core/config/Cons.java
+++ b/diboot-core/src/main/java/com/diboot/core/config/Cons.java
@@ -129,7 +129,7 @@ public class Cons {
/**
* 成功/失败 结果状态字典定义
*/
- public static enum RESULT_STATUS{
+ public enum RESULT_STATUS{
/**
* 正常
*/
diff --git a/diboot-core/src/main/java/com/diboot/core/controller/BaseCrudRestController.java b/diboot-core/src/main/java/com/diboot/core/controller/BaseCrudRestController.java
index 50fd52c3f0ab4dc0cad0b7c096c66fac0ae72a1b..8d37ea4666973a6a61caf50a0f9f096d6b147cf6 100644
--- a/diboot-core/src/main/java/com/diboot/core/controller/BaseCrudRestController.java
+++ b/diboot-core/src/main/java/com/diboot/core/controller/BaseCrudRestController.java
@@ -234,6 +234,26 @@ public class BaseCrudRestController extends BaseContro
}
}
+ /***
+ * 根据id撤回删除
+ * @param id
+ * @return
+ * @throws Exception
+ */
+ public JsonResult cancelDeletedEntity(Serializable id) throws Exception {
+ boolean success = getService().cancelDeletedById(id);
+ E entity = null;
+ if (success){
+ entity = (E) getService().getEntity(id);
+ this.afterDeletedCanceled(entity);
+ log.info("撤回删除操作成功,{}:{}", entity.getClass().getSimpleName(), id);
+ return JsonResult.OK("撤回成功");
+ } else {
+ log.warn("撤回删除操作未成功,{}:{}", entity.getClass().getSimpleName(), id);
+ return JsonResult.FAIL_OPERATION("撤回失败");
+ }
+ }
+
/***
* 根据id批量删除资源对象,用于子类重写的方法
* @param ids
@@ -283,7 +303,7 @@ public class BaseCrudRestController extends BaseContro
* @param entityOrDto
* @return
*/
- protected String beforeCreate(Object entityOrDto) throws Exception {
+ protected String beforeCreate(E entityOrDto) throws Exception {
return null;
}
@@ -292,7 +312,7 @@ public class BaseCrudRestController extends BaseContro
* @param entityOrDto
* @return
*/
- protected void afterCreated(Object entityOrDto) throws Exception {
+ protected void afterCreated(E entityOrDto) throws Exception {
}
/***
@@ -300,7 +320,7 @@ public class BaseCrudRestController extends BaseContro
* @param entityOrDto
* @return
*/
- protected String beforeUpdate(Object entityOrDto) throws Exception {
+ protected String beforeUpdate(E entityOrDto) throws Exception {
return null;
}
@@ -309,7 +329,7 @@ public class BaseCrudRestController extends BaseContro
* @param entityOrDto
* @return
*/
- protected void afterUpdated(Object entityOrDto) throws Exception {
+ protected void afterUpdated(E entityOrDto) throws Exception {
}
/***
@@ -317,7 +337,7 @@ public class BaseCrudRestController extends BaseContro
* @param entityOrDto
* @return
*/
- protected String beforeDelete(Object entityOrDto) throws Exception{
+ protected String beforeDelete(E entityOrDto) throws Exception{
return null;
}
@@ -326,7 +346,15 @@ public class BaseCrudRestController extends BaseContro
* @param entityOrDto
* @return
*/
- protected void afterDeleted(Object entityOrDto) throws Exception {
+ protected void afterDeleted(E entityOrDto) throws Exception {
+ }
+
+ /***
+ * 撤销删除成功后的相关处理
+ * @param entityOrDto
+ * @throws Exception
+ */
+ protected void afterDeletedCanceled(E entityOrDto) throws Exception {
}
/***
diff --git a/diboot-core/src/main/java/com/diboot/core/exception/BusinessException.java b/diboot-core/src/main/java/com/diboot/core/exception/BusinessException.java
index 7eba84549342168a37cd69147c9f2dfc5afd49fa..78857d85b5e1afe1981ca0693823b7ee220c1945 100644
--- a/diboot-core/src/main/java/com/diboot/core/exception/BusinessException.java
+++ b/diboot-core/src/main/java/com/diboot/core/exception/BusinessException.java
@@ -29,6 +29,8 @@ import java.util.Map;
*/
public class BusinessException extends RuntimeException {
+ private Integer code;
+
/**
* 错误的状态
*/
@@ -70,12 +72,23 @@ public class BusinessException extends RuntimeException {
this.status = status;
}
+ /**
+ * 自定义状态码和内容提示
+ * @param code
+ * @param msg
+ */
+ public BusinessException(int code, String msg) {
+ super(msg);
+ this.code = code;
+ }
+
/**
* 自定义内容提示
* @param msg
*/
public BusinessException(String msg) {
- super( msg);
+ super(msg);
+ this.status = Status.FAIL_OPERATION;
}
/**
@@ -88,13 +101,23 @@ public class BusinessException extends RuntimeException {
this.status = status;
}
+ /**
+ * 自定义内容提示
+ * @param code
+ * @param msg
+ */
+ public BusinessException(int code, String msg, Throwable ex) {
+ super(msg, ex);
+ this.code = code;
+ }
+
/**
* 转换为Map
* @return
*/
public Map toMap(){
- Map map = new HashMap<>();
- map.put("code", status.code());
+ Map map = new HashMap<>(8);
+ map.put("code", getCode());
map.put("msg", getMessage());
return map;
}
@@ -106,4 +129,12 @@ public class BusinessException extends RuntimeException {
public Status getStatus(){
return this.status;
}
+
+ private int getCode(){
+ if(this.code == null && this.status != null){
+ this.code = this.status.code();
+ }
+ return this.code;
+ }
+
}
diff --git a/diboot-core/src/main/java/com/diboot/core/handler/IEncryptorHandler.java b/diboot-core/src/main/java/com/diboot/core/handler/IEncryptorHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..22c3e68a7df194f057e9f782449807bee8dbb749
--- /dev/null
+++ b/diboot-core/src/main/java/com/diboot/core/handler/IEncryptorHandler.java
@@ -0,0 +1,32 @@
+package com.diboot.core.handler;
+
+/**
+ * 加解密接口
+ *
+ * @author : uu
+ * @version : v1.0
+ * @Date 2021/7/13 09:45
+ */
+public interface IEncryptorHandler {
+
+ /**
+ * 解密
+ * @param content
+ * @return
+ * @throws Exception
+ */
+ default String encrypt(String content) throws Exception{
+ return content;
+ }
+
+ /**
+ * 解密
+ * @param content
+ * @return
+ * @throws Exception
+ */
+ default String decrypt(String content) throws Exception{
+ return content;
+ }
+
+}
diff --git a/diboot-core/src/main/java/com/diboot/core/holder/AnnotationRestApiHolder.java b/diboot-core/src/main/java/com/diboot/core/holder/AnnotationRestApiHolder.java
index e72b8705ca51bca4c8f1cf82c77f398a4dfaf55e..3caf4cc482d9cd38ffdb514b326e5790f0e16217 100644
--- a/diboot-core/src/main/java/com/diboot/core/holder/AnnotationRestApiHolder.java
+++ b/diboot-core/src/main/java/com/diboot/core/holder/AnnotationRestApiHolder.java
@@ -20,14 +20,18 @@ import com.diboot.core.config.Cons;
import com.diboot.core.holder.api.CollectThisApi;
import com.diboot.core.holder.api.RestApi;
import com.diboot.core.holder.api.RestApiWrapper;
-import com.diboot.core.util.*;
+import com.diboot.core.util.AnnotationUtils;
+import com.diboot.core.util.BeanUtils;
+import com.diboot.core.util.ContextHelper;
+import com.diboot.core.util.V;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
/**
* 注解 RestApi 信息缓存
diff --git a/diboot-core/src/main/java/com/diboot/core/holder/api/RestApi.java b/diboot-core/src/main/java/com/diboot/core/holder/api/RestApi.java
index 905a0edb536679c57892e7e509571e9dc6e7c827..1ff8b343b767b151c750ced22c206c383e22d559 100644
--- a/diboot-core/src/main/java/com/diboot/core/holder/api/RestApi.java
+++ b/diboot-core/src/main/java/com/diboot/core/holder/api/RestApi.java
@@ -15,13 +15,11 @@
*/
package com.diboot.core.holder.api;
-import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.io.Serializable;
-import java.lang.annotation.Annotation;
import java.util.List;
/**
diff --git a/diboot-core/src/main/java/com/diboot/core/mapper/BaseCrudMapper.java b/diboot-core/src/main/java/com/diboot/core/mapper/BaseCrudMapper.java
index 2dd7ab6b5bcb8ecd28a080875d20302d3a56b201..3676613fc25a86e8819b21d061c8c67dade98a19 100644
--- a/diboot-core/src/main/java/com/diboot/core/mapper/BaseCrudMapper.java
+++ b/diboot-core/src/main/java/com/diboot/core/mapper/BaseCrudMapper.java
@@ -16,6 +16,10 @@
package com.diboot.core.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
+
+import java.io.Serializable;
/**
* 基础CRUD的父类Mapper
@@ -25,4 +29,12 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/
public interface BaseCrudMapper extends BaseMapper {
+ /***
+ * 通过id撤回当前记录的删除状态
+ * @param tableName
+ * @param id
+ * @return
+ */
+ @Update("UPDATE `${tableName}` SET is_deleted=0 WHERE id=#{id}")
+ int cancelDeletedById(@Param("tableName") String tableName, @Param("id") Serializable id);
}
\ No newline at end of file
diff --git a/diboot-core/src/main/java/com/diboot/core/service/BaseService.java b/diboot-core/src/main/java/com/diboot/core/service/BaseService.java
index 305701c627ff7b082fe7c7d4964720e15ca819c4..b303302b707b30f668ab8f2cb6eaf985b83ad4d4 100644
--- a/diboot-core/src/main/java/com/diboot/core/service/BaseService.java
+++ b/diboot-core/src/main/java/com/diboot/core/service/BaseService.java
@@ -22,7 +22,6 @@ import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapp
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
-import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.diboot.core.binding.binder.EntityBinder;
import com.diboot.core.binding.binder.EntityListBinder;
import com.diboot.core.binding.binder.FieldBinder;
@@ -191,6 +190,13 @@ public interface BaseService {
*/
boolean deleteEntity(Serializable id);
+ /**
+ * 根据主键撤销删除
+ * @param id
+ * @return
+ */
+ boolean cancelDeletedById(Serializable id);
+
/**
* 按条件删除实体
* @param queryWrapper
@@ -308,6 +314,15 @@ public interface BaseService {
*/
Map getKeyValueMap(Wrapper queryWrapper);
+ /**
+ * 获取id-指定name的映射map
+ * @param entityIds
+ * @param getterFn
+ * @param
+ * @return
+ */
+ Map getId2NameMap(List entityIds, IGetter getterFn);
+
/**
* 获取Map
* @param queryWrapper
diff --git a/diboot-core/src/main/java/com/diboot/core/service/impl/BaseServiceImpl.java b/diboot-core/src/main/java/com/diboot/core/service/impl/BaseServiceImpl.java
index c77617f80c163fb8aa6ece30cc2e98113207b0f6..df1b23c5df75965fd02dd06db3b341f6c256ccb4 100644
--- a/diboot-core/src/main/java/com/diboot/core/service/impl/BaseServiceImpl.java
+++ b/diboot-core/src/main/java/com/diboot/core/service/impl/BaseServiceImpl.java
@@ -22,6 +22,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
+import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
@@ -30,13 +31,14 @@ import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
-import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.diboot.core.binding.Binder;
import com.diboot.core.binding.binder.EntityBinder;
import com.diboot.core.binding.binder.EntityListBinder;
import com.diboot.core.binding.binder.FieldBinder;
import com.diboot.core.binding.binder.FieldListBinder;
+import com.diboot.core.binding.cache.BindingCacheManager;
import com.diboot.core.binding.helper.ServiceAdaptor;
+import com.diboot.core.binding.parser.EntityInfoCache;
import com.diboot.core.binding.query.dynamic.DynamicJoinQueryWrapper;
import com.diboot.core.config.BaseConfig;
import com.diboot.core.config.Cons;
@@ -102,12 +104,15 @@ public class BaseServiceImpl, T> extends ServiceImpl
@Override
public FT getValueOfField(SFunction idGetterFn, Serializable idVal, SFunction getterFn) {
- String fieldName = convertGetterToFieldName(getterFn);
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper()
.select(idGetterFn, getterFn)
.eq(idGetterFn, idVal);
T entity = getSingleEntity(queryWrapper);
- return entity != null? (FT)BeanUtils.getProperty(entity, fieldName) : null;
+ if(entity == null){
+ return null;
+ }
+ String fieldName = convertGetterToFieldName(getterFn);
+ return (FT)BeanUtils.getProperty(entity, fieldName);
}
@Override
@@ -203,14 +208,27 @@ public class BaseServiceImpl, T> extends ServiceImpl
}
}
+ /**
+ * 用于更新之前的自动填充等场景调用
+ */
+ protected void beforeUpdateEntity(T entity){
+ }
+
+ @Override
+ public boolean updateById(T entity) {
+ return updateEntity(entity);
+ }
+
@Override
public boolean updateEntity(T entity) {
+ beforeUpdateEntity(entity);
boolean success = super.updateById(entity);
return success;
}
@Override
public boolean updateEntity(T entity, Wrapper updateWrapper) {
+ beforeUpdateEntity(entity);
boolean success = super.update(entity, updateWrapper);
return success;
}
@@ -227,6 +245,9 @@ public class BaseServiceImpl, T> extends ServiceImpl
if(V.isEmpty(entityList)){
return false;
}
+ for(T entity : entityList){
+ beforeUpdateEntity(entity);
+ }
boolean success = super.updateBatchById(entityList);
return success;
}
@@ -261,10 +282,10 @@ public class BaseServiceImpl, T> extends ServiceImpl
throw new BusinessException(Status.FAIL_INVALID_PARAM, "主动ID值不能为空!");
}
// 从getter中获取class和fieldName
- com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda lambda = LambdaUtils.resolve(driverIdGetter);
- Class middleTableClass = (Class) lambda.getImplClass();
+ LambdaMeta lambdaMeta = LambdaUtils.extract(driverIdGetter);
+ Class middleTableClass = (Class) lambdaMeta.getInstantiatedClass();
// 获取主动从动字段名
- String driverFieldName = PropertyNamer.methodToProperty(lambda.getImplMethodName());
+ String driverFieldName = PropertyNamer.methodToProperty(lambdaMeta.getImplMethodName());
String followerFieldName = convertGetterToFieldName(followerIdGetter);
List n2nRelations = null;
if(V.notEmpty(followerIdList)){
@@ -403,7 +424,14 @@ public class BaseServiceImpl, T> extends ServiceImpl
return super.removeById(id);
}
- @Override
+ @Override
+ public boolean cancelDeletedById(Serializable id) {
+ EntityInfoCache info = BindingCacheManager.getEntityInfoByClass(super.getEntityClass());
+ String tableName = info.getTableName();
+ return this.getMapper().cancelDeletedById(tableName, id) > 0;
+ }
+
+ @Override
public boolean deleteEntities(Wrapper queryWrapper){
// 执行
return super.remove(queryWrapper);
@@ -439,7 +467,7 @@ public class BaseServiceImpl, T> extends ServiceImpl
IPage page = convertToIPage(queryWrapper, pagination);
page = super.page(page, queryWrapper);
// 如果重新执行了count进行查询,则更新pagination中的总数
- if(page.isSearchCount()){
+ if(page.searchCount()){
pagination.setTotalCount(page.getTotal());
}
return page.getRecords();
@@ -520,16 +548,19 @@ public class BaseServiceImpl, T> extends ServiceImpl
@Override
public boolean exists(Wrapper queryWrapper) {
- List entityList = getEntityListLimit(queryWrapper, 1);
- boolean isExists = V.notEmpty(entityList) && entityList.size() > 0;
- entityList = null;
- return isExists;
+ if((queryWrapper instanceof QueryWrapper) && queryWrapper.getSqlSelect() == null){
+ String pk = ContextHelper.getIdFieldName(getEntityClass());
+ ((QueryWrapper)queryWrapper).select(pk);
+ }
+ T entity = getSingleEntity(queryWrapper);
+ return entity != null;
}
@Override
public List getEntityListByIds(List ids) {
QueryWrapper queryWrapper = new QueryWrapper();
- queryWrapper.in(Cons.FieldName.id.name(), ids);
+ String pk = ContextHelper.getIdFieldName(getEntityClass());
+ queryWrapper.in(pk, ids);
return getEntityList(queryWrapper);
}
@@ -544,7 +575,7 @@ public class BaseServiceImpl, T> extends ServiceImpl
IPage page = convertToIPage(queryWrapper, pagination);
IPage> resultPage = super.pageMaps(page, queryWrapper);
// 如果重新执行了count进行查询,则更新pagination中的总数
- if(page.isSearchCount()){
+ if(page.searchCount()){
pagination.setTotalCount(page.getTotal());
}
return resultPage.getRecords();
@@ -614,6 +645,33 @@ public class BaseServiceImpl, T> extends ServiceImpl
return BeanUtils.convertKeyValueList2Map(keyValueList);
}
+ @Override
+ public Map getId2NameMap(List entityIds, IGetter getterFn) {
+ if(V.isEmpty(entityIds)){
+ return Collections.emptyMap();
+ }
+ String fieldName = BeanUtils.convertToFieldName(getterFn);
+ EntityInfoCache entityInfo = BindingCacheManager.getEntityInfoByClass(this.getEntityClass());
+ String columnName = entityInfo.getColumnByField(fieldName);
+ QueryWrapper queryWrapper = new QueryWrapper().select(
+ entityInfo.getIdColumn(),
+ columnName
+ ).in(entityInfo.getIdColumn(), entityIds);
+ // map列表
+ List> mapList = getMapList(queryWrapper);
+ if(V.isEmpty(mapList)){
+ return Collections.emptyMap();
+ }
+ Map idNameMap = new HashMap<>();
+ for(Map map : mapList){
+ ID key = (ID)map.get(entityInfo.getIdColumn());
+ String value = S.valueOf(map.get(columnName));
+ idNameMap.put(key, value);
+ }
+ return idNameMap;
+ }
+
+ @Override
public Map getMap(Wrapper queryWrapper) {
return super.getMap(queryWrapper);
}
@@ -655,6 +713,7 @@ public class BaseServiceImpl, T> extends ServiceImpl
@Override
public List getViewObjectList(Wrapper queryWrapper, Pagination pagination, Class voClass) {
+ queryWrapper = ServiceAdaptor.optimizeSelect(queryWrapper, getEntityClass(), voClass);
List entityList = getEntityList(queryWrapper, pagination);
// 自动转换为VO并绑定关联对象
List voList = Binder.convertAndBindRelations(entityList, voClass);
@@ -688,8 +747,8 @@ public class BaseServiceImpl, T> extends ServiceImpl
* @return
*/
private String convertGetterToFieldName(SFunction getterFn) {
- com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda lambda = LambdaUtils.resolve(getterFn);
- String fieldName = PropertyNamer.methodToProperty(lambda.getImplMethodName());
+ LambdaMeta lambdaMeta = LambdaUtils.extract(getterFn);
+ String fieldName = PropertyNamer.methodToProperty(lambdaMeta.getImplMethodName());
return fieldName;
}
diff --git a/diboot-core/src/main/java/com/diboot/core/util/BeanUtils.java b/diboot-core/src/main/java/com/diboot/core/util/BeanUtils.java
index 074fa52d2b06dc88b38c9a8f83501dbb31d1fcd7..437be019517a81d4f5b6e836686e7253b4a7b1dd 100644
--- a/diboot-core/src/main/java/com/diboot/core/util/BeanUtils.java
+++ b/diboot-core/src/main/java/com/diboot/core/util/BeanUtils.java
@@ -15,7 +15,7 @@
*/
package com.diboot.core.util;
-
+import com.diboot.core.binding.cache.BindingCacheManager;
import com.diboot.core.binding.copy.AcceptAnnoCopier;
import com.diboot.core.config.Cons;
import com.diboot.core.entity.BaseEntity;
@@ -113,12 +113,12 @@ public class BeanUtils {
if(V.isEmpty(sourceList)){
return Collections.emptyList();
}
- List resultList = new ArrayList<>();
// 类型相同,直接跳过
if(clazz.getName().equals(sourceList.get(0).getClass().getName())){
return sourceList;
}
// 不同,则转换
+ List resultList = new ArrayList<>(sourceList.size());
try{
for(Object source : sourceList){
T target = clazz.getConstructor().newInstance();
@@ -142,8 +142,7 @@ public class BeanUtils {
if(V.isEmpty(propMap)){
return;
}
- List fields = extractAllFields(model.getClass());
- Map fieldNameMaps = convertToStringKeyObjectMap(fields, "name");
+ Map fieldNameMaps = BindingCacheManager.getFieldsMap(model.getClass());
for(Map.Entry entry : propMap.entrySet()){
Field field = fieldNameMaps.get(entry.getKey());
if(field != null){
@@ -560,6 +559,9 @@ public class BeanUtils {
* @return
*/
public static List collectToList(List