package com.kingdee.eas.custom.dataconfig.utils; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.kingdee.bos.Context; import com.kingdee.bos.metadata.data.ColumnInfo; import com.kingdee.bos.metadata.entity.*; import com.kingdee.eas.custom.entryconfig.DataConfigSelectFieldEntryCollection; import com.kingdee.eas.custom.entryconfig.DataConfigSelectFieldEntryInfo; import com.kingdee.shr.base.syssetting.util.MetaDataUtil; /** * SQL工具类,提供实体信息获取、SQL语句构建(关联表JOIN)以及查询字段信息JSON生成等功能 */ public class SqlUtils { /** * 根据实体名称获取实体对象信息 * @param name 实体名称 * @param context 上下文对象(此处未实际使用,保留参数可能为扩展用) * @return 实体对象信息EntityObjectInfo */ public EntityObjectInfo getEntryInfo(String name, Context context) { // 调用MetaDataUtil工具类根据实体名称获取实体对象信息 return MetaDataUtil.getEntityObjectByEntityName(name); } /** * 构建SQL语句中的表连接部分(包括主表和关联表的LEFT JOIN) * @param sql 用于拼接SQL的StringBuilder对象 * @param entityObjectInfo 实体对象信息,用于获取表名和属性信息 * @param alias 表的别名,如果为null或空则使用实体真实名称作为别名 * @param context 上下文对象(此处未实际使用,保留参数可能为扩展用) * @param isHead 是否为主表(头部表),主表不需要ON条件 * @param on 连接条件,当isHead为false时使用 */ public void getSql(StringBuilder sql, EntityObjectInfo entityObjectInfo, String alias , Context context, Boolean isHead, String on) { // 如果别名为空或空字符串,则使用实体的真实名称作为别名 if (alias == null || alias.equals("")) { String realName = entityObjectInfo.getRealName(); alias = realName; } // 获取实体对应的数据库表名 String name = entityObjectInfo.getTable().getName(); // 拼接表名和别名到SQL中(如:table_name as "alias") sql.append(name + " as ").append("\"" + alias + "\"").append("\n"); // 如果不是主表,则拼接ON条件 if (!isHead) { sql.append("on " + on).append("\n"); } // 获取实体所有非重复的继承属性集合 PropertyCollection properties = entityObjectInfo.getInheritedNoDuplicatedProperties(); // 遍历属性集合 for (int i = 0; i < properties.size(); i++) { PropertyInfo propertyInfo = properties.get(i); // 判断当前属性是否为关联属性(LinkPropertyInfo) if (propertyInfo instanceof LinkPropertyInfo) { // 生成关联表的别名(当前属性名 + 主表别名) String name1 = propertyInfo.getName() + alias; // 获取关联属性对应的映射字段(数据库列) ColumnInfo mappingField = propertyInfo.getMappingField(); // 如果映射字段为空,则跳过当前属性 if (mappingField == null) { continue; } // 获取映射字段的名称(数据库列名) String mappingFieldName = mappingField.getName(); // 获取关联属性指向的目标实体对应的表名 String tableName = ((LinkPropertyInfo) propertyInfo).getRelationship().getSupplierObject().getTable().getName(); // 强制转换为LinkPropertyInfo以便获取关联关系 LinkPropertyInfo linkPropertyInfo = ((LinkPropertyInfo) propertyInfo); RelationshipInfo r = linkPropertyInfo.getRelationship(); // 获取目标实体的全限定名 String fullName = r.getSupplierObject().getFullName(); // 拼接LEFT JOIN语句,关联目标表(如:left join target_table as "name1") sql.append("left join ").append(tableName).append(" as ").append("\"" + name1 + "\"").append("\n"); // 拼接关联条件(主表别名.映射列名 = 关联表别名.FID) sql.append("on \"" + alias + "\".\"" + mappingFieldName + "\" = " + " \"" + name1 + "\".\"FID" + "\" ").append("\n"); // 根据目标实体全限定名获取其实体对象信息 EntityObjectInfo entryInfo = this.getEntryInfo(fullName, context); // 获取目标实体的所有非重复继承属性集合 PropertyCollection propertiesChildren = entryInfo.getInheritedNoDuplicatedProperties(); // 遍历目标实体的属性集合(处理二级关联) for (int j = 0; j < propertiesChildren.size(); j++) { PropertyInfo propertyChildren = propertiesChildren.get(j); // 判断二级属性是否为关联属性 if (propertyChildren instanceof LinkPropertyInfo) { // 生成二级关联表的别名(一级关联表别名.二级属性名) String asTableChildren = name1 + "." + propertyChildren.getName(); // 获取二级关联属性的映射字段 ColumnInfo mappingFieldChildren = propertyChildren.getMappingField(); // 如果映射字段为空,则跳过当前二级属性 if (mappingFieldChildren == null) { continue; } // 获取二级关联属性指向的目标表名 String tableChildren = ((LinkPropertyInfo) propertyChildren).getRelationship().getSupplierObject().getTable().getName(); // 获取二级映射字段的名称(数据库列名) String mappingFieldNameChildren = mappingFieldChildren.getName(); // 拼接二级LEFT JOIN语句(如:left join child_table as "asTableChildren") sql.append("left join ").append(tableChildren).append(" as ").append("\"" + asTableChildren + "\"").append("\n"); // 拼接二级关联条件(一级关联表别名.二级映射列名 = 二级关联表别名.FID) sql.append("on \"" + name1 + "\".\"" + mappingFieldNameChildren + "\" = " + " \"" + asTableChildren + "\".\"FID" + "\" ").append("\n"); } } } } } /** * 生成查询字段的信息JSON数组,包含字段名、别名、数据类型、映射关系等 * @param entityObjectInfo 实体对象信息,用于获取属性信息 * @param alias 表别名,用于构建字段映射路径 * @param context 上下文对象(用于获取关联实体信息) * @return 包含字段信息的JSONArray */ public JSONArray getSelectField(EntityObjectInfo entityObjectInfo, String alias, Context context) { // 如果别名为空或空白,则默认使用实体的真实名称作为别名 if (alias == null || alias.trim().isEmpty()) { alias = entityObjectInfo.getRealName(); } // 获取实体所有非重复的继承属性集合 PropertyCollection properties = entityObjectInfo.getInheritedNoDuplicatedProperties(); JSONArray resultArray = new JSONArray(); // 用于存储返回的字段信息JSON数组 // 遍历实体属性集合 for (int i = 0; i < properties.size(); i++) { PropertyInfo propertyInfo = properties.get(i); JSONObject currentJson = new JSONObject(); // 存储当前属性的信息JSON对象 // 判断当前属性是否为关联属性(LinkPropertyInfo) if (propertyInfo instanceof LinkPropertyInfo) { // 强制转换为LinkPropertyInfo LinkPropertyInfo linkProperty = (LinkPropertyInfo) propertyInfo; String fieldName = linkProperty.getName(); // 属性名称 String fieldAlias = linkProperty.getAlias(); // 属性别名 // 设置当前关联属性的基础信息 currentJson.put("field", alias+"."+fieldName); currentJson.put("name", fieldAlias); currentJson.put("dataType", DataType.OBJECTVALUE.getName()); // 获取关联属性的映射字段(数据库列) ColumnInfo mappingField = linkProperty.getMappingField(); if (mappingField == null) { continue; // 若映射字段为空,则跳过当前属性 } // 获取关联关系信息 RelationshipInfo relationship = linkProperty.getRelationship(); // 获取关联目标实体的全限定名(作为枚举来源) String enumSource = relationship.getSupplierObject().getFullName(); currentJson.put("enumSource", enumSource); // 根据目标实体全限定名获取其实体对象信息 EntityObjectInfo relatedEntity = this.getEntryInfo(enumSource, context); // 获取目标实体的所有非重复继承属性集合(子属性) PropertyCollection childProperties = relatedEntity.getInheritedNoDuplicatedProperties(); JSONArray childrenArray = new JSONArray(); // 存储子属性信息的JSON数组 String realName = relatedEntity.getRealName(); // 遍历目标实体的子属性 for (int j = 0; j < childProperties.size(); j++) { PropertyInfo childProperty = childProperties.get(j); JSONObject childJson = new JSONObject(); // 存储当前子属性的信息JSON对象 // 设置子属性的基础信息 childJson.put("field", alias+"."+realName+"."+childProperty.getName()); childJson.put("name", childProperty.getAlias()); childJson.put("dataType", DataType.OBJECTVALUE.getName()); // 判断子属性是否为关联属性(二级关联) if (childProperty instanceof LinkPropertyInfo) { // 强制转换为LinkPropertyInfo LinkPropertyInfo childLink = (LinkPropertyInfo) childProperty; // 获取二级关联属性的映射字段 ColumnInfo childMappingField = childLink.getMappingField(); if (childMappingField == null) { continue; // 若映射字段为空,则跳过当前子属性 } // 获取二级关联关系信息 RelationshipInfo childRelationship = childLink.getRelationship(); // 获取二级关联目标实体的全限定名 String childEnumSource = childRelationship.getSupplierObject().getFullName(); // 避免循环关联(若二级关联目标与一级关联目标相同,则跳过) if (childEnumSource.equals(enumSource)) { continue; } childJson.put("enumSource", childEnumSource); // 根据二级关联目标实体全限定名获取其实体对象信息 EntityObjectInfo grandChildEntity = this.getEntryInfo(childEnumSource, context); // 获取二级目标实体的所有非重复继承属性集合(孙属性) PropertyCollection grandChildProperties = grandChildEntity.getInheritedNoDuplicatedProperties(); JSONArray grandChildArray = new JSONArray(); // 存储孙属性信息的JSON数组 // 遍历孙属性 for (int k = 0; k < grandChildProperties.size(); k++) { PropertyInfo grandChildProperty = grandChildProperties.get(k); // 只处理自有属性(OwnPropertyInfo),跳过关联属性 if (!(grandChildProperty instanceof OwnPropertyInfo)) { continue; } // 强制转换为OwnPropertyInfo OwnPropertyInfo ownGrandChild = (OwnPropertyInfo) grandChildProperty; JSONObject grandChildJson = new JSONObject(); // 设置孙属性的基础信息 grandChildJson.put("field", alias+"."+realName+"."+childProperty.getName()+"."+ownGrandChild.getName()); grandChildJson.put("name", ownGrandChild.getAlias()); grandChildJson.put("dataType", ownGrandChild.getDataType().getName()); // 若孙属性为枚举类型,设置枚举来源 if (ownGrandChild.getDataType().getName().equals("Enum")) { grandChildJson.put("enumSource", ownGrandChild.getEnumType().getFullName()); grandChildJson.put("enumData", ownGrandChild.getEnumType().getEnumValue()); } // 处理孙属性的数据库字段映射(考虑多语言) boolean isMultilingual = ownGrandChild.getMappingField().isMultilingual(); // 构建父字段路径(一级关联别名.二级属性名) String parentFieldPath = fieldName + alias + "." + childProperty.getName(); // 获取孙属性对应的数据库列名 String dbFieldName = ownGrandChild.getMappingField().getName(); String mappingFieldVal; // 数据库字段引用(如:"alias.field"."dbColumn") String asMappingFieldVal; // 字段别名(如:"alias.field.dbColumn") // 多语言字段拼接_l2后缀(可能为特定语言标识) if (isMultilingual) { mappingFieldVal = "\"" + parentFieldPath + "\"." + dbFieldName + "_l2"; asMappingFieldVal = "\"" + parentFieldPath + "." + dbFieldName + "_l2\""; } else { mappingFieldVal = "\"" + parentFieldPath + "\"." + dbFieldName; asMappingFieldVal = "\"" + parentFieldPath + "." + dbFieldName + "\""; } grandChildJson.put("mappingField", mappingFieldVal); grandChildJson.put("asMappingField", asMappingFieldVal); // 将孙属性信息添加到孙属性数组 grandChildArray.add(grandChildJson); } // 将孙属性数组添加到当前子属性的JSON中 childJson.put("children", grandChildArray); } else if (childProperty instanceof OwnPropertyInfo) { // 子属性为自有属性(OwnPropertyInfo) OwnPropertyInfo ownChild = (OwnPropertyInfo) childProperty; // 设置子属性的数据类型 childJson.put("dataType", ownChild.getDataType().getName()); // 若子属性为枚举类型,设置枚举来源 if (ownChild.getDataType().getName().equals("Enum")) { childJson.put("enumSource", ownChild.getEnumType().getFullName()); childJson.put("enumData", ownChild.getEnumType().getEnumValue()); } // 处理子属性的数据库字段映射(考虑多语言) boolean isMultilingual = ownChild.getMappingField().isMultilingual(); // 获取子属性对应的数据库列名 String dbFieldName = ownChild.getMappingField().getName(); String mappingFieldVal; // 数据库字段引用 String asMappingFieldVal; // 字段别名 // 多语言字段拼接_l2后缀 if (isMultilingual) { mappingFieldVal = "\"" + fieldName + alias + "\"." + dbFieldName + "_l2"; asMappingFieldVal = "\"" + fieldName + alias + "." + dbFieldName + "_l2\""; } else { mappingFieldVal = "\"" + fieldName + alias + "\"." + dbFieldName; asMappingFieldVal = "\"" + fieldName + alias + "." + dbFieldName + "\""; } childJson.put("mappingField", mappingFieldVal); childJson.put("asMappingField", asMappingFieldVal); } // 将子属性信息添加到子属性数组 childrenArray.add(childJson); } // 将子属性数组添加到当前关联属性的JSON中 currentJson.put("children", childrenArray); // 将当前关联属性信息添加到结果数组 resultArray.add(currentJson); } else if (propertyInfo instanceof OwnPropertyInfo) { // 当前属性为自有属性(OwnPropertyInfo) OwnPropertyInfo ownProperty = (OwnPropertyInfo) propertyInfo; String fieldName = ownProperty.getName(); // 属性名称 String dbFieldName = ownProperty.getMappingField().getName(); // 对应的数据库列名 // 设置自有属性的基础信息 currentJson.put("field", alias+"."+fieldName); currentJson.put("name", ownProperty.getAlias()); currentJson.put("dataType", ownProperty.getDataType().getName()); // 若自有属性为枚举类型,设置枚举来源 if (ownProperty.getDataType().getName().equals("Enum")) { currentJson.put("enumSource", ownProperty.getEnumType().getFullName()); currentJson.put("enumData", ownProperty.getEnumType().getEnumValue()); } // 处理自有属性的数据库字段映射(考虑多语言) boolean isMultilingual = ownProperty.getMappingField().isMultilingual(); String mappingFieldVal; // 数据库字段引用 String asMappingFieldVal; // 字段别名 // 多语言字段拼接_l2后缀 if (isMultilingual) { mappingFieldVal = "\"" + alias + "\"." + dbFieldName + "_l2"; asMappingFieldVal = "\"" + alias + "." + dbFieldName + "_l2\""; } else { mappingFieldVal = "\"" + alias + "\"." + dbFieldName; asMappingFieldVal = "\"" + alias + "." + dbFieldName + "\""; } currentJson.put("mappingField", mappingFieldVal); currentJson.put("asMappingField", asMappingFieldVal); // 将当前自有属性信息添加到结果数组 resultArray.add(currentJson); } } // 返回包含所有字段信息的JSON数组 return resultArray; } public StringBuilder getSelectField(DataConfigSelectFieldEntryCollection fieldEntry,StringBuilder sql){ for (int i = 0; i < fieldEntry.size(); i++) { DataConfigSelectFieldEntryInfo entryInfo = fieldEntry.get(i); String databaseName = entryInfo.getDatabaseName(); String mappingKey = entryInfo.getMappingKey(); sql.append(databaseName).append(" as ").append(mappingKey); if (i==fieldEntry.size()-1){ sql.append("\n"); }else { sql.append(" , ").append("\n"); } } return sql; } }