合并代码

This commit is contained in:
wuy 2019-07-18 13:05:52 +08:00
commit f474e81e9b
40 changed files with 1011 additions and 303 deletions

View File

@ -1,3 +1,4 @@
apply plugin: 'org.springframework.boot'
dependencies {
compile project(":diboot-core")

View File

@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.components.msg.entity.Message;
import com.diboot.components.msg.service.MessageService;
import com.diboot.components.msg.vo.MessageVO;
import com.diboot.core.binding.manager.AnnotationBindingManager;
import com.diboot.core.binding.manager.RelationsBinder;
import com.diboot.core.controller.BaseCrudRestController;
import com.diboot.core.service.BaseService;
import com.diboot.core.vo.JsonResult;
@ -39,7 +39,7 @@ public class MessageController extends BaseCrudRestController {
// 查询当前页的Entity主表数据
List<Message> entityList = getService().getEntityList(queryWrapper, pagination);
// 自动转换VO中注解绑定的关联
List<MessageVO> voList = AnnotationBindingManager.autoConvertAndBind(entityList, MessageVO.class);
List<MessageVO> voList = RelationsBinder.convertAndBind(entityList, MessageVO.class);
//返回结果
return new JsonResult(Status.OK, voList).bindPagination(pagination);
}

View File

@ -48,14 +48,14 @@ private List<Role> roleList;
~~~java
// 调用AnnotationBindingManager自动绑定注解相关关联
//List<MyUserVO> voList = ...;
AnnotationBindingManager.autoBind(voList);
RelationsBinder.bind(voList);
~~~
#### 2. 自动转型并绑定关联(需要转型)
~~~java
// 获取Entity列表
List<User> entityList = userService.getEntityList(queryWrapper);
// 调用AnnotationBindingManager自动绑定注解相关关联
List<MyUserVO> voList = AnnotationBindingManager.autoConvertAndBind(userList, MyUserVO.class);
List<MyUserVO> voList = RelationsBinder.convertAndBind(userList, MyUserVO.class);
~~~

View File

@ -1,16 +1,23 @@
package com.diboot.core.binding;
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.extension.service.IService;
import com.diboot.core.binding.parser.MiddleTable;
import com.diboot.core.config.BaseConfig;
import com.diboot.core.service.BaseService;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.IGetter;
import com.diboot.core.util.S;
import com.diboot.core.vo.Pagination;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* 关系绑定Binder父类
@ -31,7 +38,7 @@ public abstract class BaseBinder<T> {
/**
* 被关联对象的Service实例
*/
protected BaseService<T> referencedService;
protected IService<T> referencedService;
/***
* DO对象中的主键属性名
*/
@ -141,4 +148,48 @@ public abstract class BaseBinder<T> {
*/
public abstract void bind();
/**
* 获取EntityList
* @param queryWrapper
* @return
*/
protected List<T> getEntityList(Wrapper queryWrapper) {
if(referencedService instanceof BaseService){
return ((BaseService)referencedService).getEntityList(queryWrapper, null);
}
else{
List<T> list = referencedService.list(queryWrapper);
return checkedList(list);
}
}
/**
* 获取Map结果
* @param queryWrapper
* @return
*/
protected List<Map<String, Object>> getMapList(Wrapper queryWrapper) {
if(referencedService instanceof BaseService){
return ((BaseService)referencedService).getMapList(queryWrapper);
}
else{
List<Map<String, Object>> list = referencedService.listMaps(queryWrapper);
return checkedList(list);
}
}
/**
* 检查list结果过多打印warn
* @param list
* @return
*/
private List checkedList(List list){
if(list == null){
list = Collections.emptyList();
}
else if(list.size() > BaseConfig.getBatchSize()){
log.warn("单次查询记录数量过大,返回结果数={},请检查!", list.size());
}
return list;
}
}

View File

@ -1,6 +1,7 @@
package com.diboot.core.binding;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.diboot.core.service.BaseService;
import com.diboot.core.util.*;
import org.slf4j.Logger;
@ -31,7 +32,7 @@ public class EntityBinder<T> extends BaseBinder<T> {
* @param referencedService
* @param voList
*/
public EntityBinder(BaseService<T> referencedService, List voList){
public EntityBinder(IService<T> referencedService, List voList){
this.referencedService = referencedService;
this.annoObjectList = voList;
this.queryWrapper = new QueryWrapper<T>();
@ -85,7 +86,7 @@ public class EntityBinder<T> extends BaseBinder<T> {
// 构建查询条件
queryWrapper.in(S.toSnakeCase(referencedEntityPrimaryKey), middleTableColumnValueList);
// 查询entity列表
List<T> list = referencedService.getEntityList(queryWrapper);
List<T> list = getEntityList(queryWrapper);
if(V.notEmpty(list)){
// 转换entity列表为Map<ID, Entity>
Map<String, T> listMap = BeanUtils.convertToStringKeyObjectMap(list, S.toLowerCaseCamel(referencedEntityPrimaryKey));
@ -96,7 +97,7 @@ public class EntityBinder<T> extends BaseBinder<T> {
}
String key = entry.getKey();
T value = listMap.get(String.valueOf(fetchValueId));
valueEntityMap.put(key, value);
valueEntityMap.put(key, cloneEntity(value));
}
}
}
@ -108,12 +109,12 @@ public class EntityBinder<T> extends BaseBinder<T> {
// 构建查询条件
queryWrapper.in(S.toSnakeCase(referencedEntityPrimaryKey), annoObjectForeignKeyList);
// 查询entity列表
List<T> list = referencedService.getEntityList(queryWrapper);
List<T> list = getEntityList(queryWrapper);
if(V.notEmpty(list)){
String refEntityPKFieldName = S.toLowerCaseCamel(referencedEntityPrimaryKey);
for(T entity : list){
String pkValue = BeanUtils.getStringProperty(entity, refEntityPKFieldName);
valueEntityMap.put(pkValue, entity);
valueEntityMap.put(pkValue, cloneEntity(entity));
}
}
}
@ -121,4 +122,23 @@ public class EntityBinder<T> extends BaseBinder<T> {
BeanUtils.bindPropValueOfList(annoObjectField, annoObjectList, annoObjectForeignKey, valueEntityMap);
}
/**
* 克隆对象
* @param ent
* @param <T>
* @return
*/
protected <T> T cloneEntity(T ent){
// 克隆对象
try{
T cloneEnt = (T)org.springframework.beans.BeanUtils.instantiateClass(ent.getClass());
BeanUtils.copyProperties(ent ,cloneEnt);
return cloneEnt;
}
catch (Exception e){
log.warn("Clone Object "+ent.getClass().getSimpleName()+" error", e);
return ent;
}
}
}

View File

@ -1,6 +1,7 @@
package com.diboot.core.binding;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.diboot.core.service.BaseService;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.S;
@ -25,7 +26,7 @@ public class EntityListBinder<T> extends EntityBinder<T> {
* @param serviceInstance
* @param voList
*/
public EntityListBinder(BaseService<T> serviceInstance, List voList){
public EntityListBinder(IService<T> serviceInstance, List voList){
this.referencedService = serviceInstance;
this.annoObjectList = voList;
this.queryWrapper = new QueryWrapper<T>();
@ -56,7 +57,7 @@ public class EntityListBinder<T> extends EntityBinder<T> {
// 构建查询条件
queryWrapper.in(S.toSnakeCase(referencedEntityPrimaryKey), entityIdList);
// 查询entity列表: List<Role>
List list = referencedService.getEntityList(queryWrapper);
List list = getEntityList(queryWrapper);
// 转换entity列表为Map<ID, Entity>
Map<String, T> entityMap = BeanUtils.convertToStringKeyObjectMap(list, S.toLowerCaseCamel(referencedEntityPrimaryKey));
for(Map.Entry<String, List> entry : middleTableResultMap.entrySet()){
@ -69,7 +70,7 @@ public class EntityListBinder<T> extends EntityBinder<T> {
for(Object obj : annoObjFKList){
T ent = entityMap.get(String.valueOf(obj));
if(ent != null){
valueList.add(ent);
valueList.add(cloneEntity(ent));
}
}
valueEntityListMap.put(entry.getKey(), valueList);
@ -80,7 +81,7 @@ public class EntityListBinder<T> extends EntityBinder<T> {
// 构建查询条件
queryWrapper.in(S.toSnakeCase(referencedEntityPrimaryKey), annoObjectForeignKeyList);
// 查询entity列表
List<T> list = referencedService.getEntityList(queryWrapper);
List<T> list = getEntityList(queryWrapper);
if(V.notEmpty(list)){
for(T entity : list){
String keyValue = BeanUtils.getStringProperty(entity, S.toLowerCaseCamel(referencedEntityPrimaryKey));
@ -89,7 +90,7 @@ public class EntityListBinder<T> extends EntityBinder<T> {
entityList = new ArrayList<>();
valueEntityListMap.put(keyValue, entityList);
}
entityList.add(entity);
entityList.add(cloneEntity(entity));
}
}
}

View File

@ -1,6 +1,7 @@
package com.diboot.core.binding;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.diboot.core.binding.annotation.BindField;
import com.diboot.core.service.BaseService;
import com.diboot.core.util.*;
@ -33,7 +34,7 @@ public class FieldBinder<T> extends BaseBinder<T> {
* @param serviceInstance
* @param voList
*/
public FieldBinder(BaseService<T> serviceInstance, List voList){
public FieldBinder(IService<T> serviceInstance, List voList){
this.referencedService = serviceInstance;
this.annoObjectList = voList;
this.queryWrapper = new QueryWrapper<T>();
@ -113,7 +114,7 @@ public class FieldBinder<T> extends BaseBinder<T> {
}
// 获取匹配结果的mapList
List<Map<String, Object>> mapList = referencedService.getMapList(queryWrapper);
List<Map<String, Object>> mapList = getMapList(queryWrapper);
if(V.isEmpty(mapList)){
return;
}

View File

@ -1,6 +1,9 @@
package com.diboot.core.binding.manager;
import com.baomidou.mybatisplus.extension.service.IService;
import com.diboot.core.binding.BaseBinder;
import com.diboot.core.binding.EntityBinder;
import com.diboot.core.binding.EntityListBinder;
import com.diboot.core.binding.FieldBinder;
import com.diboot.core.binding.annotation.BindEntity;
import com.diboot.core.binding.annotation.BindEntityList;
@ -25,11 +28,13 @@ import java.util.HashMap;
import java.util.List;
/**
* 绑定管理器
* 绑定管理器 (已废弃请调用RelationsBinder)
* @author Mazhicheng
* @version v2.0
* @date 2019/3/30
* @see com.diboot.core.binding.manager.RelationsBinder
*/
@Deprecated
public class AnnotationBindingManager {
private static final Logger log = LoggerFactory.getLogger(AnnotationBindingManager.class);
@ -42,11 +47,7 @@ public class AnnotationBindingManager {
* @return
*/
public static <E, VO> List<VO> autoConvertAndBind(List<E> entityList, Class<VO> voClass){
// 转换为VO列表
List<VO> voList = BeanUtils.convertList(entityList, voClass);
// 自动绑定关联对象
autoBind(voList);
return voList;
return RelationsBinder.convertAndBind(entityList, voClass);
}
/**
@ -55,172 +56,7 @@ public class AnnotationBindingManager {
* @throws Exception
*/
public static <VO> void autoBind(List<VO> voList){
if(V.isEmpty(voList)){
return;
}
// 获取VO类
Class voClass = voList.get(0).getClass();
BindAnnotationGroup bindAnnotationGroup = BindAnnotationCacheManager.getBindAnnotationGroup(voClass);
if(bindAnnotationGroup.isNotEmpty()){
// 绑定数据字典
List<FieldAnnotation> dictAnnoList = bindAnnotationGroup.getBindDictAnnotations();
if(dictAnnoList != null){
for(FieldAnnotation annotation : dictAnnoList){
doBindingDict(voList, annotation);
}
}
// 绑定Field字段名
List<FieldAnnotation> fieldAnnoList = bindAnnotationGroup.getBindFieldAnnotations();
if(fieldAnnoList != null){
doBindingField(voList, fieldAnnoList);
}
// 绑定Entity实体
List<FieldAnnotation> entityAnnoList = bindAnnotationGroup.getBindEntityAnnotations();
if(entityAnnoList != null){
for(FieldAnnotation anno : entityAnnoList){
doBindingEntity(voList, anno);
}
}
// 绑定Entity实体List
List<FieldAnnotation> entitiesAnnoList = bindAnnotationGroup.getBindEntityListAnnotations();
if(entitiesAnnoList != null){
for(FieldAnnotation anno : entitiesAnnoList){
doBindingEntityList(voList, anno);
}
}
}
}
/***
* 绑定数据字典
* @param voList
* @param fieldAnno
* @param <VO>
*/
private static <VO> void doBindingDict(List<VO> voList, FieldAnnotation fieldAnno) {
DictionaryService dictionaryService = (DictionaryService) ContextHelper.getBean(DictionaryService.class);
if(dictionaryService != null){
BindDict annotation = (BindDict) fieldAnno.getAnnotation();
dictionaryService.bindItemLabel(voList, fieldAnno.getFieldName(), annotation.field(), annotation.type());
}
}
/***
* 绑定字段
* @param voList
* @param fieldAnnoList
* @param <VO>
*/
private static <VO> void doBindingField(List<VO> voList, List<FieldAnnotation> fieldAnnoList) {
//多个字段合并查询以减少SQL数
Map<String, List<FieldAnnotation>> clazzToListMap = new HashMap<>();
for(FieldAnnotation anno : fieldAnnoList){
BindField bindField = (BindField) anno.getAnnotation();
String key = bindField.entity().getName() + ":" + bindField.condition();
List<FieldAnnotation> list = clazzToListMap.computeIfAbsent(key, k -> new ArrayList<>());
list.add(anno);
}
// 解析条件并且执行绑定
for(Map.Entry<String, List<FieldAnnotation>> entry : clazzToListMap.entrySet()){
List<FieldAnnotation> list = entry.getValue();
BindField bindAnnotation = (BindField) list.get(0).getAnnotation();
BaseService service = getService(bindAnnotation);
FieldBinder binder = service.bindingFieldTo(voList);
for(FieldAnnotation anno : list){
BindField bindField = (BindField) anno.getAnnotation();
binder.link(bindField.field(), anno.getFieldName());
}
parseConditionsAndBinding(binder, bindAnnotation.condition());
}
}
/***
* 绑定Entity
* @param voList
* @param fieldAnnotation
* @param <VO>
*/
private static <VO> void doBindingEntity(List<VO> voList, FieldAnnotation fieldAnnotation) {
BindEntity annotation = (BindEntity) fieldAnnotation.getAnnotation();
// 绑定关联对象entity
BaseService service = getService(annotation);
if(service != null){
// 字段名
String voFieldName = fieldAnnotation.getFieldName();
// 构建binder
BaseBinder binder = service.bindingEntityTo(voList).set(voFieldName);
// 解析条件并且执行绑定
parseConditionsAndBinding(binder, annotation.condition());
}
}
/***
* 绑定Entity
* @param voList
* @param fieldAnnotation
* @param <VO>
*/
private static <VO> void doBindingEntityList(List<VO> voList, FieldAnnotation fieldAnnotation) {
BindEntityList bindAnnotation = (BindEntityList) fieldAnnotation.getAnnotation();
// 绑定关联对象entity
BaseService service = getService(bindAnnotation);
if(service != null){
// 字段名
String voFieldName = fieldAnnotation.getFieldName();
// 构建binder
BaseBinder binder = service.bindingEntityListTo(voList).set(voFieldName);
// 解析条件并且执行绑定
parseConditionsAndBinding(binder, bindAnnotation.condition());
}
}
/***
* 解析条件并且执行绑定
* @param condition
* @param binder
*/
private static void parseConditionsAndBinding(BaseBinder binder, String condition){
try{
ConditionManager.parseConditions(condition, binder);
binder.bind();
}
catch (Exception e){
log.error("解析注解条件与绑定执行异常", e);
}
}
/**
* 通过Entity获取对应的Service实现类
* @param annotation
* @return
*/
private static BaseService getService(Annotation annotation){
Class<?> entityClass = null;
if(annotation instanceof BindDict){
entityClass = Dictionary.class;
}
else if(annotation instanceof BindField){
BindField bindAnnotation = (BindField)annotation;
entityClass = bindAnnotation.entity();
}
else if(annotation instanceof BindEntity){
BindEntity bindAnnotation = (BindEntity)annotation;
entityClass = bindAnnotation.entity();
}
else if(annotation instanceof BindEntityList){
BindEntityList bindAnnotation = (BindEntityList)annotation;
entityClass = bindAnnotation.entity();
}
else{
log.warn("非预期的注解: "+ annotation.getClass().getSimpleName());
return null;
}
// 根据entity获取Service
BaseService service = ContextHelper.getServiceByEntity(entityClass);
if(service == null){
log.error("未能识别到Entity: "+entityClass.getName()+" 的Service实现");
}
return service;
RelationsBinder.bind(voList);
}
}

View File

@ -0,0 +1,264 @@
package com.diboot.core.binding.manager;
import com.baomidou.mybatisplus.extension.service.IService;
import com.diboot.core.binding.BaseBinder;
import com.diboot.core.binding.EntityBinder;
import com.diboot.core.binding.EntityListBinder;
import com.diboot.core.binding.FieldBinder;
import com.diboot.core.binding.annotation.BindDict;
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.parser.BindAnnotationGroup;
import com.diboot.core.binding.parser.ConditionManager;
import com.diboot.core.binding.parser.FieldAnnotation;
import com.diboot.core.entity.Dictionary;
import com.diboot.core.service.DictionaryService;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.ContextHelper;
import com.diboot.core.util.V;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 绑定管理器
* @author Mazhicheng
* @version v2.0
* @date 2019/7/18
*/
public class RelationsBinder {
private static final Logger log = LoggerFactory.getLogger(RelationsBinder.class);
/**
* 自动转换和绑定VO中的注解关联
* @param entityList
* @param voClass
* @param <E>
* @param <VO>
* @return
*/
public static <E, VO> List<VO> convertAndBind(List<E> entityList, Class<VO> voClass){
// 转换为VO列表
List<VO> voList = BeanUtils.convertList(entityList, voClass);
// 自动绑定关联对象
bind(voList);
return voList;
}
/**
* 自动绑定关联对象
* @return
* @throws Exception
*/
public static <VO> void bind(List<VO> voList){
if(V.isEmpty(voList)){
return;
}
// 获取VO类
Class voClass = voList.get(0).getClass();
BindAnnotationGroup bindAnnotationGroup = BindAnnotationCacheManager.getBindAnnotationGroup(voClass);
if(bindAnnotationGroup.isNotEmpty()){
// 绑定数据字典
List<FieldAnnotation> dictAnnoList = bindAnnotationGroup.getBindDictAnnotations();
if(dictAnnoList != null){
for(FieldAnnotation annotation : dictAnnoList){
doBindingDict(voList, annotation);
}
}
// 绑定Field字段名
List<FieldAnnotation> fieldAnnoList = bindAnnotationGroup.getBindFieldAnnotations();
if(fieldAnnoList != null){
doBindingField(voList, fieldAnnoList);
}
// 绑定Entity实体
List<FieldAnnotation> entityAnnoList = bindAnnotationGroup.getBindEntityAnnotations();
if(entityAnnoList != null){
for(FieldAnnotation anno : entityAnnoList){
doBindingEntity(voList, anno);
}
}
// 绑定Entity实体List
List<FieldAnnotation> entitiesAnnoList = bindAnnotationGroup.getBindEntityListAnnotations();
if(entitiesAnnoList != null){
for(FieldAnnotation anno : entitiesAnnoList){
doBindingEntityList(voList, anno);
}
}
}
}
/***
* 绑定数据字典
* @param voList
* @param fieldAnno
* @param <VO>
*/
private static <VO> void doBindingDict(List<VO> voList, FieldAnnotation fieldAnno) {
DictionaryService dictionaryService = (DictionaryService) ContextHelper.getBean(DictionaryService.class);
if(dictionaryService != null){
BindDict annotation = (BindDict) fieldAnno.getAnnotation();
dictionaryService.bindItemLabel(voList, fieldAnno.getFieldName(), annotation.field(), annotation.type());
}
}
/***
* 绑定字段
* @param voList
* @param fieldAnnoList
* @param <VO>
*/
private static <VO> void doBindingField(List<VO> voList, List<FieldAnnotation> fieldAnnoList) {
//多个字段合并查询以减少SQL数
Map<String, List<FieldAnnotation>> clazzToListMap = new HashMap<>();
for(FieldAnnotation anno : fieldAnnoList){
BindField bindField = (BindField) anno.getAnnotation();
String key = bindField.entity().getName() + ":" + bindField.condition();
List<FieldAnnotation> list = clazzToListMap.computeIfAbsent(key, k -> new ArrayList<>());
list.add(anno);
}
// 解析条件并且执行绑定
for(Map.Entry<String, List<FieldAnnotation>> entry : clazzToListMap.entrySet()){
List<FieldAnnotation> list = entry.getValue();
BindField bindAnnotation = (BindField) list.get(0).getAnnotation();
FieldBinder binder = buildFieldBinder(bindAnnotation, voList);
for(FieldAnnotation anno : list){
BindField bindField = (BindField) anno.getAnnotation();
binder.link(bindField.field(), anno.getFieldName());
}
parseConditionsAndBinding(binder, bindAnnotation.condition());
}
}
/***
* 绑定Entity
* @param voList
* @param fieldAnnotation
* @param <VO>
*/
private static <VO> void doBindingEntity(List<VO> voList, FieldAnnotation fieldAnnotation) {
BindEntity annotation = (BindEntity) fieldAnnotation.getAnnotation();
// 绑定关联对象entity
EntityBinder binder = buildEntityBinder(annotation, voList);
if(binder != null){
// 构建binder
binder.set(fieldAnnotation.getFieldName());
// 解析条件并且执行绑定
parseConditionsAndBinding(binder, annotation.condition());
}
}
/***
* 绑定Entity
* @param voList
* @param fieldAnnotation
* @param <VO>
*/
private static <VO> void doBindingEntityList(List<VO> voList, FieldAnnotation fieldAnnotation) {
BindEntityList bindAnnotation = (BindEntityList) fieldAnnotation.getAnnotation();
// 构建binder
EntityListBinder binder = buildEntityListBinder(bindAnnotation, voList);
if(binder != null){
binder.set(fieldAnnotation.getFieldName());
// 解析条件并且执行绑定
parseConditionsAndBinding(binder, bindAnnotation.condition());
}
}
/***
* 解析条件并且执行绑定
* @param condition
* @param binder
*/
private static void parseConditionsAndBinding(BaseBinder binder, String condition){
try{
ConditionManager.parseConditions(condition, binder);
binder.bind();
}
catch (Exception e){
log.error("解析注解条件与绑定执行异常", e);
}
}
/**
* 构建FieldBinder
* @param annotation
* @param voList
* @return
*/
private static FieldBinder buildFieldBinder(Annotation annotation, List voList){
IService service = getService(annotation);
if(service != null){
return new FieldBinder<>(service, voList);
}
return null;
}
/**
* 构建EntityBinder
* @param annotation
* @param voList
* @return
*/
private static EntityBinder buildEntityBinder(Annotation annotation, List voList){
IService service = getService(annotation);
if(service != null){
return new EntityBinder<>(service, voList);
}
return null;
}
/**
* 构建EntityListBinder
* @param annotation
* @param voList
* @return
*/
private static EntityListBinder buildEntityListBinder(Annotation annotation, List voList){
IService service = getService(annotation);
if(service != null){
return new EntityListBinder<>(service, voList);
}
return null;
}
/**
* 通过Entity获取对应的Service实现类
* @param annotation
* @return
*/
private static IService getService(Annotation annotation){
Class<?> entityClass = null;
if(annotation instanceof BindDict){
entityClass = Dictionary.class;
}
else if(annotation instanceof BindField){
BindField bindAnnotation = (BindField)annotation;
entityClass = bindAnnotation.entity();
}
else if(annotation instanceof BindEntity){
BindEntity bindAnnotation = (BindEntity)annotation;
entityClass = bindAnnotation.entity();
}
else if(annotation instanceof BindEntityList){
BindEntityList bindAnnotation = (BindEntityList)annotation;
entityClass = bindAnnotation.entity();
}
else{
log.warn("非预期的注解: "+ annotation.getClass().getSimpleName());
return null;
}
// 根据entity获取Service
IService service = ContextHelper.getServiceByEntity(entityClass);
if(service == null){
log.error("未能识别到Entity: "+entityClass.getName()+" 的Service实现");
}
return service;
}
}

View File

@ -1,11 +1,9 @@
package com.diboot.core.controller;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.diboot.core.binding.manager.AnnotationBindingManager;
import com.diboot.core.binding.manager.RelationsBinder;
import com.diboot.core.entity.BaseEntity;
import com.diboot.core.service.BaseService;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.V;
import com.diboot.core.vo.JsonResult;
import com.diboot.core.vo.Status;
import com.diboot.core.vo.Pagination;
@ -202,7 +200,7 @@ public abstract class BaseCrudRestController extends BaseController {
*/
protected <VO> List<VO> convertToVoAndBindRelations(List entityList, Class<VO> voClass){
// 转换为VO
List<VO> voList = AnnotationBindingManager.autoConvertAndBind(entityList, voClass);
List<VO> voList = RelationsBinder.convertAndBind(entityList, voClass);
return voList;
}

View File

@ -3,12 +3,13 @@ package com.diboot.core.service.impl;
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.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.diboot.core.binding.manager.AnnotationBindingManager;
import com.diboot.core.binding.EntityBinder;
import com.diboot.core.binding.EntityListBinder;
import com.diboot.core.binding.FieldBinder;
import com.diboot.core.binding.manager.RelationsBinder;
import com.diboot.core.config.BaseConfig;
import com.diboot.core.config.Cons;
import com.diboot.core.mapper.BaseCrudMapper;
@ -247,7 +248,7 @@ public class BaseServiceImpl<M extends BaseCrudMapper<T>, T> extends ServiceImpl
List<T> enityList = new ArrayList<>();
enityList.add(entity);
// 绑定
List<VO> voList = AnnotationBindingManager.autoConvertAndBind(enityList, voClass);
List<VO> voList = RelationsBinder.convertAndBind(enityList, voClass);
return voList.get(0);
}
@ -255,7 +256,7 @@ public class BaseServiceImpl<M extends BaseCrudMapper<T>, T> extends ServiceImpl
public <VO> List<VO> getViewObjectList(Wrapper queryWrapper, Pagination pagination, Class<VO> voClass) {
List<T> entityList = getEntityList(queryWrapper, pagination);
// 自动转换为VO并绑定关联对象
List<VO> voList = AnnotationBindingManager.autoConvertAndBind(entityList, voClass);
List<VO> voList = RelationsBinder.convertAndBind(entityList, voClass);
return voList;
}
@ -264,17 +265,26 @@ public class BaseServiceImpl<M extends BaseCrudMapper<T>, T> extends ServiceImpl
* @param pagination
* @return
*/
protected IPage<T> convertToIPage(Pagination pagination){
protected Page<T> convertToIPage(Pagination pagination){
if(pagination == null){
return null;
}
IPage<T> page = new Page<T>()
Page<T> page = new Page<T>()
.setCurrent(pagination.getPageIndex())
.setSize(pagination.getPageSize())
// 如果前端传递过来了缓存的总数则本次不再count统计
.setTotal(pagination.getTotalCount() > 0? -1 : pagination.getTotalCount())
.setAscs(S.toSnakeCase(pagination.getAscList()))
.setDescs(S.toSnakeCase(pagination.getDescList()));
.setTotal(pagination.getTotalCount() > 0? -1 : pagination.getTotalCount());
// 排序
if(V.notEmpty(pagination.getAscList())){
pagination.getAscList().forEach(s -> {
page.addOrder(OrderItem.asc(s));
});
}
if(V.notEmpty(pagination.getDescList())){
pagination.getDescList().forEach(s -> {
page.addOrder(OrderItem.desc(s));
});
}
return page;
}

View File

@ -1,5 +1,7 @@
package com.diboot.core.util;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.diboot.core.service.BaseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -35,7 +37,7 @@ public class ContextHelper implements ApplicationContextAware {
/**
* Entity-对应的Mapper缓存
*/
private static Map<String, BaseService> entityToMapperCacheMap = new ConcurrentHashMap<>();
private static Map<String, IService> entityToMapperCacheMap = new ConcurrentHashMap<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
@ -106,11 +108,11 @@ public class ContextHelper implements ApplicationContextAware {
* @param entity
* @return
*/
public static BaseService getServiceByEntity(Class entity){
public static IService getServiceByEntity(Class entity){
if(entityToMapperCacheMap.isEmpty()){
Map<String, BaseService> serviceMap = getApplicationContext().getBeansOfType(BaseService.class);
Map<String, IService> serviceMap = getApplicationContext().getBeansOfType(IService.class);
if(V.notEmpty(serviceMap)){
for(Map.Entry<String, BaseService> entry : serviceMap.entrySet()){
for(Map.Entry<String, IService> entry : serviceMap.entrySet()){
String entityClassName = getEntityClassByServiceImpl(entry.getValue().getClass());
if(V.notEmpty(entityClassName)){
entityToMapperCacheMap.put(entityClassName, entry.getValue());

View File

@ -33,13 +33,14 @@ public class SqlExecutor {
log.warn("无法获取SqlSessionFactory实例SQL将不被执行。");
return null;
}
log.debug("==> SQL: "+sql);
// 替换单个?参数为多个用于拼接IN参数
if(V.notEmpty(params)){
log.debug("==> Params: {}", JSON.stringify(params));
if(params.size() > 2000){
log.warn("查询参数集合数量过多, size={},请检查调用是否合理!", params.size());
}
}
log.debug("==> SQL: "+sql);
try(SqlSession session = sqlSessionFactory.openSession(); Connection conn = session.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)){
if(V.notEmpty(params)){
for(int i=0; i<params.size(); i++){
@ -60,7 +61,7 @@ public class SqlExecutor {
}
rs.close();
}
log.debug("<== "+JSON.stringify(mapList));
log.debug("<== {}", JSON.stringify(mapList));
return mapList;
}
catch(Exception e){
@ -126,24 +127,31 @@ public class SqlExecutor {
return resultMap;
}
/**
* 执行更新操作
* @param sql
* @param params
* @return
* @throws Exception
*/
public static boolean executeUpdate(String sql, List params) throws Exception{
if (V.isEmpty(sql)){
return false;
}
// 获取SqlSessionFactory实例
SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) ContextHelper.getBean(SqlSessionFactory.class);
if (sqlSessionFactory == null){
log.warn("无法获取SqlSessionFactory实例SQL将不被执行。");
return false;
}
if (V.notEmpty(params)){
if (params.size() > 2000){
log.warn("SQL语句参数集合数量过多size={},请检查调用是否合理!", params.size());
log.debug("==> SQL: "+sql);
// 替换单个?参数为多个用于拼接IN参数
if(V.notEmpty(params)){
log.debug("==> Params: {}", JSON.stringify(params));
if(params.size() > 2000){
log.warn("更新参数集合数量过多, size={},请检查调用是否合理!", params.size());
}
}
log.debug("==> SQL:" + sql);
try(SqlSession session = sqlSessionFactory.openSession(); Connection conn = session.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)){
if (V.notEmpty(params)){
for (int i=0; i<params.size(); i++){

View File

@ -1,19 +1,20 @@
package diboot.core.test.binder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.diboot.core.binding.manager.AnnotationBindingManager;
import com.diboot.core.binding.manager.RelationsBinder;
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.EntityBinderVO;
import diboot.core.test.binder.vo.FieldBinderVO;
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;
@ -25,6 +26,7 @@ import java.util.List;
* @date 2019/06/22
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {SpringMvcConfig.class})
@SpringBootTest(classes = {StartupApplication.class})
public class TestEntityBinder {
@ -36,9 +38,9 @@ public class TestEntityBinder {
// 加载测试数据
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(User::getId, 1001L, 1002L);
List<User> userList = userService.getEntityList(queryWrapper);
List<User> userList = userService.list(queryWrapper);
// 自动绑定
List<EntityBinderVO> voList = AnnotationBindingManager.autoConvertAndBind(userList, EntityBinderVO.class);
List<EntityBinderVO> voList = RelationsBinder.convertAndBind(userList, EntityBinderVO.class);
// 验证绑定结果
if(V.notEmpty(voList)){
for(EntityBinderVO vo : voList){

View File

@ -1,8 +1,7 @@
package diboot.core.test.binder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.binding.manager.AnnotationBindingManager;
import com.diboot.core.binding.manager.RelationsBinder;
import com.diboot.core.util.JSON;
import com.diboot.core.util.V;
import diboot.core.test.StartupApplication;
@ -13,11 +12,13 @@ import diboot.core.test.binder.service.UserService;
import diboot.core.test.binder.vo.EntityBinderVO;
import diboot.core.test.binder.vo.EntityListComplexBinderVO;
import diboot.core.test.binder.vo.EntityListSimpleBinderVO;
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;
@ -29,6 +30,7 @@ import java.util.List;
* @date 2019/06/22
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {SpringMvcConfig.class})
@SpringBootTest(classes = {StartupApplication.class})
public class TestEntityListBinder {
@ -48,13 +50,19 @@ public class TestEntityListBinder {
queryWrapper.eq(Department::getId, 10001L);
List<Department> entityList = departmentService.getEntityList(queryWrapper);
// 自动绑定
List<EntityListSimpleBinderVO> voList = AnnotationBindingManager.autoConvertAndBind(entityList, EntityListSimpleBinderVO.class);
List<EntityListSimpleBinderVO> voList = RelationsBinder.convertAndBind(entityList, EntityListSimpleBinderVO.class);
// 验证绑定结果
if(V.notEmpty(voList)){
for(EntityListSimpleBinderVO vo : voList){
// 验证直接关联的绑定
Assert.assertTrue(V.notEmpty(vo.getChildren()));
System.out.println(JSON.stringify(vo));
if(vo.getChildren() != null){
for(Department dept : vo.getChildren()){
System.out.println(dept.toString());
}
}
}
}
}
@ -67,9 +75,9 @@ public class TestEntityListBinder {
// 加载测试数据
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(User::getId, 1001L, 1002L);
List<User> userList = userService.getEntityList(queryWrapper);
List<User> userList = userService.list(queryWrapper);
// 自动绑定
List<EntityListComplexBinderVO> voList = AnnotationBindingManager.autoConvertAndBind(userList, EntityListComplexBinderVO.class);
List<EntityListComplexBinderVO> voList = RelationsBinder.convertAndBind(userList, EntityListComplexBinderVO.class);
// 验证绑定结果
if(V.notEmpty(voList)){
for(EntityListComplexBinderVO vo : voList){

View File

@ -1,19 +1,20 @@
package diboot.core.test.binder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.diboot.core.binding.manager.AnnotationBindingManager;
import com.diboot.core.binding.manager.RelationsBinder;
import com.diboot.core.util.JSON;
import com.diboot.core.util.V;
import com.diboot.core.vo.Pagination;
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.FieldBinderVO;
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;
@ -25,6 +26,7 @@ import java.util.List;
* @date 2019/06/22
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {SpringMvcConfig.class})
@SpringBootTest(classes = {StartupApplication.class})
public class TestFieldBinder {
@ -36,9 +38,9 @@ public class TestFieldBinder {
// 加载测试数据
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(User::getId, 1001L, 1002L);
List<User> userList = userService.getEntityList(queryWrapper);
List<User> userList = userService.list(queryWrapper);
// 自动绑定
List<FieldBinderVO> voList = AnnotationBindingManager.autoConvertAndBind(userList, FieldBinderVO.class);
List<FieldBinderVO> voList = RelationsBinder.convertAndBind(userList, FieldBinderVO.class);
// 验证绑定结果
if(V.notEmpty(voList)){
for(FieldBinderVO vo : voList){

View File

@ -1,5 +1,6 @@
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.Role;
import diboot.core.test.binder.entity.User;
@ -10,6 +11,6 @@ import diboot.core.test.binder.entity.User;
* @version v2.0
* @date 2019/1/5
*/
public interface RoleService extends BaseService<Role> {
public interface RoleService extends IService<Role> {
}

View File

@ -1,5 +1,6 @@
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.User;
@ -9,6 +10,6 @@ import diboot.core.test.binder.entity.User;
* @version v2.0
* @date 2019/1/5
*/
public interface UserService extends BaseService<User> {
public interface UserService extends IService<User> {
}

View File

@ -1,5 +1,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.Role;
import diboot.core.test.binder.mapper.RoleMapper;
@ -13,6 +14,6 @@ import org.springframework.stereotype.Service;
* Copyright © www.dibo.ltd
*/
@Service
public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, Role> implements RoleService {
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
}

View File

@ -1,5 +1,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.User;
import diboot.core.test.binder.mapper.UserMapper;
@ -13,6 +14,6 @@ import org.springframework.stereotype.Service;
* Copyright © www.dibo.ltd
*/
@Service
public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implements UserService {
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}

View File

@ -11,6 +11,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@ -29,9 +30,7 @@ import java.util.List;
* @version v2.0
* @date 2019/6/10
*/
@Configuration
@EnableAutoConfiguration
@EnableTransactionManagement(proxyTargetClass=true)
@TestConfiguration
@ComponentScan(basePackages={"com.diboot", "diboot.core"})
@MapperScan({"com.diboot.**.mapper", "diboot.**.mapper"})
public class SpringMvcConfig implements WebMvcConfigurer{

View File

@ -8,11 +8,13 @@ import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.V;
import com.diboot.core.vo.Pagination;
import diboot.core.test.StartupApplication;
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.ArrayList;
@ -25,6 +27,7 @@ import java.util.List;
* @date 2019/06/15
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {SpringMvcConfig.class})
@SpringBootTest(classes = {StartupApplication.class})
public class BaseServiceTest {

View File

@ -15,7 +15,7 @@ public class PropertiesTest {
@Test
public void testGetString(){
String str1 = PropertiesUtils.get("spring.datasource.url");
String str2 = PropertiesUtils.get("spring.datasource.url", "application.properties");
String str2 = PropertiesUtils.get("spring.datasource.url", "application.properties.bak");
Assert.assertNotNull(str1);
Assert.assertNotNull(str2);
}

View File

@ -14,7 +14,6 @@ import com.diboot.example.entity.Organization;
import com.diboot.example.service.DepartmentService;
import com.diboot.example.vo.DepartmentVO;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;

View File

@ -1,7 +1,7 @@
package com.diboot.example.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.binding.manager.AnnotationBindingManager;
import com.diboot.core.binding.manager.RelationsBinder;
import com.diboot.core.controller.BaseCrudRestController;
import com.diboot.core.entity.Dictionary;
import com.diboot.core.service.BaseService;
@ -47,7 +47,7 @@ public class DictionaryController extends BaseCrudRestController {
//获取实体list
List<Dictionary> dictionaryList = dictionaryService.getEntityList(queryWrapper, pagination);
//筛选出在列表页展示的字段
List<DictionaryListVO> dicVoList = AnnotationBindingManager.autoConvertAndBind(dictionaryList, DictionaryListVO.class);
List<DictionaryListVO> dicVoList = RelationsBinder.convertAndBind(dictionaryList, DictionaryListVO.class);
//返回结果
return new JsonResult(Status.OK, dicVoList).bindPagination(pagination);
}

View File

@ -2,7 +2,7 @@ package com.diboot.example.controller;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.binding.manager.AnnotationBindingManager;
import com.diboot.core.binding.manager.RelationsBinder;
import com.diboot.core.controller.BaseCrudRestController;
import com.diboot.core.service.BaseService;
import com.diboot.core.service.DictionaryService;
@ -57,7 +57,7 @@ public class SysUserController extends BaseCrudRestController {
// 查询当前页的Entity主表数据
List<SysUserVO> voList = sysUserService.getSysUserList(queryWrapper, pagination);
//筛选出在列表页展示的字段
List<SysUserListVO> userVoList = AnnotationBindingManager.autoConvertAndBind(voList, SysUserListVO.class);
List<SysUserListVO> userVoList = RelationsBinder.convertAndBind(voList, SysUserListVO.class);
// 返回结果
return new JsonResult(Status.OK, userVoList).bindPagination(pagination);
}

View File

@ -1,7 +1,6 @@
package com.diboot.example.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.binding.manager.AnnotationBindingManager;
import com.diboot.core.entity.Dictionary;
import com.diboot.core.mapper.DictionaryMapper;
import com.diboot.core.service.impl.BaseServiceImpl;
@ -15,7 +14,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**

View File

@ -2,7 +2,7 @@ package com.diboot.example.service.impl;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.binding.manager.AnnotationBindingManager;
import com.diboot.core.binding.manager.RelationsBinder;
import com.diboot.core.service.impl.BaseServiceImpl;
import com.diboot.core.util.V;
import com.diboot.core.vo.Pagination;
@ -40,7 +40,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
@Override
public List<SysUserVO> getSysUserList(Wrapper queryWrapper, Pagination pagination) {
List<SysUser> sysUserList = super.getEntityList(queryWrapper, pagination);
List<SysUserVO> sysUserVOList = AnnotationBindingManager.autoConvertAndBind(sysUserList, SysUserVO.class);
List<SysUserVO> sysUserVOList = RelationsBinder.convertAndBind(sysUserList, SysUserVO.class);
if(V.notEmpty(sysUserVOList)){
for(SysUserVO sysUserVO : sysUserVOList){
List<Role> roleList = sysUserVO.getRoleList();

View File

@ -11,13 +11,13 @@ spring.server.MaxFileSize=10MB
spring.server.MaxRequestSize=50MB
#文件本地存放路径
files.storage.directory=C:/Users/wuweiqing/Downloads/upload/
files.storage.directory=
#七牛
qiniu.key.access=xJPWOwatadCt8ANWPaxrhj3Dj8DGIFoN9jD29SCP
qiniu.key.secret=IbWRTTXdOKoD8qdpug7Xm+rTXX2yhKuh8tfY6Ov4t1SDq/P1oT4cbREWnbgXofwt
qiniu.bucket.name=thirdparty
qiniu.image.domain=http://thirdparty.dibo.ltd/
#七牛配置
qiniu.key.access=xxx
qiniu.key.secret=xxx
qiniu.bucket.name=xxx
qiniu.image.domain=xxx
# spring config
spring.devtools.restart.enabled=true
@ -85,7 +85,7 @@ email.sender.host=smtp.163.com
#发送端口
email.sender.sslport=
#发送方称呼
email.sender.name=wangyl
email.sender.name=
#权限配置

View File

@ -1,11 +0,0 @@
package com.diboot.example.test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTest {
}

View File

@ -1,20 +0,0 @@
package com.diboot.example.test.sql;
import com.diboot.core.util.SqlExecutor;
import com.diboot.example.test.ApplicationTest;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class ExecuteSqlTest extends ApplicationTest {
@Test
public void testExecuteShowTableInfo() throws Exception{
String sql = "";
boolean success = SqlExecutor.executeUpdate(sql, null);
Assert.assertTrue(success);
}
}

View File

@ -1,17 +0,0 @@
package com.diboot.example.test.str;
import com.diboot.core.service.impl.BaseServiceImpl;
import org.junit.Test;
import org.springframework.stereotype.Component;
@Component
public class ConvertStrTest{
@Test
public void convert2Hump() throws Exception{
String str = "aaa_bbb_ccc_ddd_eee_fff";
BaseServiceImpl base = new BaseServiceImpl();
String a = base.convert2Hump(str);
System.out.println(a);
}
}

View File

@ -1,7 +1,6 @@
apply plugin: 'org.springframework.boot'
dependencies {
compile project(":diboot-core")
compile project(":diboot-shiro")
//

View File

@ -15,7 +15,6 @@ repositories {
dependencies {
compile project(":diboot-core")
compile project(":diboot-shiro")
//

View File

@ -0,0 +1,219 @@
package com.diboot.shiro.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.controller.BaseCrudRestController;
import com.diboot.core.service.BaseService;
import com.diboot.core.service.DictionaryService;
import com.diboot.core.util.V;
import com.diboot.core.vo.JsonResult;
import com.diboot.core.vo.KeyValue;
import com.diboot.core.vo.Pagination;
import com.diboot.core.vo.Status;
import com.diboot.shiro.entity.Permission;
import com.diboot.shiro.entity.Role;
import com.diboot.shiro.service.RoleService;
import com.diboot.shiro.vo.RoleVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@RestController
@RequestMapping("/role")
public class RoleController extends BaseCrudRestController {
@Autowired
private RoleService roleService;
@Autowired
private DictionaryService dictionaryService;
@Override
protected BaseService getService() {
return roleService;
}
/***
* 获取Entity列表分页
* @param request
* @return
* @throws Exception
*/
@GetMapping("/list")
public JsonResult getVOList(HttpServletRequest request) throws Exception{
QueryWrapper<Role> queryWrapper = buildQuery(request);
// 构建分页
Pagination pagination = buildPagination(request);
// 获取结果
List<RoleVO> voList = roleService.getRoleList(queryWrapper, pagination);
// 返回结果
return new JsonResult(Status.OK, voList).bindPagination(pagination);
}
/***
* 显示创建页面
* @return
* @throws Exception
*/
@GetMapping("/toCreatePage")
public JsonResult toCreatePage(HttpServletRequest request, ModelMap modelMap)
throws Exception{
List<Permission> menuList = roleService.getAllMenu();
modelMap.put("menuList", menuList);
return new JsonResult(modelMap);
}
/***
* 创建Entity
* @return
* @throws Exception
*/
@PostMapping("/")
public JsonResult createEntity(@RequestBody Role entity, BindingResult result, HttpServletRequest request, ModelMap modelMap)
throws Exception{
// 创建
boolean success = roleService.createRole(entity);
if(success){
return new JsonResult(Status.OK);
}else{
return new JsonResult(Status.FAIL_OPERATION);
}
}
/***
* 显示更新页面
* @return
* @throws Exception
*/
@GetMapping("/toUpdatePage/{id}")
public JsonResult toUpdatePage(@PathVariable("id")Long id, HttpServletRequest request, ModelMap modelMap)
throws Exception{
RoleVO roleVO = roleService.toUpdatePage(id);
return new JsonResult(roleVO);
}
/***
* 更新Entity
* @param id ID
* @return
* @throws Exception
*/
@PutMapping("/{id}")
public JsonResult updateModel(@PathVariable("id")Long id, @RequestBody Role entity, BindingResult result,
HttpServletRequest request, ModelMap modelMap) throws Exception{
// Model属性值验证结果
if(result.hasErrors()) {
return new JsonResult(Status.FAIL_INVALID_PARAM, super.getBindingError(result));
}
if(modelMap.get(ERROR) != null){
return new JsonResult(Status.FAIL_VALIDATION, (String) modelMap.get(ERROR));
}
entity.setId(id);
boolean success = roleService.updateRole(entity);
if(success){
return new JsonResult(Status.OK);
}else{
return new JsonResult(Status.FAIL_OPERATION);
}
}
/***
* 查询Entity
* @param id ID
* @return
* @throws Exception
*/
@GetMapping("/{id}")
public JsonResult getModel(@PathVariable("id")Long id, HttpServletRequest request, ModelMap modelMap)
throws Exception{
RoleVO roleVO = roleService.getRole(id);
return new JsonResult(roleVO);
}
/***
* 删除
* @param id
* @return
* @throws Exception
*/
@DeleteMapping("/{id}")
public JsonResult deleteModel(@PathVariable("id")Long id, HttpServletRequest request) throws Exception{
boolean success = roleService.deleteRole(id);
if(success){
return new JsonResult(Status.OK);
}else{
return new JsonResult(Status.FAIL_OPERATION );
}
}
/***
* 获取所有菜单,以及每个菜单下的所有权限
* @return
* @throws Exception
*/
@GetMapping("/getAllMenu")
public JsonResult getAllMenu(HttpServletRequest request, ModelMap modelMap)
throws Exception{
List<Permission> list = roleService.getAllMenu();
return new JsonResult(list);
}
/***
* 加载更多数据
* @return
* @throws Exception
*/
@GetMapping("/attachMore")
public JsonResult attachMore(HttpServletRequest request, ModelMap modelMap)
throws Exception{
//获取角色状态KV
List<KeyValue> roleStatusKvList = dictionaryService.getKeyValueList(Role.METATYPE_STATUS);
modelMap.put("roleStatusKvList", roleStatusKvList);
return new JsonResult(modelMap);
}
/*
* 校验角色code是否重复
* */
@GetMapping("/checkCodeRepeat")
public JsonResult checkCodeRepeat(Long id, String code, HttpServletRequest request){
if(V.notEmpty(code)){
QueryWrapper<Role> wrapper = new QueryWrapper();
wrapper.lambda().eq(Role::getCode, code);
List<Role> roleList = roleService.getEntityList(wrapper);
if(V.isEmpty(id)){//新建时
if(V.notEmpty(roleList)){
return new JsonResult(Status.FAIL_OPERATION, "code已存在");
}
}else{//更新时
Role role = roleService.getEntity(id);
if(V.notEmpty(role)){
if(V.notEmpty(roleList)){
if(roleList.size() >= 2){
return new JsonResult(Status.FAIL_OPERATION, "code已存在");
}else if(!(role.getId().equals(roleList.get(0).getId()))){
return new JsonResult(Status.FAIL_OPERATION, "code已存在");
}
}
}else{
if(V.notEmpty(roleList)){
return new JsonResult(Status.FAIL_OPERATION, "code已存在");
}
}
}
}
return new JsonResult(Status.OK);
}
}

View File

@ -4,6 +4,9 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.diboot.core.entity.BaseEntity;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* @author Yangzhao
* @version v2.0
@ -26,4 +29,12 @@ public class Permission extends BaseEntity {
@TableField
private String permissionName;
//某角色是否拥有该权限
@TableField(exist = false)
private boolean own = false;
//菜单下的各种权限资源
@TableField(exist = false)
private List<Permission> permissionList;
}

View File

@ -16,12 +16,21 @@ public class Role extends BaseEntity {
private static final long serialVersionUID = 5433209472424293571L;
// status字段的关联元数据
public static final String METATYPE_STATUS = "ROLE_STATUS";
@TableField
private String name;
@TableField
private String code;
@TableField
private String status;
@TableField
private String comment;
@TableField(exist = false)
private List<Permission> permissionList;

View File

@ -1,6 +1,9 @@
package com.diboot.shiro.service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.diboot.core.service.BaseService;
import com.diboot.core.vo.Pagination;
import com.diboot.shiro.entity.Permission;
import com.diboot.shiro.entity.Role;
import com.diboot.shiro.vo.RoleVO;
@ -14,6 +17,27 @@ import java.util.List;
*/
public interface RoleService extends BaseService<Role> {
//获取角色列表
List<RoleVO> getRoleList(Wrapper queryWrapper, Pagination pagination);
//获取角色信息
RoleVO getRole(Long id);
//新建角色信息
boolean createRole(Role role);
//显示更新页面
RoleVO toUpdatePage(Long id);
//修改角色信息
boolean updateRole(Role role);
//删除角色信息
boolean deleteRole(Long id);
//获取所有菜单
List<Permission> getAllMenu();
/***
* 根据用户类型和用户id获取角色关联权限列表
* @param userType

View File

@ -1,20 +1,31 @@
package com.diboot.shiro.service.impl;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.binding.manager.RelationsBinder;
import com.diboot.core.service.impl.BaseServiceImpl;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.V;
import com.diboot.core.vo.Pagination;
import com.diboot.shiro.entity.Permission;
import com.diboot.shiro.entity.Role;
import com.diboot.shiro.entity.RolePermission;
import com.diboot.shiro.entity.UserRole;
import com.diboot.shiro.mapper.RoleMapper;
import com.diboot.shiro.service.PermissionService;
import com.diboot.shiro.service.RolePermissionService;
import com.diboot.shiro.service.RoleService;
import com.diboot.shiro.service.UserRoleService;
import com.diboot.shiro.vo.PermissionVO;
import com.diboot.shiro.vo.RoleVO;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -26,9 +37,278 @@ import java.util.stream.Collectors;
@Service
@Slf4j
public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, Role> implements RoleService {
private static final Logger logger = LoggerFactory.getLogger(RoleServiceImpl.class);
@Autowired
private UserRoleService userRoleService;
@Autowired
private PermissionService permissionService;
@Autowired
private RolePermissionService rolePermissionService;
@Override
public List<RoleVO> getRoleList(Wrapper queryWrapper, Pagination pagination) {
List<Role> roleList = super.getEntityList(queryWrapper, pagination);
List<RoleVO> roleVOList = RelationsBinder.convertAndBind(roleList, RoleVO.class);
if(V.notEmpty(roleVOList)){
for(RoleVO roleVO : roleVOList){
List<Permission> permissionList = roleVO.getPermissionList();
if(V.notEmpty(permissionList)){
//获取这个角色拥有的菜单资源,并去重
List<Permission> menuList = new ArrayList();//菜单资源
HashSet menuSet = new HashSet();
Set<Long> idSet = new HashSet<>();//资源id set
for(Permission permission : permissionList){
//克隆roleVO.permissionList中的每一个permission解决查出来的列表页数据重复的问题
Permission temp = BeanUtils.convert(permission, Permission.class);
idSet.add(temp.getId());
if(menuSet.add(temp.getMenuCode())){
menuList.add(temp);
}
}
//获取菜单资源下的该角色已有的权限资源
if(V.notEmpty(menuList)){
for(Permission menu : menuList){
QueryWrapper<Permission> query = new QueryWrapper();
query.lambda().in(Permission::getId, idSet)
.eq(Permission::getMenuCode, menu.getMenuCode());
List<Permission> menuPermissionList = permissionService.getEntityList(query);
menu.setPermissionList(menuPermissionList);
}
}
roleVO.setMenuList(menuList);
}
}
}
return roleVOList;
}
@Override
public RoleVO getRole(Long id) {
RoleVO roleVO = super.getViewObject(id, RoleVO.class);
//角色已拥有的权限列表
List<Permission> ownPermissionList = roleVO.getPermissionList();
//角色已拥有的菜单资源
List<Permission> ownMenuList = null;
Set<Long> idSet = new HashSet<>();
if(V.notEmpty(ownPermissionList)){
//获取这个角色拥有的菜单资源
ownMenuList = new ArrayList();
HashSet set = new HashSet();
for(Permission permission : ownPermissionList){
idSet.add(permission.getId());
if(set.add(permission.getMenuCode())){
ownMenuList.add(permission);
}
}
}
//获取菜单资源下的该角色已有的权限资源
if(V.notEmpty(ownMenuList)){
for(Permission menu : ownMenuList){
QueryWrapper<Permission> query = new QueryWrapper();
query.lambda().in(Permission::getId, idSet)
.eq(Permission::getMenuCode, menu.getMenuCode());
List<Permission> menuPermissionList = permissionService.getEntityList(query);
menu.setPermissionList(menuPermissionList);
}
}
roleVO.setMenuList(ownMenuList);
return roleVO;
}
@Override
@Transactional
public boolean createRole(Role role) {
if(V.isEmpty(role)){
return false;
}
try{
//新建角色信息
boolean success = super.createEntity(role);
if(!success){
return false;
}
//新建角色权限信息
List<Permission> permissionList = role.getPermissionList();
if(V.notEmpty(permissionList)){
for(Permission p : permissionList){
RolePermission rolePermission = new RolePermission();
rolePermission.setRoleId(role.getId());
rolePermission.setPermissionId(p.getId());
rolePermissionService.createEntity(rolePermission);
}
}
}catch(Exception e){
throw new RuntimeException();
}
return true;
}
@Override
public RoleVO toUpdatePage(Long id) {
RoleVO roleVO = super.getViewObject(id, RoleVO.class);
//角色已拥有的权限列表
List<Permission> ownPermissionList = roleVO.getPermissionList();
//角色已拥有的菜单资源
List<Permission> ownMenuList = null;
if(V.notEmpty(ownPermissionList)){
//获取这个角色拥有的菜单资源
ownMenuList = new ArrayList();
HashSet set = new HashSet();
for(Permission permission : ownPermissionList){
if(set.add(permission.getMenuCode())){
ownMenuList.add(permission);
}
}
}
//获取所有菜单及菜单下的权限信息
List<Permission> allMenuList = getAllMenu();
if(V.notEmpty(allMenuList)){
for(Permission menu : allMenuList){
List<Permission> allPermissionList = menu.getPermissionList();
//判断该角色是否有该菜单资源若有设为true
if(V.notEmpty(ownMenuList)){
for(Permission m : ownMenuList){
if(menu.getMenuCode().equals(m.getMenuCode())){
menu.setOwn(true);
}
}
}
//判断该角色是否有该资源权限若有设为true
if(V.notEmpty(allPermissionList) && V.notEmpty(ownPermissionList)){
for(Permission permission : allPermissionList){
for(Permission p : ownPermissionList){
if(permission.getId().equals(p.getId())){
permission.setOwn(true);
}
}
}
}
}
}
roleVO.setMenuList(allMenuList);
return roleVO;
}
@Override
@Transactional
public boolean updateRole(Role role) {
if(V.isEmpty(role)){
return false;
}
try {
//更新角色信息
boolean success = super.updateEntity(role);
if(!success){
return false;
}
//获取角色原来拥有的权限信息
QueryWrapper<RolePermission> query = new QueryWrapper();
query.lambda().eq(RolePermission::getRoleId, role.getId());
List<RolePermission> oldPermissionList = rolePermissionService.getEntityList(query);
List<Permission> newPermissionList = role.getPermissionList();
StringBuffer oldBuffer = new StringBuffer();
StringBuffer newBuffer = new StringBuffer();
if(V.notEmpty(oldPermissionList)){
for(RolePermission rp : oldPermissionList){
oldBuffer.append(rp.getPermissionId()).append(",");
}
}
if(V.notEmpty(newPermissionList)){
for(Permission p : newPermissionList){
newBuffer.append(p.getId()).append(",");
}
}
//删除页面取消选择的角色权限
if(V.notEmpty(oldPermissionList)){
for(RolePermission rp : oldPermissionList){
if(!(newBuffer.toString().contains(rp.getPermissionId().toString()))){
rolePermissionService.deleteEntity(rp.getId());
}
}
}
//新增页面选择的角色权限
if(V.notEmpty(newPermissionList)){
for(Permission p : newPermissionList){
if(!(oldBuffer.toString().contains(p.getId().toString()))){
RolePermission entity = new RolePermission();
entity.setRoleId(role.getId());
entity.setPermissionId(p.getId());
rolePermissionService.createEntity(entity);
}
}
}
} catch (Exception e) {
throw new RuntimeException();
}
return true;
}
@Override
@Transactional
public boolean deleteRole(Long id) {
try {
boolean success = super.deleteEntity(id);
if(!success){
return false;
}
//获取角色原来拥有的权限信息
QueryWrapper<RolePermission> query = new QueryWrapper();
query.lambda().eq(RolePermission::getRoleId, id);
List<RolePermission> rolePermissionList = rolePermissionService.getEntityList(query);
//删除角色权限
if(V.notEmpty(rolePermissionList)){
for(RolePermission rp : rolePermissionList){
rolePermissionService.deleteEntity(rp.getId());
}
}
} catch (Exception e) {
throw new RuntimeException();
}
return true;
}
@Override
public List<Permission> getAllMenu() {
//获取所有菜单
Wrapper wrapper = new QueryWrapper<Permission>()
.lambda()
.groupBy(Permission::getMenuCode)
.select()
;
List<Permission> menuList = permissionService.getEntityList(wrapper);
if(V.notEmpty(menuList)){
for(Permission menu : menuList){
//获取一个菜单的所有权限资源
QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(Permission::getMenuCode, menu.getMenuCode());
List<Permission> allPermissionList = permissionService.getEntityList(queryWrapper);
menu.setPermissionList(allPermissionList);
}
}
return menuList;
}
@Override
public List<RoleVO> getRelatedRoleAndPermissionListByUser(String userType, Long userId) {

View File

@ -1,5 +1,7 @@
package com.diboot.shiro.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.diboot.core.binding.annotation.BindDict;
import com.diboot.core.binding.annotation.BindEntityList;
import com.diboot.shiro.entity.Permission;
import com.diboot.shiro.entity.Role;
@ -17,8 +19,14 @@ public class RoleVO extends Role {
private static final long serialVersionUID = 860775286174387052L;
@BindDict(type="ROLE_STATUS", field="status")
private String statusLabel;
/**支持通过中间表的多-多Entity实体关联*/
@BindEntityList(entity = Permission.class, condition="this.id=role_permission.role_id AND role_permission.permission_id=id")
@BindEntityList(entity = Permission.class, condition="this.id=role_permission.role_id AND role_permission.permission_id=id AND role_permission.deleted=0")
private List<Permission> permissionList;
@TableField(exist = false)
private List<Permission> menuList;
}