Merge branch 'develop' of https://github.com/dibo-software/diboot-v2 into develop

This commit is contained in:
wuy 2019-06-27 15:59:24 +08:00
commit c7ffaedb47
20 changed files with 172 additions and 176 deletions

View File

@ -15,7 +15,7 @@ diboot 2.0版本项目,实现: diboot-core全新内核 + diboot-devtools代码
#### 多表关联查询无SQL适用于大多数场景拆分成单表查询自动实现结果绑定 #### 多表关联查询无SQL适用于大多数场景拆分成单表查询自动实现结果绑定
> 通过注解实现多数场景下的关联查询无SQL化自动绑定 > 通过注解实现多数场景下的关联查询无SQL化自动绑定
##### 1. @BindMetadata 注解自动绑定元数据(枚举值)的显示值Label ##### 1. @BindDict 注解自动绑定数据字典(枚举值)的显示值Label
##### 2. @BindField 注解自动绑定其他表的字段 ##### 2. @BindField 注解自动绑定其他表的字段
##### 3. @BindEntity 注解自动绑定单个其他表实体Entity ##### 3. @BindEntity 注解自动绑定单个其他表实体Entity
##### 4. @BindEntityList 注解自动绑定其他表实体集合List<Entity> ##### 4. @BindEntityList 注解自动绑定其他表实体集合List<Entity>

View File

@ -7,9 +7,9 @@
> 依赖Mybatis-Plus实现Mybatis-Plus具备通用Mapper方案和灵活的查询构造器 > 依赖Mybatis-Plus实现Mybatis-Plus具备通用Mapper方案和灵活的查询构造器
### ** 多表关联查询无SQL适用于大多数场景拆分成单表查询自动实现结果绑定 ### ** 多表关联查询无SQL适用于大多数场景拆分成单表查询自动实现结果绑定
> 通过注解实现多数场景下的关联查询无SQL > 通过注解实现多数场景下的关联查询无SQL
#### 2.1. 注解自动绑定数据(枚举值)的显示值Label #### 2.1. 注解自动绑定数据字典(枚举值)的显示值Label
~~~java ~~~java
@BindMetadata(type="GENDER", field = "gender") @BindDict(type="GENDER", field = "gender")
private String genderLabel; private String genderLabel;
~~~ ~~~
#### 2. 注解自动绑定其他表的字段 #### 2. 注解自动绑定其他表的字段

View File

@ -11,16 +11,16 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Inherited @Inherited
@Documented @Documented
public @interface BindMetadata { public @interface BindDict {
/*** /***
* 绑定数据类型 * 绑定数据字典类型
* @return * @return
*/ */
String type(); String type();
/*** /***
* 数据项取值字段 * 数据字典项取值字段
* @return * @return
*/ */
String field(); String field();

View File

@ -5,13 +5,13 @@ import com.diboot.core.binding.FieldBinder;
import com.diboot.core.binding.annotation.BindEntity; import com.diboot.core.binding.annotation.BindEntity;
import com.diboot.core.binding.annotation.BindEntityList; import com.diboot.core.binding.annotation.BindEntityList;
import com.diboot.core.binding.annotation.BindField; import com.diboot.core.binding.annotation.BindField;
import com.diboot.core.binding.annotation.BindMetadata; import com.diboot.core.binding.annotation.BindDict;
import com.diboot.core.binding.parser.BindAnnotationGroup; import com.diboot.core.binding.parser.BindAnnotationGroup;
import com.diboot.core.binding.parser.ConditionManager; import com.diboot.core.binding.parser.ConditionManager;
import com.diboot.core.binding.parser.FieldAnnotation; import com.diboot.core.binding.parser.FieldAnnotation;
import com.diboot.core.entity.Metadata; import com.diboot.core.entity.Dictionary;
import com.diboot.core.service.BaseService; import com.diboot.core.service.BaseService;
import com.diboot.core.service.MetadataService; import com.diboot.core.service.DictionaryService;
import com.diboot.core.util.BeanUtils; import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.ContextHelper; import com.diboot.core.util.ContextHelper;
import com.diboot.core.util.V; import com.diboot.core.util.V;
@ -62,11 +62,11 @@ public class AnnotationBindingManager {
Class voClass = voList.get(0).getClass(); Class voClass = voList.get(0).getClass();
BindAnnotationGroup bindAnnotationGroup = BindAnnotationCacheManager.getBindAnnotationGroup(voClass); BindAnnotationGroup bindAnnotationGroup = BindAnnotationCacheManager.getBindAnnotationGroup(voClass);
if(bindAnnotationGroup.isNotEmpty()){ if(bindAnnotationGroup.isNotEmpty()){
// 绑定数据 // 绑定数据字典
List<FieldAnnotation> metadataAnnoList = bindAnnotationGroup.getBindMetadataAnnotations(); List<FieldAnnotation> dictAnnoList = bindAnnotationGroup.getBindDictAnnotations();
if(metadataAnnoList != null){ if(dictAnnoList != null){
for(FieldAnnotation annotation : metadataAnnoList){ for(FieldAnnotation annotation : dictAnnoList){
doBindingMetadata(voList, annotation); doBindingDict(voList, annotation);
} }
} }
// 绑定Field字段名 // 绑定Field字段名
@ -92,16 +92,16 @@ public class AnnotationBindingManager {
} }
/*** /***
* 绑定数据 * 绑定数据字典
* @param voList * @param voList
* @param fieldAnno * @param fieldAnno
* @param <VO> * @param <VO>
*/ */
private static <VO> void doBindingMetadata(List<VO> voList, FieldAnnotation fieldAnno) { private static <VO> void doBindingDict(List<VO> voList, FieldAnnotation fieldAnno) {
MetadataService metadataService = (MetadataService) ContextHelper.getBean(MetadataService.class); DictionaryService dictionaryService = (DictionaryService) ContextHelper.getBean(DictionaryService.class);
if(metadataService != null){ if(dictionaryService != null){
BindMetadata annotation = (BindMetadata) fieldAnno.getAnnotation(); BindDict annotation = (BindDict) fieldAnno.getAnnotation();
metadataService.bindItemLabel(voList, fieldAnno.getFieldName(), annotation.field(), annotation.type()); dictionaryService.bindItemLabel(voList, fieldAnno.getFieldName(), annotation.field(), annotation.type());
} }
} }
@ -196,8 +196,8 @@ public class AnnotationBindingManager {
*/ */
private static BaseService getService(Annotation annotation){ private static BaseService getService(Annotation annotation){
Class<?> entityClass = null; Class<?> entityClass = null;
if(annotation instanceof BindMetadata){ if(annotation instanceof BindDict){
entityClass = Metadata.class; entityClass = Dictionary.class;
} }
else if(annotation instanceof BindField){ else if(annotation instanceof BindField){
BindField bindAnnotation = (BindField)annotation; BindField bindAnnotation = (BindField)annotation;

View File

@ -3,7 +3,7 @@ package com.diboot.core.binding.parser;
import com.diboot.core.binding.annotation.BindEntity; import com.diboot.core.binding.annotation.BindEntity;
import com.diboot.core.binding.annotation.BindEntityList; import com.diboot.core.binding.annotation.BindEntityList;
import com.diboot.core.binding.annotation.BindField; import com.diboot.core.binding.annotation.BindField;
import com.diboot.core.binding.annotation.BindMetadata; import com.diboot.core.binding.annotation.BindDict;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.util.ArrayList; import java.util.ArrayList;
@ -17,9 +17,9 @@ import java.util.List;
*/ */
public class BindAnnotationGroup { public class BindAnnotationGroup {
/** /**
* Metadata注解 * Dictionary注解
*/ */
private List<FieldAnnotation> bindMetadataAnnotations; private List<FieldAnnotation> bindDictAnnotations;
/** /**
* 字段关联注解 * 字段关联注解
*/ */
@ -39,11 +39,11 @@ public class BindAnnotationGroup {
* @param annotation * @param annotation
*/ */
public void addBindAnnotation(String fieldName, Annotation annotation){ public void addBindAnnotation(String fieldName, Annotation annotation){
if(annotation instanceof BindMetadata){ if(annotation instanceof BindDict){
if(bindMetadataAnnotations == null){ if(bindDictAnnotations == null){
bindMetadataAnnotations = new ArrayList<>(); bindDictAnnotations = new ArrayList<>();
} }
bindMetadataAnnotations.add(new FieldAnnotation(fieldName, annotation)); bindDictAnnotations.add(new FieldAnnotation(fieldName, annotation));
} }
else if(annotation instanceof BindField){ else if(annotation instanceof BindField){
if(bindFieldAnnotations == null){ if(bindFieldAnnotations == null){
@ -65,8 +65,8 @@ public class BindAnnotationGroup {
} }
} }
public List<FieldAnnotation> getBindMetadataAnnotations() { public List<FieldAnnotation> getBindDictAnnotations() {
return bindMetadataAnnotations; return bindDictAnnotations;
} }
public List<FieldAnnotation> getBindFieldAnnotations() { public List<FieldAnnotation> getBindFieldAnnotations() {
@ -82,6 +82,6 @@ public class BindAnnotationGroup {
} }
public boolean isNotEmpty() { public boolean isNotEmpty() {
return bindMetadataAnnotations != null || bindFieldAnnotations != null || bindEntityAnnotations != null || bindEntityListAnnotations != null; return bindDictAnnotations != null || bindFieldAnnotations != null || bindEntityAnnotations != null || bindEntityListAnnotations != null;
} }
} }

View File

@ -40,7 +40,7 @@ public abstract class BaseCrudRestController extends BaseController {
/*** /***
* 获取某资源的集合 * 获取某资源的集合
* <p> * <p>
* url参数示例: /metadata/list?_pageSize=20&_pageIndex=1&_orderBy=itemValue&type=GENDAR * url参数示例: /dictionary/list?_pageSize=20&_pageIndex=1&_orderBy=itemValue&type=GENDAR
* </p> * </p>
* @param request * @param request
* @return JsonResult * @return JsonResult
@ -56,7 +56,7 @@ public abstract class BaseCrudRestController extends BaseController {
/*** /***
* 获取某资源的集合 * 获取某资源的集合
* <p> * <p>
* url参数示例: /metadata/list?_pageSize=20&_pageIndex=1&_orderBy=itemValue&type=GENDAR * url参数示例: /dictionary/list?_pageSize=20&_pageIndex=1&_orderBy=itemValue&type=GENDAR
* </p> * </p>
* @param request * @param request
* @return JsonResult * @return JsonResult
@ -74,7 +74,7 @@ public abstract class BaseCrudRestController extends BaseController {
/*** /***
* 获取某VO资源的集合 * 获取某VO资源的集合
* <p> * <p>
* url参数示例: /metadata/list?_pageSize=20&_pageIndex=1&_orderBy=itemValue&type=GENDAR * url参数示例: /dictionary/list?_pageSize=20&_pageIndex=1&_orderBy=itemValue&type=GENDAR
* </p> * </p>
* @param request * @param request
* @return JsonResult * @return JsonResult

View File

@ -7,12 +7,12 @@ import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
/** /**
* 数据实体 * 数据字典实体
* @author Mazhicheng * @author Mazhicheng
* @version v2.0 * @version v2.0
* @date 2018/12/27 * @date 2018/12/27
*/ */
public class Metadata extends BaseExtEntity { public class Dictionary extends BaseExtEntity {
private static final long serialVersionUID = 11301L; private static final long serialVersionUID = 11301L;
/*** /***
@ -23,32 +23,32 @@ public class Metadata extends BaseExtEntity {
private Long parentId = 0L; private Long parentId = 0L;
/*** /***
* 数据类型 * 数据字典类型
*/ */
@NotNull(message = "数据类型不能为空!") @NotNull(message = "数据字典类型不能为空!")
@Length(max = 50, message = "数据类型长度超长!") @Length(max = 50, message = "数据字典类型长度超长!")
@TableField @TableField
private String type; private String type;
/*** /***
* 数据项的显示名称 * 数据字典项的显示名称
*/ */
@NotNull(message = "数据项名称不能为空!") @NotNull(message = "数据字典项名称不能为空!")
@Length(max = 100, message = "数据项名称长度超长!") @Length(max = 100, message = "数据字典项名称长度超长!")
@TableField @TableField
private String itemName; private String itemName;
/*** /***
* 数据项的存储值编码 * 数据字典项的存储值编码
*/ */
@Length(max = 100, message = "数据项编码长度超长!") @Length(max = 100, message = "数据字典项编码长度超长!")
@TableField @TableField
private String itemValue; private String itemValue;
/*** /***
* 备注信息 * 备注信息
*/ */
@Length(max = 200, message = "数据备注长度超长!") @Length(max = 200, message = "数据字典备注长度超长!")
@TableField @TableField
private String comment; private String comment;

View File

@ -0,0 +1,14 @@
package com.diboot.core.mapper;
import com.diboot.core.entity.Dictionary;
/**
* 数据字典Mapper
* @author Mazhicheng
* @version v2.0
* @date 2018/12/22
*/
public interface DictionaryMapper extends BaseCrudMapper<Dictionary> {
}

View File

@ -1,14 +0,0 @@
package com.diboot.core.mapper;
import com.diboot.core.entity.Metadata;
/**
* 元数据Mapper
* @author Mazhicheng
* @version v2.0
* @date 2018/12/22
*/
public interface MetadataMapper extends BaseCrudMapper<Metadata> {
}

View File

@ -1,6 +1,6 @@
package com.diboot.core.service; package com.diboot.core.service;
import com.diboot.core.entity.Metadata; import com.diboot.core.entity.Dictionary;
import com.diboot.core.util.IGetter; import com.diboot.core.util.IGetter;
import com.diboot.core.util.ISetter; import com.diboot.core.util.ISetter;
import com.diboot.core.vo.KeyValue; import com.diboot.core.vo.KeyValue;
@ -8,12 +8,12 @@ import com.diboot.core.vo.KeyValue;
import java.util.List; import java.util.List;
/** /**
* 数据Service * 数据字典Service
* @author Mazhicheng * @author Mazhicheng
* @version 2.0 * @version 2.0
* @date 2019/01/01 * @date 2019/01/01
*/ */
public interface MetadataService extends BaseService<Metadata>{ public interface DictionaryService extends BaseService<Dictionary>{
/*** /***
* 获取对应类型的键值对 * 获取对应类型的键值对

View File

@ -94,7 +94,7 @@ public class BaseServiceImpl<M extends BaseCrudMapper<T>, T> extends ServiceImpl
@Override @Override
public boolean createOrUpdateEntities(Collection entityList) { public boolean createOrUpdateEntities(Collection entityList) {
if(V.isEmpty(entityList)){ if(V.isEmpty(entityList)){
warning("createEntities", "参数entityList为空!"); warning("createOrUpdateEntities", "参数entityList为空!");
return false; return false;
} }
// 批量插入 // 批量插入
@ -187,7 +187,7 @@ public class BaseServiceImpl<M extends BaseCrudMapper<T>, T> extends ServiceImpl
String sqlSelect = queryWrapper.getSqlSelect(); String sqlSelect = queryWrapper.getSqlSelect();
// 最多支持3个属性k, v, ext // 最多支持3个属性k, v, ext
if(V.isEmpty(sqlSelect) || S.countMatches(sqlSelect, Cons.SEPARATOR_COMMA) > 2){ if(V.isEmpty(sqlSelect) || S.countMatches(sqlSelect, Cons.SEPARATOR_COMMA) > 2){
log.error("调用错误: getKeyValueList必须用select依次指定返回的Key,Value, ext键值字段如: new QueryWrapper<Metadata>().lambda().select(Metadata::getItemName, Metadata::getItemValue)"); log.error("调用错误: getKeyValueList必须用select依次指定返回的Key,Value, ext键值字段如: new QueryWrapper<Dictionary>().lambda().select(Dictionary::getItemName, Dictionary::getItemValue)");
return Collections.emptyList(); return Collections.emptyList();
} }
// 获取mapList // 获取mapList

View File

@ -2,9 +2,9 @@ package com.diboot.core.service.impl;
import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.entity.Metadata; import com.diboot.core.entity.Dictionary;
import com.diboot.core.mapper.MetadataMapper; import com.diboot.core.mapper.DictionaryMapper;
import com.diboot.core.service.MetadataService; import com.diboot.core.service.DictionaryService;
import com.diboot.core.util.*; import com.diboot.core.util.*;
import com.diboot.core.vo.KeyValue; import com.diboot.core.vo.KeyValue;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -14,29 +14,29 @@ import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
/** /**
* 数据相关service实现 * 数据字典相关service实现
* @author Mazhicheng * @author Mazhicheng
* @version 2.0 * @version 2.0
* @date 2019/01/01 * @date 2019/01/01
*/ */
@Service @Service
public class MetadataServiceImpl extends BaseServiceImpl<MetadataMapper, Metadata> implements MetadataService{ public class DictionaryServiceImpl extends BaseServiceImpl<DictionaryMapper, Dictionary> implements DictionaryService {
private static final Logger log = LoggerFactory.getLogger(MetadataServiceImpl.class); private static final Logger log = LoggerFactory.getLogger(DictionaryServiceImpl.class);
private static final String FIELD_NAME_ITEM_NAME = BeanUtils.convertToFieldName(Metadata::getItemName); private static final String FIELD_NAME_ITEM_NAME = BeanUtils.convertToFieldName(Dictionary::getItemName);
private static final String FIELD_NAME_ITEM_VALUE = BeanUtils.convertToFieldName(Metadata::getItemValue); private static final String FIELD_NAME_ITEM_VALUE = BeanUtils.convertToFieldName(Dictionary::getItemValue);
private static final String FIELD_NAME_TYPE = BeanUtils.convertToFieldName(Metadata::getType); private static final String FIELD_NAME_TYPE = BeanUtils.convertToFieldName(Dictionary::getType);
private static final String FIELD_NAME_PARENT_ID = BeanUtils.convertToFieldName(Metadata::getParentId); private static final String FIELD_NAME_PARENT_ID = BeanUtils.convertToFieldName(Dictionary::getParentId);
@Override @Override
public List<KeyValue> getKeyValueList(String type) { public List<KeyValue> getKeyValueList(String type) {
// 构建查询条件 // 构建查询条件
Wrapper queryMetadata = new QueryWrapper<Metadata>().lambda() Wrapper queryDictionary = new QueryWrapper<Dictionary>().lambda()
.select(Metadata::getItemName, Metadata::getItemValue) .select(Dictionary::getItemName, Dictionary::getItemValue)
.eq(Metadata::getType, type) .eq(Dictionary::getType, type)
.gt(Metadata::getParentId, 0); .gt(Dictionary::getParentId, 0);
// 返回构建条件 // 返回构建条件
return getKeyValueList(queryMetadata); return getKeyValueList(queryDictionary);
} }
@Override @Override
@ -46,8 +46,8 @@ public class MetadataServiceImpl extends BaseServiceImpl<MetadataMapper, Metadat
return; return;
} }
bindingFieldTo(voList) bindingFieldTo(voList)
.link(Metadata::getItemName, setFieldLabelFn) .link(Dictionary::getItemName, setFieldLabelFn)
.joinOn(getFieldIdFn, Metadata::getItemValue) .joinOn(getFieldIdFn, Dictionary::getItemValue)
.andEQ(FIELD_NAME_TYPE, type) .andEQ(FIELD_NAME_TYPE, type)
.andGT(FIELD_NAME_PARENT_ID, 0) .andGT(FIELD_NAME_PARENT_ID, 0)
.bind(); .bind();

View File

@ -1,19 +1,19 @@
SET FOREIGN_KEY_CHECKS=0; SET FOREIGN_KEY_CHECKS=0;
-- 数据表 -- 数据字典
-- DROP TABLE IF EXISTS `metadata`; -- DROP TABLE IF EXISTS `dictionary`;
CREATE TABLE `metadata` ( CREATE TABLE `dictionary` (
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`parent_id` int unsigned NOT NULL COMMENT '父ID', `parent_id` int unsigned NOT NULL COMMENT '父ID',
`type` varchar(50) NOT NULL COMMENT '元数据类型', `type` varchar(50) NOT NULL COMMENT '字典类型',
`item_name` varchar(100) NOT NULL COMMENT '元数据项显示名', `item_name` varchar(100) NOT NULL COMMENT '字典项显示名',
`item_value` varchar(100) DEFAULT NULL COMMENT '元数据项存储值', `item_value` varchar(100) DEFAULT NULL COMMENT '字典项存储值',
`comment` varchar(100) DEFAULT NULL COMMENT '备注', `comment` varchar(100) DEFAULT NULL COMMENT '备注',
`extdata` varchar(200) DEFAULT NULL COMMENT '扩展属性', `extdata` varchar(200) DEFAULT NULL COMMENT '扩展属性',
`sort_id` smallint NOT NULL DEFAULT '99' COMMENT '排序号', `sort_id` smallint NOT NULL DEFAULT '99' COMMENT '排序号',
`system` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否系统预置', `system` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否系统预置',
`editable` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否可编辑', `editable` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否可编辑',
`active` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否有效', `active` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否有效',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `idx_metadata` (`type`) KEY `idx_dict` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@ -1,8 +1,7 @@
package diboot.core.test.binder.vo; package diboot.core.test.binder.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.diboot.core.binding.annotation.BindField; import com.diboot.core.binding.annotation.BindField;
import com.diboot.core.binding.annotation.BindMetadata; import com.diboot.core.binding.annotation.BindDict;
import diboot.core.test.binder.entity.Department; import diboot.core.test.binder.entity.Department;
import diboot.core.test.binder.entity.Organization; import diboot.core.test.binder.entity.Organization;
import diboot.core.test.binder.entity.User; import diboot.core.test.binder.entity.User;
@ -27,8 +26,8 @@ public class FieldBinderVO extends User{
@BindField(entity = Organization.class, field="telphone", condition="this.department_id=department.id AND department.org_id=id") @BindField(entity = Organization.class, field="telphone", condition="this.department_id=department.id AND department.org_id=id")
private String orgTelphone; private String orgTelphone;
// 绑定数据枚举 // 绑定数据字典枚举
@BindMetadata(type="GENDER", field = "gender") @BindDict(type="GENDER", field = "gender")
private String genderLabel; private String genderLabel;
public String getDeptName() { public String getDeptName() {

View File

@ -2,8 +2,8 @@ package diboot.core.test.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.diboot.core.config.BaseConfig; import com.diboot.core.config.BaseConfig;
import com.diboot.core.entity.Metadata; import com.diboot.core.entity.Dictionary;
import com.diboot.core.service.MetadataService; import com.diboot.core.service.DictionaryService;
import com.diboot.core.util.V; import com.diboot.core.util.V;
import com.diboot.core.vo.Pagination; import com.diboot.core.vo.Pagination;
import diboot.core.test.StartupApplication; import diboot.core.test.StartupApplication;
@ -27,33 +27,33 @@ import java.util.List;
public class BaseServiceTest { public class BaseServiceTest {
@Autowired @Autowired
MetadataService metadataService; DictionaryService dictionaryService;
@Test @Test
public void testGet(){ public void testGet(){
// 查询总数 // 查询总数
int count = metadataService.getEntityListCount(null); int count = dictionaryService.getEntityListCount(null);
Assert.assertTrue(count > 0); Assert.assertTrue(count > 0);
// 查询list // 查询list
List<Metadata> metadataList = metadataService.getEntityList(null); List<Dictionary> dictionaryList = dictionaryService.getEntityList(null);
Assert.assertTrue(V.notEmpty(metadataList)); Assert.assertTrue(V.notEmpty(dictionaryList));
Assert.assertTrue(metadataList.size() == count); Assert.assertTrue(dictionaryList.size() == count);
// 第一页数据 // 第一页数据
List<Metadata> pageList = metadataService.getEntityList(null, new Pagination()); List<Dictionary> pageList = dictionaryService.getEntityList(null, new Pagination());
Assert.assertTrue(pageList.size() > 0 && pageList.size() <= BaseConfig.getPageSize()); Assert.assertTrue(pageList.size() > 0 && pageList.size() <= BaseConfig.getPageSize());
// 查询单个记录 // 查询单个记录
Long id = metadataList.get(0).getId(); Long id = dictionaryList.get(0).getId();
Metadata first = metadataService.getEntity(id); Dictionary first = dictionaryService.getEntity(id);
Assert.assertTrue(first != null); Assert.assertTrue(first != null);
// 只查询第一条记录对应type类型的 // 只查询第一条记录对应type类型的
LambdaQueryWrapper<Metadata> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<Dictionary> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Metadata::getType, first.getType()); queryWrapper.eq(Dictionary::getType, first.getType());
metadataList = metadataService.getEntityList(queryWrapper); dictionaryList = dictionaryService.getEntityList(queryWrapper);
Assert.assertTrue(V.notEmpty(metadataList)); Assert.assertTrue(V.notEmpty(dictionaryList));
// 结果type值一致 // 结果type值一致
metadataList.stream().forEach( m -> { dictionaryList.stream().forEach(m -> {
Assert.assertTrue(m.getType().equals(first.getType())); Assert.assertTrue(m.getType().equals(first.getType()));
}); });
} }
@ -62,28 +62,28 @@ public class BaseServiceTest {
public void testCreateUpdateAndDelete(){ public void testCreateUpdateAndDelete(){
// 创建 // 创建
String TYPE = "ID_TYPE"; String TYPE = "ID_TYPE";
Metadata metadata = new Metadata(); Dictionary dictionary = new Dictionary();
metadata.setType(TYPE); dictionary.setType(TYPE);
metadata.setItemName("证件品类"); dictionary.setItemName("证件品类");
metadata.setParentId(0L); dictionary.setParentId(0L);
metadataService.createEntity(metadata); dictionaryService.createEntity(dictionary);
// 查询是否创建成功 // 查询是否创建成功
LambdaQueryWrapper<Metadata> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<Dictionary> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Metadata::getType, TYPE); queryWrapper.eq(Dictionary::getType, TYPE);
List<Metadata> metadataList = metadataService.getEntityList(queryWrapper); List<Dictionary> dictionaryList = dictionaryService.getEntityList(queryWrapper);
Assert.assertTrue(V.notEmpty(metadataList)); Assert.assertTrue(V.notEmpty(dictionaryList));
// 更新 // 更新
metadata.setItemName("证件类型"); dictionary.setItemName("证件类型");
metadataService.updateEntity(metadata); dictionaryService.updateEntity(dictionary);
Metadata metadata2 = metadataService.getEntity(metadata.getId()); Dictionary dictionary2 = dictionaryService.getEntity(dictionary.getId());
Assert.assertTrue(metadata2.getItemName().equals(metadata.getItemName())); Assert.assertTrue(dictionary2.getItemName().equals(dictionary.getItemName()));
// 删除 // 删除
metadataService.deleteEntity(metadata.getId()); dictionaryService.deleteEntity(dictionary.getId());
metadata2 = metadataService.getEntity(metadata.getId()); dictionary2 = dictionaryService.getEntity(dictionary.getId());
Assert.assertTrue(metadata2 == null); Assert.assertTrue(dictionary2 == null);
} }
} }

View File

@ -1,6 +1,6 @@
package diboot.core.test.util; package diboot.core.test.util;
import com.diboot.core.entity.Metadata; import com.diboot.core.entity.Dictionary;
import com.diboot.core.util.BeanUtils; import com.diboot.core.util.BeanUtils;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
@ -21,75 +21,75 @@ public class BeanUtilsTest {
@Test @Test
public void testCopyBean(){ public void testCopyBean(){
String itemName = "在职"; String itemName = "在职";
Metadata metadata1 = new Metadata(); Dictionary dictionary1 = new Dictionary();
metadata1.setType("STATUS"); dictionary1.setType("STATUS");
metadata1.setItemName(itemName); dictionary1.setItemName(itemName);
Metadata metadata2 = new Metadata(); Dictionary dictionary2 = new Dictionary();
BeanUtils.copyProperties(metadata1, metadata2); BeanUtils.copyProperties(dictionary1, dictionary2);
Assert.assertTrue(metadata2.getItemName().equals(itemName)); Assert.assertTrue(dictionary2.getItemName().equals(itemName));
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
map.put("type", "STATUS"); map.put("type", "STATUS");
map.put("itemName",itemName); map.put("itemName",itemName);
Metadata metadata3 = new Metadata(); Dictionary dictionary3 = new Dictionary();
BeanUtils.bindProperties(metadata3, map); BeanUtils.bindProperties(dictionary3, map);
Assert.assertTrue(metadata2.getItemName().equals(itemName)); Assert.assertTrue(dictionary2.getItemName().equals(itemName));
} }
@Test @Test
public void testGetProperty(){ public void testGetProperty(){
Metadata metadata1 = new Metadata(); Dictionary dictionary1 = new Dictionary();
metadata1.setId(1001L); dictionary1.setId(1001L);
// getProperty // getProperty
Object id = BeanUtils.getProperty(metadata1, "id"); Object id = BeanUtils.getProperty(dictionary1, "id");
Assert.assertTrue(id instanceof Long); Assert.assertTrue(id instanceof Long);
// getStringProperty // getStringProperty
Assert.assertTrue(BeanUtils.getStringProperty(metadata1, "id").equals("1001")); Assert.assertTrue(BeanUtils.getStringProperty(dictionary1, "id").equals("1001"));
} }
@Test @Test
public void testConvert(){ public void testConvert(){
List<Metadata> metadataList = new ArrayList<>(); List<Dictionary> dictionaryList = new ArrayList<>();
for(long id=1001; id<1005; id++){ for(long id=1001; id<1005; id++){
Metadata metadata1 = new Metadata(); Dictionary dictionary1 = new Dictionary();
metadata1.setId(id); dictionary1.setId(id);
metadataList.add(metadata1); dictionaryList.add(dictionary1);
} }
List<Long> metaIdList = BeanUtils.collectToList(metadataList, Metadata::getId); List<Long> metaIdList = BeanUtils.collectToList(dictionaryList, Dictionary::getId);
Assert.assertTrue(metaIdList.size() == 4); Assert.assertTrue(metaIdList.size() == 4);
} }
@Test @Test
public void testGetterSetter(){ public void testGetterSetter(){
Assert.assertEquals(BeanUtils.convertToFieldName(Metadata::getItemName), "itemName"); Assert.assertEquals(BeanUtils.convertToFieldName(Dictionary::getItemName), "itemName");
Assert.assertEquals(BeanUtils.convertToFieldName(Metadata::setItemName), "itemName"); Assert.assertEquals(BeanUtils.convertToFieldName(Dictionary::setItemName), "itemName");
} }
@Test @Test
public void testBindProp(){ public void testBindProp(){
List<Metadata> metadataList = new ArrayList<>(); List<Dictionary> dictionaryList = new ArrayList<>();
for(long id=1001; id<1005; id++){ for(long id=1001; id<1005; id++){
Metadata metadata1 = new Metadata(); Dictionary dictionary1 = new Dictionary();
metadata1.setId(id); dictionary1.setId(id);
metadataList.add(metadata1); dictionaryList.add(dictionary1);
} }
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
map.put("1001", "在职"); map.put("1001", "在职");
map.put("1002", "在职"); map.put("1002", "在职");
map.put("1003", "离职"); map.put("1003", "离职");
BeanUtils.bindPropValueOfList(Metadata::setItemName, metadataList, Metadata::getId, map); BeanUtils.bindPropValueOfList(Dictionary::setItemName, dictionaryList, Dictionary::getId, map);
Assert.assertEquals(metadataList.get(0).getItemName(), "在职"); Assert.assertEquals(dictionaryList.get(0).getItemName(), "在职");
Assert.assertEquals(metadataList.get(2).getItemName(), "离职"); Assert.assertEquals(dictionaryList.get(2).getItemName(), "离职");
Map<Long, String> map2 = new HashMap<>(); Map<Long, String> map2 = new HashMap<>();
map2.put(1001L, "在职"); map2.put(1001L, "在职");
map2.put(1002L, "在职"); map2.put(1002L, "在职");
map2.put(1003L, "离职"); map2.put(1003L, "离职");
BeanUtils.bindPropValueOfList("itemName", metadataList, "id", map2); BeanUtils.bindPropValueOfList("itemName", dictionaryList, "id", map2);
Assert.assertEquals(metadataList.get(0).getItemName(), "在职"); Assert.assertEquals(dictionaryList.get(0).getItemName(), "在职");
Assert.assertEquals(metadataList.get(2).getItemName(), "离职"); Assert.assertEquals(dictionaryList.get(2).getItemName(), "离职");
} }
} }

View File

@ -13,18 +13,18 @@ create table department
) )
comment '组织单位' charset=utf8mb4; comment '组织单位' charset=utf8mb4;
create table metadata create table dictionary
( (
id int unsigned auto_increment comment 'ID' id int unsigned auto_increment comment 'ID'
primary key, primary key,
parent_id int unsigned not null comment '父ID', parent_id int unsigned not null comment '父ID',
type varchar(50) not null comment '元数据类型', type varchar(50) not null comment '字典类型',
item_name varchar(100) not null comment '元数据项显示名', item_name varchar(100) not null comment '字典项显示名',
item_value varchar(100) null comment '元数据项存储值', item_value varchar(100) null comment '字典项存储值',
comment varchar(200) null comment '备注', comment varchar(200) null comment '备注',
extdata varchar(200) null comment '扩展属性', extdata varchar(200) null comment '扩展属性',
sort_id smallint(6) default 99 not null comment '排序号', sort_id smallint(6) default 99 not null comment '排序号',
`system` tinyint(1) default 0 not null comment '是否系统预置', `system` tinyint(1) default 0 not null comment '是否系统预置',
editable tinyint(1) default 1 not null comment '是否可编辑', editable tinyint(1) default 1 not null comment '是否可编辑',
deleted tinyint(1) default 0 not null comment '已删除', deleted tinyint(1) default 0 not null comment '已删除',
create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间' create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间'
@ -74,7 +74,7 @@ create table user_role
INSERT INTO department (id, parent_id, org_id, name) INSERT INTO department (id, parent_id, org_id, name)
VALUES (10001, 0, 100001, '产品部'), (10002, 10001, 100001, '研发组'), (10003, 10001, 100001, '测试组'); VALUES (10001, 0, 100001, '产品部'), (10002, 10001, 100001, '研发组'), (10003, 10001, 100001, '测试组');
INSERT INTO metadata (id, parent_id, type, item_name, item_value, comment, extdata, sort_id, `system`, editable) INSERT INTO dictionary (id, parent_id, type, item_name, item_value, comment, extdata, sort_id, `system`, editable)
VALUES (1, 0, 'GENDER', '性别', null, '', null, 99, 1, 1), (2, 1, 'GENDER', '', 'M', null, null, 99, 1, 0), (3, 1, 'GENDER', '', 'F', null, null, 99, 1, 0); VALUES (1, 0, 'GENDER', '性别', null, '', null, 99, 1, 1), (2, 1, 'GENDER', '', 'M', null, null, 99, 1, 0), (3, 1, 'GENDER', '', 'F', null, null, 99, 1, 0);
INSERT INTO organization (id, parent_id, name, telphone) VALUES (100001, 0, '苏州帝博', '0512-62988949'); INSERT INTO organization (id, parent_id, name, telphone) VALUES (100001, 0, '苏州帝博', '0512-62988949');

View File

@ -1,5 +1,6 @@
package com.diboot.example.config; package com.diboot.example.config;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.injector.ISqlInjector; import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector; import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
@ -32,7 +33,7 @@ public class MybatisPlusConfig {
*/ */
@Bean @Bean
public ISqlInjector sqlInjector() { public ISqlInjector sqlInjector() {
return new LogicSqlInjector(); return new DefaultSqlInjector();
} }
} }

View File

@ -1,17 +1,13 @@
package com.diboot.example.vo; package com.diboot.example.vo;
import com.diboot.core.binding.annotation.BindEntity; import com.diboot.core.binding.annotation.BindEntity;
import com.diboot.core.binding.annotation.BindEntityList;
import com.diboot.core.binding.annotation.BindField; import com.diboot.core.binding.annotation.BindField;
import com.diboot.core.binding.annotation.BindMetadata; import com.diboot.core.binding.annotation.BindDict;
import com.diboot.example.entity.Department; import com.diboot.example.entity.Department;
import com.diboot.example.entity.Organization; import com.diboot.example.entity.Organization;
import com.diboot.example.entity.Role;
import com.diboot.example.entity.User; import com.diboot.example.entity.User;
import lombok.Data; import lombok.Data;
import java.util.List;
/** /**
* @author Mazhicheng * @author Mazhicheng
* @version v2.0 * @version v2.0
@ -21,8 +17,8 @@ import java.util.List;
public class UserVO extends User { public class UserVO extends User {
private static final long serialVersionUID = 3526115343377985725L; private static final long serialVersionUID = 3526115343377985725L;
// 绑定数据枚举 // 绑定数据字典枚举
@BindMetadata(type="GENDER", field = "gender") @BindDict(type="GENDER", field = "gender")
private String genderLabel; private String genderLabel;
// 字段关联相同条件的entity+condition将合并为一条SQL查询 // 字段关联相同条件的entity+condition将合并为一条SQL查询

View File

@ -13,18 +13,18 @@ create table department
) )
comment '组织单位' charset=utf8mb4; comment '组织单位' charset=utf8mb4;
create table metadata create table dictionary
( (
id int unsigned auto_increment comment 'ID' id int unsigned auto_increment comment 'ID'
primary key, primary key,
parent_id int unsigned not null comment '父ID', parent_id int unsigned not null comment '父ID',
type varchar(50) not null comment '元数据类型', type varchar(50) not null comment '字典类型',
item_name varchar(100) not null comment '元数据项显示名', item_name varchar(100) not null comment '字典项显示名',
item_value varchar(100) null comment '元数据项存储值', item_value varchar(100) null comment '字典项存储值',
comment varchar(200) null comment '备注', comment varchar(200) null comment '备注',
extdata varchar(200) null comment '扩展属性', extdata varchar(200) null comment '扩展属性',
sort_id smallint(6) default 99 not null comment '排序号', sort_id smallint(6) default 99 not null comment '排序号',
`system` tinyint(1) default 0 not null comment '是否系统预置', `system` tinyint(1) default 0 not null comment '是否系统预置',
editable tinyint(1) default 1 not null comment '是否可编辑', editable tinyint(1) default 1 not null comment '是否可编辑',
deleted tinyint(1) default 0 not null comment '已删除', deleted tinyint(1) default 0 not null comment '已删除',
create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间' create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间'
@ -74,7 +74,7 @@ create table user_role
INSERT INTO department (id, parent_id, org_id, name) INSERT INTO department (id, parent_id, org_id, name)
VALUES (10001, 0, 100001, '产品部'), (10002, 10001, 100001, '研发组'), (10003, 10001, 100001, '测试组'); VALUES (10001, 0, 100001, '产品部'), (10002, 10001, 100001, '研发组'), (10003, 10001, 100001, '测试组');
INSERT INTO metadata (id, parent_id, type, item_name, item_value, comment, extdata, sort_id, `system`, editable) INSERT INTO dictionary (id, parent_id, type, item_name, item_value, comment, extdata, sort_id, `system`, editable)
VALUES (1, 0, 'GENDER', '性别', null, '', null, 99, 1, 1), (2, 1, 'GENDER', '', 'M', null, null, 99, 1, 0), (3, 1, 'GENDER', '', 'F', null, null, 99, 1, 0); VALUES (1, 0, 'GENDER', '性别', null, '', null, 99, 1, 1), (2, 1, 'GENDER', '', 'M', null, null, 99, 1, 0), (3, 1, 'GENDER', '', 'F', null, null, 99, 1, 0);
INSERT INTO organization (id, parent_id, name, telphone) VALUES (100001, 0, '苏州帝博', '0512-62988949'); INSERT INTO organization (id, parent_id, name, telphone) VALUES (100001, 0, '苏州帝博', '0512-62988949');