diff --git a/diboot-core/src/main/java/com/diboot/core/binding/EntityBinder.java b/diboot-core/src/main/java/com/diboot/core/binding/EntityBinder.java index e566799..125f291 100644 --- a/diboot-core/src/main/java/com/diboot/core/binding/EntityBinder.java +++ b/diboot-core/src/main/java/com/diboot/core/binding/EntityBinder.java @@ -64,30 +64,37 @@ public class EntityBinder extends BaseBinder { return; } if(referencedEntityPrimaryKey == null){ - log.warn("调用错误:必须调用joinOn()方法连接两个字段."); + log.warn("调用错误:无法从condition中解析出字段关联."); } - // 提取主键pk列表 + // 提取注解条件中指定的对应的列表 String annoObjectForeignKeyField = S.toLowerCaseCamel(annoObjectForeignKey); List annoObjectForeignKeyList = BeanUtils.collectToList(annoObjectList, annoObjectForeignKeyField); if(V.isEmpty(annoObjectForeignKeyList)){ return; } - // 解析中间表查询关联 + // 通过中间表关联Entity + // @BindEntity(entity = Organization.class, condition = "this.department_id=department.id AND department.org_id=id AND department.deleted=0") + // Organization organization; if(middleTable != null){ + // 提取中间表查询SQL String sql = middleTable.toSQL(annoObjectForeignKeyList); // 执行查询并合并结果 String keyName = middleTable.getEqualsToRefEntityPkColumn(), valueName = middleTable.getEqualsToAnnoObjectFKColumn(); - Map middleTableResultMap = SqlExecutor.executeQueryAndMergeResult(sql, annoObjectForeignKeyList, keyName, valueName); + Map middleTableResultMap = SqlExecutor.executeQueryAndMergeResult(sql, annoObjectForeignKeyList, keyName, valueName); if(V.notEmpty(middleTableResultMap)){ + // 提取entity主键值集合 Collection middleTableColumnValueList = middleTableResultMap.keySet(); // 构建查询条件 queryWrapper.in(S.toSnakeCase(referencedEntityPrimaryKey), middleTableColumnValueList); // 查询entity列表 List list = referencedService.getEntityList(queryWrapper); - // 绑定结果 - bindingResult(S.toLowerCaseCamel(referencedEntityPrimaryKey), list, middleTableResultMap); + // 基于中间表查询结果和entity列表绑定结果 + bindingResultWithMiddleTable(S.toLowerCaseCamel(referencedEntityPrimaryKey), list, middleTableResultMap); } } + // 直接关联Entity + // @BindEntity(entity = Department.class, condition="department_id=id") + // Department department; else{ // 构建查询条件 queryWrapper.in(S.toSnakeCase(referencedEntityPrimaryKey), annoObjectForeignKeyList); @@ -99,20 +106,23 @@ public class EntityBinder extends BaseBinder { } /*** - * 绑定结果 + * 基于中间表查询结果和entity列表绑定结果 * @param doPkPropName * @param list */ - protected void bindingResult(String doPkPropName, List list, Map middleTableResultMap) { - Map valueEntityMap = new HashMap<>(list.size()); - for(T entity : list){ - Object pkValue = BeanUtils.getProperty(entity, doPkPropName); - Object annoObjFK = middleTableResultMap.get(pkValue); - if(annoObjFK != null){ - valueEntityMap.put(String.valueOf(annoObjFK), entity); + private void bindingResultWithMiddleTable(String doPkPropName, List list, Map middleTableResultMap) { + // 构建IdString-Entity之间的映射Map + Map valueEntityMap = new HashMap<>(list.size()); + for(E entity : list){ + // 获取主键值 + String pkValue = BeanUtils.getStringProperty(entity, doPkPropName); + // 得到对应Entity + List annoObjFKList = middleTableResultMap.get(pkValue); + if(V.notEmpty(annoObjFKList)){ + valueEntityMap.put(String.valueOf(annoObjFKList.get(0)), entity); } else{ - log.warn("转换结果异常,中间关联条件数据不一致"); + log.warn("{}.{}={} 无匹配结果!", entity.getClass().getSimpleName(), doPkPropName, pkValue); } } // 绑定 @@ -124,11 +134,11 @@ public class EntityBinder extends BaseBinder { * @param doPkPropName * @param list */ - protected void bindingResult(String doPkPropName, List list) { - Map valueEntityMap = new HashMap<>(list.size()); + private void bindingResult(String doPkPropName, List list) { + Map valueEntityMap = new HashMap<>(list.size()); for(T entity : list){ - Object pkValue = BeanUtils.getProperty(entity, doPkPropName); - valueEntityMap.put(String.valueOf(pkValue), entity); + String pkValue = BeanUtils.getStringProperty(entity, doPkPropName); + valueEntityMap.put(pkValue, entity); } // 绑定 BeanUtils.bindPropValueOfList(annoObjectField, annoObjectList, annoObjectForeignKey, valueEntityMap); diff --git a/diboot-core/src/main/java/com/diboot/core/binding/EntityListBinder.java b/diboot-core/src/main/java/com/diboot/core/binding/EntityListBinder.java index dea649b..d485bb5 100644 --- a/diboot-core/src/main/java/com/diboot/core/binding/EntityListBinder.java +++ b/diboot-core/src/main/java/com/diboot/core/binding/EntityListBinder.java @@ -3,15 +3,16 @@ package com.diboot.core.binding; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.diboot.core.service.BaseService; import com.diboot.core.util.BeanUtils; +import com.diboot.core.util.S; +import com.diboot.core.util.SqlExecutor; +import com.diboot.core.util.V; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** + * Entity集合绑定实现 * @author Mazhicheng * @version v2.0 * @date 2019/1/19 @@ -31,7 +32,92 @@ public class EntityListBinder extends EntityBinder { } @Override - protected void bindingResult(String fkName, List list) { + public void bind() { + if(V.isEmpty(annoObjectList)){ + return; + } + if(referencedEntityPrimaryKey == null){ + log.warn("调用错误:无法从condition中解析出字段关联."); + } + // 提取主键pk列表 + String annoObjectForeignKeyField = S.toLowerCaseCamel(annoObjectForeignKey); + List annoObjectForeignKeyList = BeanUtils.collectToList(annoObjectList, annoObjectForeignKeyField); + if(V.isEmpty(annoObjectForeignKeyList)){ + return; + } + // 解析中间表查询 1-N关联,如: + //User.class @BindEntityList(entity = Role.class, condition="this.id=user_role.user_id AND user_role.role_id=id") + if(middleTable != null){ + // 构建查询SQL: SELECT user_id, role_id FROM user_role WHERE user_id IN (?) + String sql = middleTable.toSQL(annoObjectForeignKeyList); + // 执行查询并合并结果 + String valueName = middleTable.getEqualsToRefEntityPkColumn(), keyName = middleTable.getEqualsToAnnoObjectFKColumn(); + Map middleTableResultMap = SqlExecutor.executeQueryAndMergeResult(sql, annoObjectForeignKeyList, keyName, valueName); + if(V.notEmpty(middleTableResultMap)){ + // 收集查询结果values集合 + List entityIdList = new ArrayList(); + for(Map.Entry entry : middleTableResultMap.entrySet()){ + if(V.notEmpty(entry.getValue())){ + for(Object id : entry.getValue()){ + if(!entityIdList.contains(id)){ + entityIdList.add(id); + } + } + } + } + // 构建查询条件 + queryWrapper.in(S.toSnakeCase(referencedEntityPrimaryKey), entityIdList); + // 查询entity列表: List + List list = referencedService.getEntityList(queryWrapper); + // 绑定结果 + bindingResultWithMiddleTable(S.toLowerCaseCamel(annoObjectForeignKey), list, middleTableResultMap); + } + } + else{ + // 构建查询条件 + queryWrapper.in(S.toSnakeCase(referencedEntityPrimaryKey), annoObjectForeignKeyList); + // 查询entity列表 + List list = referencedService.getEntityList(queryWrapper); + // 绑定结果 + bindingResult(S.toLowerCaseCamel(referencedEntityPrimaryKey), list); + } + } + + /*** + * 基于中间表查询结果和entity列表绑定结果 + * @param annoObjectForeignKey + * @param list + */ + private void bindingResultWithMiddleTable(String annoObjectForeignKey, List list, Map middleTableResultMap) { + if(V.isEmpty(list)){ + return; + } + // 将 List 转换为 Map + Map entityMap = BeanUtils.convertToStringKeyObjectMap(list, annoObjectForeignKey); + // 将Map> 转换为 Map> + Map> valueEntityMap = new HashMap<>(list.size()); + for(Map.Entry entry : middleTableResultMap.entrySet()){ + // List + List annoObjFKList = entry.getValue(); + if(V.notEmpty(annoObjFKList)){ + List valueList = new ArrayList(); + for(Object obj : annoObjFKList){ + E ent = entityMap.get(String.valueOf(obj)); + if(ent != null){ + valueList.add(ent); + } + } + valueEntityMap.put(entry.getKey(), valueList); + } + else{ + log.warn("转换结果异常,中间关联条件数据不一致"); + } + } + // 绑定 + BeanUtils.bindPropValueOfList(annoObjectField, annoObjectList, annoObjectForeignKey, valueEntityMap); + } + + private void bindingResult(String fkName, List list) { Map> valueEntityListMap = new HashMap<>(list.size()); for(T entity : list){ Object keyValue = BeanUtils.getProperty(entity, fkName); diff --git a/diboot-core/src/main/java/com/diboot/core/binding/parser/MiddleTable.java b/diboot-core/src/main/java/com/diboot/core/binding/parser/MiddleTable.java index a5bcb71..854c80b 100644 --- a/diboot-core/src/main/java/com/diboot/core/binding/parser/MiddleTable.java +++ b/diboot-core/src/main/java/com/diboot/core/binding/parser/MiddleTable.java @@ -77,13 +77,6 @@ public class MiddleTable { if(V.isEmpty(annoObjectForeignKeyList)){ return null; } - Object object = annoObjectForeignKeyList.get(0); - // 不需要加引号的类型 - boolean noQuotes = object instanceof Integer - || object instanceof Long - || object instanceof Double - || object instanceof Float - || object instanceof BigDecimal; // 构建SQL StringBuilder sb = new StringBuilder(); sb.append("SELECT ").append(this.equalsToAnnoObjectFKColumn).append(Cons.SEPARATOR_COMMA) diff --git a/diboot-core/src/main/java/com/diboot/core/service/impl/BaseServiceImpl.java b/diboot-core/src/main/java/com/diboot/core/service/impl/BaseServiceImpl.java index 0afd563..b503e88 100644 --- a/diboot-core/src/main/java/com/diboot/core/service/impl/BaseServiceImpl.java +++ b/diboot-core/src/main/java/com/diboot/core/service/impl/BaseServiceImpl.java @@ -183,8 +183,8 @@ public class BaseServiceImpl, T> extends ServiceImpl @Override public List getKeyValueList(Wrapper queryWrapper) { String sqlSelect = queryWrapper.getSqlSelect(); - if(V.isEmpty(sqlSelect) || S.countMatches(sqlSelect, Cons.SEPARATOR_COMMA) != 1){ - log.error("调用错误: getKeyValueList必须用select依次指定返回的键值字段,如: new QueryWrapper().lambda().select(Metadata::getItemName, Metadata::getItemValue)"); + if(V.isEmpty(sqlSelect) || S.countMatches(sqlSelect, Cons.SEPARATOR_COMMA) > 2){ + log.error("调用错误: getKeyValueList必须用select依次指定返回的Key,Value, ext键值字段,如: new QueryWrapper().lambda().select(Metadata::getItemName, Metadata::getItemValue)"); return Collections.emptyList(); } // 获取mapList @@ -198,6 +198,9 @@ public class BaseServiceImpl, T> extends ServiceImpl for(Map map : mapList){ if(map.get(keyValueArray[0]) != null){ KeyValue kv = new KeyValue((String)map.get(keyValueArray[0]), map.get(keyValueArray[1])); + if(keyValueArray.length > 2){ + kv.setExt(map.get(keyValueArray[2])); + } keyValueList.add(kv); } } diff --git a/diboot-core/src/main/java/com/diboot/core/util/BeanUtils.java b/diboot-core/src/main/java/com/diboot/core/util/BeanUtils.java index 43d05f0..d54b157 100644 --- a/diboot-core/src/main/java/com/diboot/core/util/BeanUtils.java +++ b/diboot-core/src/main/java/com/diboot/core/util/BeanUtils.java @@ -196,6 +196,20 @@ public class BeanUtils { return wrapper.getPropertyValue(field); } + /*** + * 获取对象的属性值并转换为String + * @param obj + * @param field + * @return + */ + public static String getStringProperty(Object obj, String field){ + Object property = getProperty(obj, field); + if(property == null){ + return null; + } + return String.valueOf(property); + } + /*** * 设置属性值 * @param obj @@ -212,22 +226,22 @@ public class BeanUtils { * @param allLists * @return */ - public static Map convert2KeyObjectMap(List allLists, String... fields){ + public static Map convertToStringKeyObjectMap(List allLists, String... fields){ if(allLists == null || allLists.isEmpty()){ return null; } - Map allListMap = new LinkedHashMap<>(allLists.size()); + Map allListMap = new LinkedHashMap<>(allLists.size()); // 转换为map try{ for(T model : allLists){ - Object key = null; + String key = null; if(V.isEmpty(fields)){ //未指定字段,以id为key - key = getProperty(model, Cons.FieldName.parentId.name());; + key = getStringProperty(model, Cons.FieldName.parentId.name()); } // 指定了一个字段,以该字段为key,类型同该字段 else if(fields.length == 1){ - key = getProperty(model, fields[0]); + key = getStringProperty(model, fields[0]); } else{ // 指定了多个字段,以字段S.join的结果为key,类型为String List list = new ArrayList(); @@ -240,7 +254,7 @@ public class BeanUtils { allListMap.put(key, model); } else{ - log.warn(model.getClass().getName() + " 的属性 "+fields[0]+" 值存在 null,BeanUtils.convert2KeyModelMap转换结果需要确认!"); + log.warn(model.getClass().getName() + " 的属性 "+fields[0]+" 值存在 null,转换结果需要确认!"); } } } @@ -285,10 +299,10 @@ public class BeanUtils { */ private static void buildDeeperLevelTree(List parentModels, List allModels){ List deeperLevelModels = new ArrayList(); - Map parentLevelModelMap = convert2KeyObjectMap(parentModels); + Map parentLevelModelMap = convertToStringKeyObjectMap(parentModels); for(T model : allModels){ Object parentId = getProperty(model, Cons.FieldName.parentId.name()); - if(parentLevelModelMap.keySet().contains(parentId) && !parentId.equals(model.getId())){ + if(parentLevelModelMap.keySet().contains(String.valueOf(parentId)) && !parentId.equals(model.getId())){ deeperLevelModels.add(model); } } @@ -297,7 +311,7 @@ public class BeanUtils { } for(T model : deeperLevelModels){ Object parentId = getProperty(model, Cons.FieldName.parentId.name()); - T parentModel = parentLevelModelMap.get(parentId); + T parentModel = parentLevelModelMap.get(String.valueOf(parentId)); if(parentModel!=null){ List children = (List) getProperty(parentModel, Cons.FieldName.children.name()); if(children == null){ @@ -454,9 +468,9 @@ public class BeanUtils { try{ for(E object : fromList){ // 获取到当前的属性值 - Object fieldValue = getProperty(object, getterFieldName); + String fieldValue = getStringProperty(object, getterFieldName); // 获取到当前的value - Object value = valueMatchMap.get(String.valueOf(fieldValue)); + Object value = valueMatchMap.get(fieldValue); // 赋值 setProperty(object, setterFieldName, value); } diff --git a/diboot-core/src/main/java/com/diboot/core/util/SqlExecutor.java b/diboot-core/src/main/java/com/diboot/core/util/SqlExecutor.java index 61f518a..c8992bc 100644 --- a/diboot-core/src/main/java/com/diboot/core/util/SqlExecutor.java +++ b/diboot-core/src/main/java/com/diboot/core/util/SqlExecutor.java @@ -6,10 +6,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.sql.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * 原生SQL执行类 @@ -21,11 +18,12 @@ public class SqlExecutor { private static final Logger log = LoggerFactory.getLogger(SqlExecutor.class); /*** - * 执行Select语句 + * 执行Select语句,如: SELECT user_id,role_id FROM user_role WHERE user_id IN (?,?,?,?) + * 查询结果如: [{"user_id":1001,"role_id":101},{"user_id":1001,"role_id":102},{"user_id":1003,"role_id":102},{"user_id":1003,"role_id":103}] * @param sql * @return */ - public static List> executeQuery(String sql, List params) throws Exception{ + public static List> executeQuery(String sql, List params) throws Exception{ if(V.isEmpty(sql)){ return null; } @@ -36,8 +34,10 @@ public class SqlExecutor { return null; } // 替换单个?参数为多个,用于拼接IN参数 - if(sql.contains("?") && V.notEmpty(params)){ - sql = S.replace(sql, "?", S.repeat("?", ",", params.size())); + if(V.notEmpty(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)){ @@ -48,13 +48,13 @@ public class SqlExecutor { } ResultSet rs = stmt.executeQuery(); ResultSetMetaData meta = rs.getMetaData(); - List> mapList = new ArrayList<>(); + List> mapList = new ArrayList<>(); if(meta.getColumnCount() > 0){ // 添加数据行 while(rs.next()){ - Map dataRow = new HashMap<>(); + Map dataRow = new HashMap<>(); for(int i=1; i<=meta.getColumnCount(); i++){ - dataRow.put(meta.getColumnLabel(i), rs.getObject(i)); + dataRow.put(meta.getColumnLabel(i), (E)rs.getObject(i)); } mapList.add(dataRow); } @@ -69,14 +69,16 @@ public class SqlExecutor { } } + /** - * 执行查询和合并结果 + * 执行查询和合并结果并将结果Map的key类型转成String + * * @param sql * @param params * @return */ - public static Map executeQueryAndMergeResult(String sql, List params, String keyName, String valueName){ - List> resultSetMapList = null; + public static Map executeQueryAndMergeResult(String sql, List params, String keyName, String valueName){ + List> resultSetMapList = null; try { resultSetMapList = executeQuery(sql, params); } @@ -84,10 +86,16 @@ public class SqlExecutor { log.warn("执行查询异常", e); } // 合并list为map - Map resultMap = new HashMap<>(); + Map resultMap = new HashMap<>(); if(V.notEmpty(resultSetMapList)){ - for(Map row : resultSetMapList){ - resultMap.put(row.get(keyName), row.get(valueName)); + for(Map row : resultSetMapList){ + String key = String.valueOf(row.get(keyName)); + List valueList = resultMap.get(key); + if(valueList == null){ + valueList = new ArrayList(); + resultMap.put(key, valueList); + } + valueList.add(row.get(valueName)); } } return resultMap; diff --git a/diboot-core/src/main/java/com/diboot/core/vo/JsonResult.java b/diboot-core/src/main/java/com/diboot/core/vo/JsonResult.java index 1ec0c6b..49535ab 100644 --- a/diboot-core/src/main/java/com/diboot/core/vo/JsonResult.java +++ b/diboot-core/src/main/java/com/diboot/core/vo/JsonResult.java @@ -30,9 +30,6 @@ public class JsonResult implements Serializable { * 默认成功,无返回数据 */ public JsonResult(){ - this.code = Status.OK.code(); - this.msg = Status.OK.label(); - this.data = null; } /** diff --git a/diboot-core/src/main/java/com/diboot/core/vo/KeyValue.java b/diboot-core/src/main/java/com/diboot/core/vo/KeyValue.java index 09a9f67..766afba 100644 --- a/diboot-core/src/main/java/com/diboot/core/vo/KeyValue.java +++ b/diboot-core/src/main/java/com/diboot/core/vo/KeyValue.java @@ -28,6 +28,11 @@ public class KeyValue implements Serializable { */ private Object v; + /** + * 扩展值 + */ + private Object ext; + public String getK() { return k; } @@ -43,4 +48,12 @@ public class KeyValue implements Serializable { public void setV(Object v) { this.v = v; } + + public Object getExt() { + return ext; + } + + public void setExt(Object ext) { + this.ext = ext; + } } diff --git a/diboot-example/src/main/java/com/diboot/example/controller/DepartmentController.java b/diboot-example/src/main/java/com/diboot/example/controller/DepartmentController.java index b80b41c..71d4cb3 100644 --- a/diboot-example/src/main/java/com/diboot/example/controller/DepartmentController.java +++ b/diboot-example/src/main/java/com/diboot/example/controller/DepartmentController.java @@ -68,7 +68,7 @@ public class DepartmentController extends BaseCrudRestController { @GetMapping("/kv") public JsonResult getKVPairList(HttpServletRequest request){ Wrapper wrapper = new QueryWrapper().lambda() - .select(Department::getName, Department::getId); + .select(Department::getName, Department::getId, Department::getCode); List list = departmentService.getKeyValueList(wrapper); return new JsonResult(list); } diff --git a/diboot-example/src/main/java/com/diboot/example/controller/EmployeeController.java b/diboot-example/src/main/java/com/diboot/example/controller/EmployeeController.java deleted file mode 100644 index 1ac4209..0000000 --- a/diboot-example/src/main/java/com/diboot/example/controller/EmployeeController.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.diboot.example.controller; - -import com.baomidou.mybatisplus.core.conditions.Wrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.diboot.core.controller.BaseCrudRestController; -import com.diboot.core.service.BaseService; -import com.diboot.core.util.BeanUtils; -import com.diboot.core.util.JSON; -import com.diboot.core.vo.JsonResult; -import com.diboot.core.vo.KeyValue; -import com.diboot.core.vo.Status; -import com.diboot.example.entity.Department; -import com.diboot.example.entity.Employee; -import com.diboot.example.entity.Organization; -import com.diboot.example.service.EmployeeService; -import com.diboot.example.vo.DepartmentVO; -import com.diboot.example.vo.EmployeeVO; -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.ArrayList; -import java.util.List; - -/** - * Organization相关Controller - * @author Mazhicheng - * @version 2018/12/23 - * Copyright © www.dibo.ltd - */ -@RestController -@RequestMapping("/employee") -public class EmployeeController extends BaseCrudRestController { - - @Autowired - private EmployeeService employeeService; - - @GetMapping("/test") - public JsonResult test(HttpServletRequest request) throws Exception{ -// List userIdList = new ArrayList<>(); -// userIdList.add(1001L); -// userIdList.add(1003L); -// String sql = "SELECT user_id, role_id FROM user_role WHERE user_id IN (?)"; -// List> list = SqlExecutor.executeQuery(sql, userIdList); - - - List userIdList = new ArrayList<>(); - userIdList.add(1L); - QueryWrapper queryWrapper = new QueryWrapper(); - - //IN条件一定不能为空,否则就会删除整张表数据 - queryWrapper.in("id", userIdList); - System.out.println(JSON.stringify(queryWrapper)); - employeeService.deleteEntities(queryWrapper) - ; - userIdList.clear(); - queryWrapper = new QueryWrapper(); - queryWrapper.in("id", userIdList); - employeeService.deleteEntities(queryWrapper); - - return new JsonResult(); - } - - /*** - * 默认的分页实现 - *

- * url参数示例: /list?_pageSize=20&_pageIndex=1&_orderBy=itemValue&type=GENDAR - *

- * @return - * @throws Exception - */ - @GetMapping("/list") - public JsonResult getDefaultVOList(HttpServletRequest request) throws Exception{ - QueryWrapper queryWrapper = buildQuery(request); - return super.getEntityListWithPaging(request, queryWrapper, DepartmentVO.class); - } - - /*** - * 默认的分页实现 - *

- * url参数示例: /listVo?page.size=20&page.index=1&page.orderBy=itemValue&type=GENDAR - *

- * @return - * @throws Exception - */ - @GetMapping("/listVo") - public JsonResult getCustomVOList(HttpServletRequest request) throws Exception{ - QueryWrapper queryWrapper = buildQuery(request); - // 查询当前页的数据 - List entityList = employeeService.getEntityList(queryWrapper); - List voList = employeeService.getViewObjectList(entityList, EmployeeVO.class); - // 返回结果 - return new JsonResult(Status.OK, voList); - } - - @GetMapping("/kv") - public JsonResult getKVPairList(HttpServletRequest request){ - Wrapper wrapper = new QueryWrapper().lambda() - .select(Employee::getRealname, Employee::getId); - List list = employeeService.getKeyValueList(wrapper); - return new JsonResult(list); - } - - /*** - * 创建Entity - * @return - * @throws Exception - */ - @PostMapping("/") - public JsonResult createEntity(@ModelAttribute EmployeeVO viewObject, BindingResult result, HttpServletRequest request, ModelMap modelMap) - throws Exception{ - // 转换 - Employee entity = BeanUtils.convert(viewObject, Employee.class); - // 创建 - return super.createEntity(entity, result, modelMap); - } - - /*** - * 查询Entity - * @param id ID - * @return - * @throws Exception - */ - @GetMapping("/{id}") - public JsonResult getModel(@PathVariable("id")Long id, HttpServletRequest request, ModelMap modelMap) - throws Exception{ - EmployeeVO vo = employeeService.getViewObject(id, EmployeeVO.class); - return new JsonResult(vo); - } - - /*** - * 更新Entity - * @param id ID - * @return - * @throws Exception - */ - @PutMapping("/{id}") - public JsonResult updateModel(@PathVariable("id")Long id, @ModelAttribute Organization entity, BindingResult result, - HttpServletRequest request, ModelMap modelMap) throws Exception{ - return super.updateEntity(entity, result, modelMap); - } - - /*** - * 删除用户 - * @param id 用户ID - * @return - * @throws Exception - */ - @DeleteMapping("/{id}") - public JsonResult deleteModel(@PathVariable("id")Long id, HttpServletRequest request) throws Exception{ - return super.deleteEntity(id); - } - - @Override - protected BaseService getService() { - return employeeService; - } - -} diff --git a/diboot-example/src/main/java/com/diboot/example/controller/OrganizationController.java b/diboot-example/src/main/java/com/diboot/example/controller/OrganizationController.java deleted file mode 100644 index 0d09653..0000000 --- a/diboot-example/src/main/java/com/diboot/example/controller/OrganizationController.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.diboot.example.controller; - -import com.baomidou.mybatisplus.core.conditions.Wrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.diboot.core.controller.BaseCrudRestController; -import com.diboot.core.service.BaseService; -import com.diboot.core.util.BeanUtils; -import com.diboot.core.vo.JsonResult; -import com.diboot.core.vo.KeyValue; -import com.diboot.core.vo.Status; -import com.diboot.example.entity.Organization; -import com.diboot.example.service.OrganizationService; -import com.diboot.example.vo.OrganizationVO; -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; - -/** - * Organization相关Controller - * @author Mazhicheng - * @version 2018/12/23 - * Copyright © www.dibo.ltd - */ -@RestController -@RequestMapping("/organization") -public class OrganizationController extends BaseCrudRestController { - - @Autowired - private OrganizationService organizationService; - - /*** - * 默认的分页实现 - *

- * url参数示例: /list?_pageSize=20&_pageIndex=1&_orderBy=itemValue&type=GENDAR - *

- * @return - * @throws Exception - */ - @GetMapping("/list") - public JsonResult getDefaultVOList(HttpServletRequest request) throws Exception{ - QueryWrapper queryWrapper = buildQuery(request); - return super.getEntityListWithPaging(request, queryWrapper, OrganizationVO.class); - } - - /*** - * 默认的分页实现 - *

- * url参数示例: /listVo?page.size=20&page.index=1&page.orderBy=itemValue&type=GENDAR - *

- * @return - * @throws Exception - */ - @GetMapping("/listVo") - public JsonResult getCustomVOList(HttpServletRequest request) throws Exception{ - QueryWrapper queryWrapper = buildQuery(request); - // 查询当前页的数据 - List entityList = organizationService.getEntityList(queryWrapper); - List voList = organizationService.getViewObjectList(entityList, OrganizationVO.class); - // 返回结果 - return new JsonResult(Status.OK, voList); - } - - @GetMapping("/kv") - public JsonResult getKVPairList(HttpServletRequest request){ - Wrapper wrapper = new QueryWrapper().lambda() - .select(Organization::getName, Organization::getId); - List list = organizationService.getKeyValueList(wrapper); - return new JsonResult(list); - } - - /*** - * 创建Entity - * @return - * @throws Exception - */ - @PostMapping("/") - public JsonResult createEntity(@ModelAttribute OrganizationVO viewObject, BindingResult result, HttpServletRequest request, ModelMap modelMap) - throws Exception{ - // 转换 - Organization entity = BeanUtils.convert(viewObject, Organization.class); - // 创建 - return super.createEntity(entity, result, modelMap); - } - - /*** - * 查询Entity - * @param id ID - * @return - * @throws Exception - */ - @GetMapping("/{id}") - public JsonResult getModel(@PathVariable("id")Long id, HttpServletRequest request, ModelMap modelMap) - throws Exception{ - OrganizationVO vo = organizationService.getViewObject(id, OrganizationVO.class); - return new JsonResult(vo); - } - - /*** - * 更新Entity - * @param id ID - * @return - * @throws Exception - */ - @PutMapping("/{id}") - public JsonResult updateModel(@PathVariable("id")Long id, @ModelAttribute Organization entity, BindingResult result, - HttpServletRequest request, ModelMap modelMap) throws Exception{ - return super.updateEntity(entity, result, modelMap); - } - - /*** - * 删除用户 - * @param id 用户ID - * @return - * @throws Exception - */ - @DeleteMapping("/{id}") - public JsonResult deleteModel(@PathVariable("id")Long id, HttpServletRequest request) throws Exception{ - return super.deleteEntity(id); - } - - @Override - protected BaseService getService() { - return organizationService; - } - -} diff --git a/diboot-example/src/main/java/com/diboot/example/entity/Employee.java b/diboot-example/src/main/java/com/diboot/example/entity/Employee.java deleted file mode 100644 index 4291ca6..0000000 --- a/diboot-example/src/main/java/com/diboot/example/entity/Employee.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.diboot.example.entity; - -import com.baomidou.mybatisplus.annotation.TableField; -import com.diboot.core.entity.BaseEntity; -import lombok.Data; - -import java.util.Date; - -/** - * 员工Entity - * @author Mazhicheng - * @version v2.0 - * @date 2019/1/30 - */ -@Data -public class Employee extends BaseEntity { - private static final long serialVersionUID = 8980226078305249367L; - - @TableField - private Long departmentId; - - @TableField - private String realname; - - @TableField - private Date birthdate; - - @TableField - private String gender; - - @TableField - private String status; - -} diff --git a/diboot-example/src/main/java/com/diboot/example/entity/Role.java b/diboot-example/src/main/java/com/diboot/example/entity/Role.java index 7d5d8b6..c15a94c 100644 --- a/diboot-example/src/main/java/com/diboot/example/entity/Role.java +++ b/diboot-example/src/main/java/com/diboot/example/entity/Role.java @@ -1,12 +1,17 @@ package com.diboot.example.entity; +import com.alibaba.fastjson.annotation.JSONField; import com.diboot.core.entity.BaseEntity; +import lombok.Data; + +import java.util.Date; /** * @author Mazhicheng * @version v2.0 * @date 2019/1/30 */ +@Data public class Role extends BaseEntity { private static final long serialVersionUID = 3701095453152116088L; @@ -14,4 +19,6 @@ public class Role extends BaseEntity { private String code; + @JSONField(serialize = false) + public Date createTime; } diff --git a/diboot-example/src/main/java/com/diboot/example/entity/User.java b/diboot-example/src/main/java/com/diboot/example/entity/User.java index 9fc385a..a0febbe 100644 --- a/diboot-example/src/main/java/com/diboot/example/entity/User.java +++ b/diboot-example/src/main/java/com/diboot/example/entity/User.java @@ -13,6 +13,9 @@ import lombok.Data; public class User extends BaseEntity { private static final long serialVersionUID = 3050761344045195972L; + @TableField + private Long departmentId; + @TableField private String username; diff --git a/diboot-example/src/main/java/com/diboot/example/mapper/EmployeeMapper.java b/diboot-example/src/main/java/com/diboot/example/mapper/EmployeeMapper.java deleted file mode 100644 index 43496cd..0000000 --- a/diboot-example/src/main/java/com/diboot/example/mapper/EmployeeMapper.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.diboot.example.mapper; - -import com.diboot.core.mapper.BaseCrudMapper; -import com.diboot.example.entity.Employee; - -/** - * 员工Mapper - * @author Mazhicheng - * @version 2018/12/22 - * Copyright © www.dibo.ltd - */ -public interface EmployeeMapper extends BaseCrudMapper { - -} - diff --git a/diboot-example/src/main/java/com/diboot/example/mapper/EmployeeMapper.xml b/diboot-example/src/main/java/com/diboot/example/mapper/EmployeeMapper.xml deleted file mode 100644 index 9bde515..0000000 --- a/diboot-example/src/main/java/com/diboot/example/mapper/EmployeeMapper.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/diboot-example/src/main/java/com/diboot/example/service/EmployeeService.java b/diboot-example/src/main/java/com/diboot/example/service/EmployeeService.java deleted file mode 100644 index 37d5a08..0000000 --- a/diboot-example/src/main/java/com/diboot/example/service/EmployeeService.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.diboot.example.service; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.diboot.core.service.BaseService; -import com.diboot.example.entity.Employee; - -import java.util.List; -import java.util.Map; - -/** - * 员工相关Service - * @author Mazhicheng - * @version v2.0 - * @date 2019/1/5 - */ -public interface EmployeeService extends BaseService { - - List> testCustomQueryWrapper(QueryWrapper wrapper); - -} diff --git a/diboot-example/src/main/java/com/diboot/example/service/impl/EmployeeServiceImpl.java b/diboot-example/src/main/java/com/diboot/example/service/impl/EmployeeServiceImpl.java deleted file mode 100644 index 2ef15ba..0000000 --- a/diboot-example/src/main/java/com/diboot/example/service/impl/EmployeeServiceImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.diboot.example.service.impl; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.diboot.core.service.impl.BaseServiceImpl; -import com.diboot.example.entity.Employee; -import com.diboot.example.mapper.EmployeeMapper; -import com.diboot.example.service.EmployeeService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Map; - -/** - * 员工相关Service - * @author Mazhicheng - * @version 2018/12/23 - * Copyright © www.dibo.ltd - */ -@Service -@Slf4j -public class EmployeeServiceImpl extends BaseServiceImpl implements EmployeeService { - - @Override - public List> testCustomQueryWrapper(QueryWrapper wrapper){ - return getBaseMapper().selectMaps(wrapper); - } -} diff --git a/diboot-example/src/main/java/com/diboot/example/vo/DepartmentVO.java b/diboot-example/src/main/java/com/diboot/example/vo/DepartmentVO.java index 200f4c6..22f6ee1 100644 --- a/diboot-example/src/main/java/com/diboot/example/vo/DepartmentVO.java +++ b/diboot-example/src/main/java/com/diboot/example/vo/DepartmentVO.java @@ -1,5 +1,6 @@ package com.diboot.example.vo; +import com.diboot.core.binding.annotation.BindEntity; import com.diboot.core.binding.annotation.BindEntityList; import com.diboot.core.binding.annotation.BindField; import com.diboot.example.entity.Department; @@ -20,9 +21,13 @@ public class DepartmentVO extends Department { @BindField(entity = Organization.class, field = "name", condition = "org_id=id") private String orgName; + @BindEntity(entity = Organization.class, condition="this.org_id=id") + private Organization organization; + @BindField(entity = Department.class, field = "name", condition = "parent_id=id") private String parentName; + //TODO 该绑定未生效,待检查 @BindEntityList(entity = Department.class, condition = "id=parent_id") private List children; diff --git a/diboot-example/src/main/java/com/diboot/example/vo/EmployeeVO.java b/diboot-example/src/main/java/com/diboot/example/vo/EmployeeVO.java deleted file mode 100644 index 019d771..0000000 --- a/diboot-example/src/main/java/com/diboot/example/vo/EmployeeVO.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.diboot.example.vo; - -import com.diboot.core.binding.annotation.BindEntity; -import com.diboot.core.binding.annotation.BindField; -import com.diboot.core.binding.annotation.BindMetadata; -import com.diboot.example.entity.Department; -import com.diboot.example.entity.Employee; -import com.diboot.example.entity.Organization; -import lombok.Data; - -/** - * @author Mazhicheng - * @version v2.0 - * @date 2019/1/5 - */ -@Data -public class EmployeeVO extends Employee { - private static final long serialVersionUID = 2956966168209358800L; - - @BindEntity(entity = Department.class, condition="department_id=id") - private Department department; - - @BindMetadata(type="GENDER", field="gender") - private String genderLabel; - - @BindField(entity=Department.class, field="name", condition="this.department_id=id AND code IS NOT NULL") - private String deptName; - - // 通过中间表关联 - @BindEntity(entity = Organization.class, condition = "this.department_id=department.id AND department.org_id=id AND department.deleted=0") // AND deleted=0 - private Organization organization; -} \ No newline at end of file diff --git a/diboot-example/src/main/java/com/diboot/example/vo/OrganizationVO.java b/diboot-example/src/main/java/com/diboot/example/vo/OrganizationVO.java deleted file mode 100644 index 6ebce98..0000000 --- a/diboot-example/src/main/java/com/diboot/example/vo/OrganizationVO.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.diboot.example.vo; - -import com.diboot.core.binding.annotation.BindEntityList; -import com.diboot.core.binding.annotation.BindField; -import com.diboot.example.entity.Organization; -import lombok.Data; - -import java.util.List; - -/** - * @author Mazhicheng - * @version v2.0 - * @date 2019/1/5 - */ -@Data -public class OrganizationVO extends Organization { - private static final long serialVersionUID = 9056449207962546696L; - - @BindField(entity = Organization.class, field = "name", condition = "this.parentId=id") - private String parentName; - - @BindEntityList(entity = Organization.class, condition = "this.id=parentId") - private List children; - -} diff --git a/diboot-example/src/main/java/com/diboot/example/vo/UserVO.java b/diboot-example/src/main/java/com/diboot/example/vo/UserVO.java index b3764e1..c930bdd 100644 --- a/diboot-example/src/main/java/com/diboot/example/vo/UserVO.java +++ b/diboot-example/src/main/java/com/diboot/example/vo/UserVO.java @@ -4,6 +4,7 @@ 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.BindMetadata; +import com.diboot.example.entity.Department; import com.diboot.example.entity.Organization; import com.diboot.example.entity.Role; import com.diboot.example.entity.User; @@ -23,12 +24,22 @@ public class UserVO extends User { @BindMetadata(type="GENDER", field = "gender") private String genderLabel; + @BindField(entity=Department.class, field="name", condition="department_id=id AND code IS NOT NULL") + private String deptName; + + @BindEntity(entity = Department.class, condition="department_id=id") + private Department department; + // 支持级联字段关联 //@BindField(entity = Organization.class, field="name", condition="this.departmentId=Department.id AND Department.orgId=id") private String orgName; + // 通过中间表关联 + @BindEntity(entity = Organization.class, condition = "this.department_id=department.id AND department.org_id=id AND department.deleted=0") // AND deleted=0 + private Organization organization; + // 支持多-多Entity实体关联 - //@BindEntityList(entity = Role.class, condition="this.id=user_role.user_id AND user_role.role_id=id") + @BindEntityList(entity = Role.class, condition="this.id=user_role.user_id AND user_role.role_id=id") private List roleList; } \ No newline at end of file diff --git a/diboot-example/src/main/resources/init-mysql.sql b/diboot-example/src/main/resources/init-mysql.sql new file mode 100644 index 0000000..e56854d --- /dev/null +++ b/diboot-example/src/main/resources/init-mysql.sql @@ -0,0 +1,90 @@ +-- create schema diboot_example collate utf8_general_ci; +-- 初始化表 +create table department +( + id bigint unsigned not null comment 'ID' + primary key, + parent_id bigint default 0 not null comment '上级部门ID', + org_id bigint not null comment '单位ID', + name varchar(50) not null comment '名称', + code varchar(20) null comment '编码', + extdata varchar(100) null comment '扩展字段', + deleted tinyint(1) default 0 not null comment '已删除', + create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间' +) + comment '组织单位' charset=utf8mb4; + +create table metadata +( + id int unsigned auto_increment comment 'ID' + primary key, + parent_id int unsigned not null comment '父ID', + type varchar(50) not null comment '元数据类型', + item_name varchar(100) not null comment '元数据项显示名', + item_value varchar(100) null comment '元数据项存储值', + comment varchar(200) null comment '备注', + extdata varchar(200) null comment '扩展属性', + sort_id smallint(6) default 99 not null comment '排序号', + `system` tinyint(1) default 0 not null comment '是否是系统预置', + editable tinyint(1) default 1 not null comment '是否可编辑', + deleted tinyint(1) default 0 not null comment '已删除', + create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间' +); + +create table organization +( + id int auto_increment comment 'ID' + primary key, + parent_id int default 0 not null comment '上级单位ID', + name varchar(100) not null comment '名称', + telphone varchar(20) null comment '电话', + address varchar(255) null comment '地址', + deleted tinyint(1) default 0 not null comment '是否有效', + create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间' +) + comment '组织单位' charset=utf8mb4; + +create table role +( + id int auto_increment comment 'ID' + primary key, + name varchar(20) null, + code varchar(20) null, + deleted tinyint(1) default 0 null, + create_time timestamp default CURRENT_TIMESTAMP null comment '创建时间' +); + +create table user +( + id int auto_increment comment 'ID' + primary key, + department_id int default 0 not null, + username varchar(20) null, + gender varchar(20) null, + deleted tinyint(1) default 0 null, + create_time timestamp default CURRENT_TIMESTAMP null comment '创建时间' +); + +create table user_role +( + user_id int not null comment '用户ID', + role_id int not null comment '角色ID', + primary key (user_id, role_id) +); + +-- 初始化样例数据 +INSERT INTO department (id, parent_id, org_id, name, code) +VALUES (10001, 0, 100001, '研发部', 'DEV'), (10002, 10001, 100001, '开发组', 'DEVT'), (10003, 10001, 100001, '测试组', 'TST'); + +INSERT INTO metadata (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); + +INSERT INTO organization (id, parent_id, name, telphone, address) +VALUES (100000, 0, '帝博集团', '0512-12345678', '江苏苏州'), (100001, 100000, '苏州帝博', '0512-62988949', '江苏苏州'); + +INSERT INTO role (id, name, code) VALUES (101, '管理员', 'ADMIN'), (102, '操作员', 'OPERATOR'), (103, '只读用户', 'READ'), (104, '项目经理', 'PM'); + +INSERT INTO user (id, department_id, username, gender) +VALUES (1001, 10002, '张三', 'M'), (1002, 10002, '李四', 'F'), (1003, 10003, '王五', 'M'), (1004, 10001, '马六', 'M'); + +INSERT INTO user_role (user_id, role_id) VALUES (1001, 101),(1001, 102),(1003, 102),(1003, 103); \ No newline at end of file