Binder.bind()实现代码优化

This commit is contained in:
mazhicheng 2019-06-01 13:31:36 +08:00
parent 89e9fb699d
commit d708d474aa
7 changed files with 189 additions and 191 deletions

View File

@ -72,24 +72,33 @@ public class EntityBinder<T> extends BaseBinder<T> {
if(V.isEmpty(annoObjectForeignKeyList)){
return;
}
// 结果转换Map
Map<String, T> valueEntityMap = new HashMap<>();
// 通过中间表关联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: SELECT id, org_id FROM department WHERE id IN(?)
String sql = middleTable.toSQL(annoObjectForeignKeyList);
// 执行查询并合并结果
String keyName = middleTable.getEqualsToRefEntityPkColumn(), valueName = middleTable.getEqualsToAnnoObjectFKColumn();
Map<String, List> middleTableResultMap = SqlExecutor.executeQueryAndMergeResult(sql, annoObjectForeignKeyList, keyName, valueName);
Map<String, Object> middleTableResultMap = middleTable.executeOneToOneQuery(annoObjectForeignKeyList);
if(V.notEmpty(middleTableResultMap)){
// 提取entity主键值集合
Collection middleTableColumnValueList = middleTableResultMap.keySet();
Collection middleTableColumnValueList = middleTableResultMap.values();
// 构建查询条件
queryWrapper.in(S.toSnakeCase(referencedEntityPrimaryKey), middleTableColumnValueList);
// 查询entity列表
List<T> list = referencedService.getEntityList(queryWrapper);
// 基于中间表查询结果和entity列表绑定结果
bindingResultWithMiddleTable(S.toLowerCaseCamel(referencedEntityPrimaryKey), list, middleTableResultMap);
if(V.notEmpty(list)){
// 转换entity列表为Map<ID, Entity>
Map<String, T> listMap = BeanUtils.convertToStringKeyObjectMap(list, S.toLowerCaseCamel(referencedEntityPrimaryKey));
for(Map.Entry<String, Object> entry : middleTableResultMap.entrySet()){
Object fetchValueId = entry.getValue();
if(fetchValueId == null){
continue;
}
String key = entry.getKey();
T value = listMap.get(String.valueOf(fetchValueId));
valueEntityMap.put(key, value);
}
}
}
}
// 直接关联Entity
@ -100,47 +109,15 @@ public class EntityBinder<T> extends BaseBinder<T> {
queryWrapper.in(S.toSnakeCase(referencedEntityPrimaryKey), annoObjectForeignKeyList);
// 查询entity列表
List<T> list = referencedService.getEntityList(queryWrapper);
// 绑定结果
bindingResult(S.toLowerCaseCamel(referencedEntityPrimaryKey), list);
}
}
/***
* 基于中间表查询结果和entity列表绑定结果
* @param doPkPropName
* @param list
*/
private <E> void bindingResultWithMiddleTable(String doPkPropName, List<E> list, Map<String, List> middleTableResultMap) {
// 构建IdString-Entity之间的映射Map
Map<String, E> 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("{}.{}={} 无匹配结果!", entity.getClass().getSimpleName(), doPkPropName, pkValue);
if(V.notEmpty(list)){
String refEntityPKFieldName = S.toLowerCaseCamel(referencedEntityPrimaryKey);
for(T entity : list){
String pkValue = BeanUtils.getStringProperty(entity, refEntityPKFieldName);
valueEntityMap.put(pkValue, entity);
}
}
}
// 绑定
BeanUtils.bindPropValueOfList(annoObjectField, annoObjectList, annoObjectForeignKey, valueEntityMap);
}
/***
* 绑定结果
* @param doPkPropName
* @param list
*/
private void bindingResult(String doPkPropName, List<T> list) {
Map<String, T> valueEntityMap = new HashMap<>(list.size());
for(T entity : list){
String pkValue = BeanUtils.getStringProperty(entity, doPkPropName);
valueEntityMap.put(pkValue, entity);
}
// 绑定
// 绑定结果
BeanUtils.bindPropValueOfList(annoObjectField, annoObjectList, annoObjectForeignKey, valueEntityMap);
}

View File

@ -45,32 +45,35 @@ public class EntityListBinder<T> extends EntityBinder<T> {
if(V.isEmpty(annoObjectForeignKeyList)){
return;
}
Map<String, List<T>> valueEntityListMap = new HashMap<>();
// 解析中间表查询 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<String, List> middleTableResultMap = SqlExecutor.executeQueryAndMergeResult(sql, annoObjectForeignKeyList, keyName, valueName);
Map<String, List> middleTableResultMap = middleTable.executeOneToManyQuery(annoObjectForeignKeyList);
if(V.notEmpty(middleTableResultMap)){
// 收集查询结果values集合
List entityIdList = new ArrayList();
for(Map.Entry<String, List> entry : middleTableResultMap.entrySet()){
if(V.notEmpty(entry.getValue())){
for(Object id : entry.getValue()){
if(!entityIdList.contains(id)){
entityIdList.add(id);
}
}
}
}
List entityIdList = extractIdValueFromMap(middleTableResultMap);
// 构建查询条件
queryWrapper.in(S.toSnakeCase(referencedEntityPrimaryKey), entityIdList);
// 查询entity列表: List<Role>
List list = referencedService.getEntityList(queryWrapper);
// 绑定结果
bindingResultWithMiddleTable(S.toLowerCaseCamel(annoObjectForeignKey), list, middleTableResultMap);
// 转换entity列表为Map<ID, Entity>
Map<String, T> entityMap = BeanUtils.convertToStringKeyObjectMap(list, S.toLowerCaseCamel(referencedEntityPrimaryKey));
for(Map.Entry<String, List> entry : middleTableResultMap.entrySet()){
// List<roleId>
List annoObjFKList = entry.getValue();
if(V.isEmpty(annoObjFKList)){
continue;
}
List<T> valueList = new ArrayList();
for(Object obj : annoObjFKList){
T ent = entityMap.get(String.valueOf(obj));
if(ent != null){
valueList.add(ent);
}
}
valueEntityListMap.put(entry.getKey(), valueList);
}
}
}
else{
@ -78,58 +81,40 @@ public class EntityListBinder<T> extends EntityBinder<T> {
queryWrapper.in(S.toSnakeCase(referencedEntityPrimaryKey), annoObjectForeignKeyList);
// 查询entity列表
List<T> list = referencedService.getEntityList(queryWrapper);
// 绑定结果
bindingResult(S.toLowerCaseCamel(referencedEntityPrimaryKey), list);
}
}
/***
* 基于中间表查询结果和entity列表绑定结果
* @param annoObjectForeignKey
* @param list
*/
private <E> void bindingResultWithMiddleTable(String annoObjectForeignKey, List<E> list, Map<String, List> middleTableResultMap) {
if(V.isEmpty(list)){
return;
}
// List<Role> 转换为 Map<Id,Role>
Map<String, E> entityMap = BeanUtils.convertToStringKeyObjectMap(list, annoObjectForeignKey);
// 将Map<String, List<Id>> 转换为 Map<String, List<Role>>
Map<String, List<E>> valueEntityMap = new HashMap<>(list.size());
for(Map.Entry<String, List> entry : middleTableResultMap.entrySet()){
// List<roleId>
List annoObjFKList = entry.getValue();
if(V.notEmpty(annoObjFKList)){
List<E> valueList = new ArrayList();
for(Object obj : annoObjFKList){
E ent = entityMap.get(String.valueOf(obj));
if(ent != null){
valueList.add(ent);
if(V.notEmpty(list)){
for(T entity : list){
String keyValue = BeanUtils.getStringProperty(entity, S.toLowerCaseCamel(referencedEntityPrimaryKey));
List<T> entityList = valueEntityListMap.get(keyValue);
if(entityList == null){
entityList = new ArrayList<>();
valueEntityListMap.put(keyValue, entityList);
}
entityList.add(entity);
}
valueEntityMap.put(entry.getKey(), valueList);
}
else{
log.warn("转换结果异常,中间关联条件数据不一致");
}
}
// 绑定
BeanUtils.bindPropValueOfList(annoObjectField, annoObjectList, annoObjectForeignKey, valueEntityMap);
}
private void bindingResult(String fkName, List<T> list) {
Map<String, List<T>> valueEntityListMap = new HashMap<>(list.size());
for(T entity : list){
String keyValue = BeanUtils.getStringProperty(entity, fkName);
List<T> entityList = valueEntityListMap.get(keyValue);
if(entityList == null){
entityList = new ArrayList<>();
valueEntityListMap.put(keyValue, entityList);
}
entityList.add(entity);
}
// 绑定
// 绑定结果
BeanUtils.bindPropValueOfList(annoObjectField, annoObjectList, annoObjectForeignKey, valueEntityListMap);
}
/**
* 从Map中提取ID的值
* @param middleTableResultMap
* @return
*/
private List extractIdValueFromMap(Map<String, List> middleTableResultMap) {
List entityIdList = new ArrayList();
for(Map.Entry<String, List> entry : middleTableResultMap.entrySet()){
if(V.isEmpty(entry.getValue())){
continue;
}
for(Object id : entry.getValue()){
if(!entityIdList.contains(id)){
entityIdList.add(id);
}
}
}
return entityIdList;
}
}

View File

@ -85,60 +85,23 @@ public class FieldBinder<T> extends BaseBinder<T> {
if(V.isEmpty(annoObjectForeignKeyList)){
return;
}
// 将结果list转换成map
Map<String, Object> middleTableResultMap = null;
//@BindField(entity = Organization.class, field="name", condition="this.department_id=department.id AND department.org_id=id")
//String orgName;
if(middleTable != null){
// 提取中间表查询SQL: SELECT id, org_id FROM department WHERE id IN(?)
String sql = middleTable.toSQL(annoObjectForeignKeyList);
// 执行查询并合并结果
String keyName = middleTable.getEqualsToAnnoObjectFKColumn(), valueName = middleTable.getEqualsToRefEntityPkColumn();
Map<String, List> middleTableResultMap = SqlExecutor.executeQueryAndMergeResult(sql, annoObjectForeignKeyList, keyName, valueName);
middleTableResultMap = middleTable.executeOneToOneQuery(annoObjectForeignKeyList);
if(V.notEmpty(middleTableResultMap)){
// 收集查询结果values集合
List middleTableColumnValueList = new ArrayList();
for(Map.Entry<String, List> entry : middleTableResultMap.entrySet()){
if(V.notEmpty(entry.getValue())){
for(Object id : entry.getValue()){
if(!middleTableColumnValueList.contains(id)){
middleTableColumnValueList.add(id);
}
}
}
}
Collection middleTableColumnValueList = middleTableResultMap.values();
// 构建查询条件
List<String> selectColumns = new ArrayList<>(referencedGetterColumnNameList.size()+1);
selectColumns.add(referencedEntityPkName);
selectColumns.addAll(referencedGetterColumnNameList);
queryWrapper.select(S.toStringArray(selectColumns)).in(S.toSnakeCase(referencedEntityPrimaryKey), middleTableColumnValueList);
// 获取匹配结果的mapList: SELECT id,name FROM organization
List<Map<String, Object>> mapList = referencedService.getMapList(queryWrapper);
if(V.isEmpty(mapList)){
return;
}
// 将结果list转换成map
Map<String, Map<String, Object>> referencedEntityPk2DataMap = new HashMap<>(mapList.size());
// 转换列名为字段名MyBatis-plus的getMapList结果会将列名转成驼峰式
String referencedEntityPkFieldName = S.toLowerCaseCamel(referencedEntityPkName);
for(Map<String, Object> map : mapList){
Object pkVal = map.get(referencedEntityPkFieldName);
if(pkVal != null){
referencedEntityPk2DataMap.put(String.valueOf(pkVal), map);
}
}
// 遍历list并赋值
for(Object annoObject : annoObjectList){
// 将数字类型转换成字符串以便解决类型不一致的问题
String annoObjectId = BeanUtils.getStringProperty(annoObject, annoObjectFkFieldName);
// 通过中间结果Map转换得到OrgId
List valueList = middleTableResultMap.get(annoObjectId);
String annoObjectFkFieldValue = String.valueOf(valueList.get(0));
Map<String, Object> relationMap = referencedEntityPk2DataMap.get(annoObjectFkFieldValue);
if(relationMap != null){
for(int i = 0; i< annoObjectSetterPropNameList.size(); i++){
BeanUtils.setProperty(annoObject, annoObjectSetterPropNameList.get(i), relationMap.get(S.toLowerCaseCamel(referencedGetterColumnNameList.get(i))));
}
}
}
}
else{
return;
}
}
else{
@ -147,33 +110,40 @@ public class FieldBinder<T> extends BaseBinder<T> {
selectColumns.add(referencedEntityPkName);
selectColumns.addAll(referencedGetterColumnNameList);
queryWrapper.select(S.toStringArray(selectColumns)).in(referencedEntityPkName, annoObjectForeignKeyList);
// 获取匹配结果的mapList
List<Map<String, Object>> mapList = referencedService.getMapList(queryWrapper);
if(V.isEmpty(mapList)){
return;
}
// 获取匹配结果的mapList
List<Map<String, Object>> mapList = referencedService.getMapList(queryWrapper);
if(V.isEmpty(mapList)){
return;
}
// 将结果list转换成map
Map<String, Map<String, Object>> referencedEntityPk2DataMap = new HashMap<>(mapList.size());
// 转换列名为字段名MyBatis-plus的getMapList结果会将列名转成驼峰式
String referencedEntityPkFieldName = S.toLowerCaseCamel(referencedEntityPkName);
for(Map<String, Object> map : mapList){
Object pkVal = map.get(referencedEntityPkFieldName);
if(pkVal != null){
referencedEntityPk2DataMap.put(String.valueOf(pkVal), map);
}
// 将结果list转换成map
Map<String, Map<String, Object>> referencedEntityPk2DataMap = new HashMap<>(mapList.size());
// 转换列名为字段名MyBatis-plus的getMapList结果会将列名转成驼峰式
String referencedEntityPkFieldName = S.toLowerCaseCamel(referencedEntityPkName);
for(Map<String, Object> map : mapList){
Object pkVal = map.get(referencedEntityPkFieldName);
if(pkVal != null){
referencedEntityPk2DataMap.put(String.valueOf(pkVal), map);
}
}
// 遍历list并赋值
for(Object annoObject : annoObjectList){
// 将数字类型转换成字符串以便解决类型不一致的问题
String annoObjectId = BeanUtils.getStringProperty(annoObject, annoObjectFkFieldName);
// 通过中间结果Map转换得到OrgId
if(V.notEmpty(middleTableResultMap)){
Object value = middleTableResultMap.get(annoObjectId);
annoObjectId = String.valueOf(value);
}
// 遍历list并赋值
for(Object annoObject : annoObjectList){
// 将数字类型转换成字符串以便解决类型不一致的问题
String annoObjectId = BeanUtils.getStringProperty(annoObject, annoObjectFkFieldName);
Map<String, Object> relationMap = referencedEntityPk2DataMap.get(annoObjectId);
if(relationMap != null){
for(int i = 0; i< annoObjectSetterPropNameList.size(); i++){
BeanUtils.setProperty(annoObject, annoObjectSetterPropNameList.get(i), relationMap.get(S.toLowerCaseCamel(referencedGetterColumnNameList.get(i))));
}
Map<String, Object> relationMap = referencedEntityPk2DataMap.get(annoObjectId);
if(relationMap != null){
for(int i = 0; i< annoObjectSetterPropNameList.size(); i++){
BeanUtils.setProperty(annoObject, annoObjectSetterPropNameList.get(i), relationMap.get(S.toLowerCaseCamel(referencedGetterColumnNameList.get(i))));
}
}
}
}
}

View File

@ -2,11 +2,13 @@ package com.diboot.core.binding.parser;
import com.diboot.core.config.Cons;
import com.diboot.core.util.S;
import com.diboot.core.util.SqlExecutor;
import com.diboot.core.util.V;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 中间表
@ -68,6 +70,40 @@ public class MiddleTable {
return equalsToRefEntityPkColumn;
}
/**
* 执行1-1关联查询得到关联映射Map
* @param annoObjectForeignKeyList
* @return
*/
public Map<String, Object> executeOneToOneQuery(List annoObjectForeignKeyList){
// 提取中间表查询SQL: SELECT id, org_id FROM department WHERE id IN(?)
String sql = toSQL(annoObjectForeignKeyList);
// 执行查询并合并结果
//id
String keyName = getEqualsToAnnoObjectFKColumn(),
//org_id
valueName = getEqualsToRefEntityPkColumn();
Map<String, Object> middleTableResultMap = SqlExecutor.executeQueryAndMergeOneToOneResult(sql, annoObjectForeignKeyList, keyName, valueName);
return middleTableResultMap;
}
/**
* 执行1-N关联查询得到关联映射Map
* @param annoObjectForeignKeyList
* @return
*/
public Map<String, List> executeOneToManyQuery(List annoObjectForeignKeyList){
// 提取中间表查询SQL: SELECT user_id, role_id FROM user_role WHERE user_id IN(?)
String sql = toSQL(annoObjectForeignKeyList);
// 执行查询并合并结果
//user_id
String keyName = getEqualsToAnnoObjectFKColumn(),
//role_id
valueName = getEqualsToRefEntityPkColumn();
Map<String, List> middleTableResultMap = SqlExecutor.executeQueryAndMergeOneToManyResult(sql, annoObjectForeignKeyList, keyName, valueName);
return middleTableResultMap;
}
/**
* 转换查询SQL
* @param annoObjectForeignKeyList 注解外键值的列表用于拼接SQL查询
@ -80,8 +116,8 @@ public class MiddleTable {
// 构建SQL
StringBuilder sb = new StringBuilder();
sb.append("SELECT ").append(this.equalsToAnnoObjectFKColumn).append(Cons.SEPARATOR_COMMA)
.append(this.equalsToRefEntityPkColumn).append(" FROM ").append(this.table)
.append(" WHERE ").append(this.equalsToAnnoObjectFKColumn).append(" IN (");
.append(this.equalsToRefEntityPkColumn).append(" FROM ").append(this.table)
.append(" WHERE ").append(this.equalsToAnnoObjectFKColumn).append(" IN (");
String params = S.repeat("?", ",", annoObjectForeignKeyList.size());
sb.append(params).append(")");
if(this.additionalConditions != null){

View File

@ -39,7 +39,7 @@ public class SqlExecutor {
log.warn("查询参数集合数量过多, size={},请检查调用是否合理!", params.size());
}
}
log.debug("执行查询SQL: "+sql);
log.debug("==>\tSQL: "+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 +60,7 @@ public class SqlExecutor {
}
rs.close();
}
log.debug("查询结果: "+JSON.stringify(mapList));
log.debug("<==\t"+JSON.stringify(mapList));
return mapList;
}
catch(Exception e){
@ -69,6 +69,33 @@ public class SqlExecutor {
}
}
/**
* 执行1-1关联查询和合并结果并将结果Map的key类型转成String
*
* @param sql
* @param params
* @return
*/
public static <E> Map<String, Object> executeQueryAndMergeOneToOneResult(String sql, List<E> params, String keyName, String valueName) {
List<Map<String, E>> resultSetMapList = null;
try {
resultSetMapList = executeQuery(sql, params);
} catch (Exception e) {
log.warn("执行查询异常", e);
}
// 合并list为map
Map<String, Object> resultMap = new HashMap<>();
if(V.notEmpty(resultSetMapList)){
for(Map<String, E> row : resultSetMapList){
String key = String.valueOf(row.get(keyName));
Object value = row.get(valueName);
resultMap.put(key, value);
}
}
return resultMap;
}
/**
* 执行查询和合并结果并将结果Map的key类型转成String
*
@ -76,7 +103,7 @@ public class SqlExecutor {
* @param params
* @return
*/
public static <E> Map<String, List> executeQueryAndMergeResult(String sql, List<E> params, String keyName, String valueName){
public static <E> Map<String, List> executeQueryAndMergeOneToManyResult(String sql, List<E> params, String keyName, String valueName){
List<Map<String, E>> resultSetMapList = null;
try {
resultSetMapList = executeQuery(sql, params);

View File

@ -18,15 +18,15 @@ import java.util.List;
public class DepartmentVO extends Department {
private static final long serialVersionUID = -362116388664907913L;
// 直接关联Entity中的某字段
@BindField(entity = Organization.class, field = "name", condition = "org_id=id")
private String orgName;
// 直接关联Entity
@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;
// 直接关联多个Entity
@BindEntityList(entity = Department.class, condition = "id=parent_id")
private List<Department> children;

View File

@ -21,24 +21,27 @@ import java.util.List;
public class UserVO extends User {
private static final long serialVersionUID = 3526115343377985725L;
// 绑定元数据枚举
@BindMetadata(type="GENDER", field = "gender")
private String genderLabel;
// 字段关联相同条件的entity+condition将合并为一条SQL查询
@BindField(entity=Department.class, field="name", condition="department_id=id AND code IS NOT NULL")
private String deptName;
@BindField(entity=Department.class, field="code", condition="department_id=id")
private String deptCode;
@BindEntity(entity = Department.class, condition="department_id=id")
private Department department;
// 支持级联字段关联
// 支持级联字段关联相同条件的entity+condition将合并为一条SQL查询
@BindField(entity = Organization.class, field="name", condition="this.department_id=department.id AND department.org_id=id")
private String orgName;
@BindField(entity = Organization.class, field="telphone", condition="this.department_id=department.id AND department.org_id=id")
private String orgTelphone;
// 通过中间表关联
// 通过中间表关联Entity
@BindEntity(entity = Organization.class, condition = "this.department_id=department.id AND department.org_id=id") // AND deleted=0
private Organization organization;
// 支持-多Entity实体关联
// 支持通过中间表的-多Entity实体关联
@BindEntityList(entity = Role.class, condition="this.id=user_role.user_id AND user_role.role_id=id")
private List<Role> roleList;