All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.cassite.daf4j.jpa.JPQLDataAccess Maven / Gradle / Ivy

The newest version!
package net.cassite.daf4j.jpa;

import net.cassite.daf4j.*;
import net.cassite.daf4j.types.*;
import net.cassite.daf4j.util.ConstantMap;
import net.cassite.daf4j.util.AliasMap;
import net.cassite.daf4j.util.Location;
import net.cassite.daf4j.Selectable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.persistence.*;
import javax.persistence.Query;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.*;

/**
 * Use JPQLDataSource instead.
* JPA的DataAccess实现.
* 将Pure.Data Query转化为JPQL(或者直接传入)并通过JPQL进行增删改查.
* 构造时传入EntityManagerFactory */ @Deprecated class JPQLDataAccess implements DataAccess { private static final String aliasPrefix = "var"; private Logger logger = LoggerFactory.getLogger(DataAccess.class); private static class Args { public StringBuilder sb; public Where whereClause; public QueryParameter queryParameter; public Object entity; public Class entityClass; public AliasMap aliasMap; public ConstantMap constantMap; public Map toJoin; public IExpression expression; public Object obj; public Condition condition; public String aggregateFunctions; public List selectNonAggregationAliases; public boolean doGroupBy = false; public boolean notDistinctOrAlreadyDone = true; public boolean generatingSelect = false; public Args doClone() { Args args = new Args(); args.sb = this.sb; args.whereClause = this.whereClause; args.queryParameter = queryParameter; args.entity = entity; args.entityClass = this.entityClass; args.aliasMap = this.aliasMap; args.constantMap = this.constantMap; args.toJoin = this.toJoin; args.aggregateFunctions = this.aggregateFunctions; args.selectNonAggregationAliases = this.selectNonAggregationAliases; args.doGroupBy = this.doGroupBy; args.notDistinctOrAlreadyDone = this.notDistinctOrAlreadyDone; args.generatingSelect = this.generatingSelect; return args; } public Args fillObj(Object obj) { Args a = doClone(); a.obj = obj; return a; } public Args fillExp(IExpression exp) { Args a = doClone(); a.expression = exp; return a; } public Args fillWhere(Where where) { Args a = doClone(); a.whereClause = where; return a; } public Args fillCondition(Condition condition) { Args a = doClone(); a.condition = condition; return a; } public Args prepareForSubQuery(PreResult query) { Args a = this.doClone(); a.aliasMap = new AliasMap(aliasPrefix, this.aliasMap.getAliasCount()); a.toJoin = new LinkedHashMap(); a.sb = new StringBuilder(); a.entity = query.entity; a.entityClass = query.entity.getClass(); a.whereClause = query.whereClause; a.queryParameter = null; a.aggregateFunctions = null; a.selectNonAggregationAliases = new ArrayList(); a.doGroupBy = false; a.notDistinctOrAlreadyDone = true; a.generatingSelect = false; return a; } } private final EntityManager entityManager; private EntityTransaction tx; public JPQLDataAccess(EntityManager entityManager) { this.entityManager = entityManager; } /** * 生成表达式
* 调用objToString,对于exists也调用generateSelect * * @param args Args对象 * @return 生成的表达式语句 * @see JPQLDataAccess#objToString(Args) * @see JPQLDataAccess#generateSelect(Args, boolean) */ private String generateExpression(Args args) { if (args.expression.expType() == ExpressionTypes.add) { return objToString(args.fillObj(args.expression.expArgs()[0])) + " + " + objToString(args.fillObj(args.expression.expArgs()[1])); } else if (args.expression.expType() == ExpressionTypes.avg) { if (!args.notDistinctOrAlreadyDone && args.generatingSelect) { return "AVG(DISTINCT " + objToString(args.fillObj(args.expression.expArgs()[0])) + ")"; } else { return "AVG(" + objToString(args.fillObj(args.expression.expArgs()[0])) + ")"; } } else if (args.expression.expType() == ExpressionTypes.concat) { return "CONCAT(" + objToString(args.fillObj(args.expression.expArgs()[0])) + ", " + objToString(args.fillObj(args.expression.expArgs()[1])) + ")"; } else if (args.expression.expType() == ExpressionTypes.count) { if (!args.notDistinctOrAlreadyDone && args.generatingSelect) { return "COUNT(DISTINCT " + objToString(args.fillObj(args.expression.expArgs()[0])) + ")"; } else { return "COUNT(" + objToString(args.fillObj(args.expression.expArgs()[0])) + ")"; } } else if (args.expression.expType() == ExpressionTypes.divide) { return objToString(args.fillObj(args.expression.expArgs()[0])) + " / " + objToString(args.fillObj(args.expression.expArgs()[1])); } else if (args.expression.expType() == ExpressionTypes.exists) { PreResult query = (PreResult) args.expression.expArgs()[0]; Args a = args.prepareForSubQuery(query); String toReturn = "EXISTS(" + generateSelect(a, false) + ")"; args.aliasMap.setAliasCount(a.aliasMap.getAliasCount()); return toReturn; } else if (args.expression.expType() == ExpressionTypes.length) { return "LENGTH(" + objToString(args.fillObj(args.expression.expArgs()[0])) + ")"; } else if (args.expression.expType() == ExpressionTypes.locate) { return "LOCATE(" + objToString(args.fillObj(args.expression.expArgs()[0])) + ", " + objToString(args.fillObj(args.expression.expArgs()[1])) + ")"; } else if (args.expression.expType() == ExpressionTypes.lower) { return "LOWER(" + objToString(args.fillObj(args.expression.expArgs()[0])) + ")"; } else if (args.expression.expType() == ExpressionTypes.max) { if (!args.notDistinctOrAlreadyDone && args.generatingSelect) { return "MAX(DISTINCT " + objToString(args.fillObj(args.expression.expArgs()[0])) + ")"; } else { return "MAX(" + objToString(args.fillObj(args.expression.expArgs()[0])) + ")"; } } else if (args.expression.expType() == ExpressionTypes.min) { if (!args.notDistinctOrAlreadyDone && args.generatingSelect) { return "MIN(DISTINCT " + objToString(args.fillObj(args.expression.expArgs()[0])) + ")"; } else { return "MIN(" + objToString(args.fillObj(args.expression.expArgs()[0])) + ")"; } } else if (args.expression.expType() == ExpressionTypes.minus) { return objToString(args.fillObj(args.expression.expArgs()[0])) + " - " + objToString(args.fillObj(args.expression.expArgs()[1])); } else if (args.expression.expType() == ExpressionTypes.mod) { return "MOD(" + objToString(args.fillObj(args.expression.expArgs()[0])) + ", " + objToString(args.fillObj(args.expression.expArgs()[1])) + ")"; } else if (args.expression.expType() == ExpressionTypes.multi) { return objToString(args.fillObj(args.expression.expArgs()[0])) + " * " + objToString(args.fillObj(args.expression.expArgs()[1])); } else if (args.expression.expType() == ExpressionTypes.notExists) { PreResult query = (PreResult) args.expression.expArgs()[0]; Args a = args.prepareForSubQuery(query); String toReturn = "NOT EXISTS(" + generateSelect(a, false) + ")"; args.aliasMap.setAliasCount(a.aliasMap.getAliasCount()); return toReturn; } else if (args.expression.expType() == ExpressionTypes.substring) { return "SUBSTRING(" + objToString(args.fillObj(args.expression.expArgs()[0])) + ", " + objToString(args.fillObj(args.expression.expArgs()[1])) + ", " + objToString(args.fillObj(args.expression.expArgs()[2])) + ")"; } else if (args.expression.expType() == ExpressionTypes.sum) { if (!args.notDistinctOrAlreadyDone && args.generatingSelect) { return "SUM(DISTINCT " + objToString(args.fillObj(args.expression.expArgs()[0])) + ")"; } else { return "SUM(" + objToString(args.fillObj(args.expression.expArgs()[0])) + ")"; } } else if (args.expression.expType() == ExpressionTypes.trim) { return "TRIM(" + objToString(args.fillObj(args.expression.expArgs()[0])) + ")"; } else if (args.expression.expType() == ExpressionTypes.unary_negative) { return "- " + objToString(args.fillObj(args.expression.expArgs()[0])); } else if (args.expression.expType() == ExpressionTypes.upper) { return "UPPER(" + objToString(args.fillObj(args.expression.expArgs()[0])) + ")"; } else { throw new UnsupportedOperationException(args.expression.expType() + " not supported"); } } /** * 转换obj为String.对于daf4j下的对象转换为字符串,对于java自带对象转换为数字的占位符(从1开始)
* 对于IData,执行dataToString * 对于IExpression,执行generateExpression * * @param args Args对象 * @return 生成的字符串 * @see JPQLDataAccess#dataToString(IData, Args) * @see JPQLDataAccess#generateExpression(Args) */ private String objToString(Args args) { if (args.obj.getClass().isArray()) { StringBuilder sb = new StringBuilder(); sb.append("("); boolean isFirst = true; for (Object o : (Object[]) args.obj) { if (isFirst) { isFirst = false; } else { sb.append(", "); } sb.append(objToString(args.fillObj(o))); } return sb.append(")").toString(); } else if (args.obj instanceof Iterable) { StringBuilder sb = new StringBuilder(); sb.append("("); boolean isFirst = true; for (Object o : (Iterable) args.obj) { if (isFirst) { isFirst = false; } else { sb.append(", "); } sb.append(objToString(args.fillObj(o))); } return sb.append(")").toString(); } else if (args.obj.getClass().getName().startsWith("java.") || args.obj.getClass().getName().startsWith("javax.")) { return "?" + args.constantMap.add(args.obj); } else if (args.obj instanceof IData) { return dataToString((IData) args.obj, args); } else if (args.obj instanceof IExpression) { return generateExpression(args.fillExp((IExpression) args.obj)); } else { if (args.entity == args.obj) { return args.aliasMap.get(new Location(null)); } try { Location l = findEntity(args.obj, args); return args.aliasMap.get(l); } catch (IllegalArgumentException e) { throw new UnsupportedOperationException(args.obj.getClass() + " not supported"); } } } /** * 获取实体的调用位置
* 使用广度优先搜索
* 找到时自动加入AliasMap * * @param entity 从该实体开始寻找 * @param toFind 要寻找的实体 * @param list 已经经过的路径 * @param args Args对象 * @param alreadySearched 已经寻找过的实体 * @return 找到的实体位置(Location对象), 没找到则返回null */ private Location findEntity(Object entity, Object toFind, List list, Args args, Set alreadySearched, List> locationsMightBeJoined) { Map objectStringMap = new LinkedHashMap(); try { for (Field f : entity.getClass().getFields()) { // is IData if (IData.class.isAssignableFrom(f.getType())) { // get 1st generic type Class cls; try { cls = ((Class) ((ParameterizedType) f.getGenericType()).getActualTypeArguments()[0]); } catch (ClassCastException e) { // not generic type , maybe one of XTypes Class type = f.getType(); if (XInt.class.isAssignableFrom(type)) { cls = Integer.class; } else if (XLong.class.isAssignableFrom(type)) { cls = Long.class; } else if (XDouble.class.isAssignableFrom(type)) { cls = Double.class; } else if (XDate.class.isAssignableFrom(type)) { cls = Date.class; } else if (XString.class.isAssignableFrom(type)) { cls = String.class; } else if (XBool.class.isAssignableFrom(type)) { cls = Boolean.class; } else { throw e; } } // is not java. / javax. if (!cls.getName().startsWith("java.") && !cls.getName().startsWith("javax.")) { IData data = (IData) f.get(entity); Object obj = data.get(); if (obj == null) continue; if (obj instanceof Iterable) { // is aggregate Iterator it = ((Iterable) obj).iterator(); if (it.hasNext()) { Object o = it.next(); List tmp = new ArrayList(list); tmp.add(f.getName()); locationsMightBeJoined.add(new ArrayList(tmp)); if (o == toFind) { list.add(f.getName()); if (toFind != args.entity) { for (List locationList : locationsMightBeJoined) { Location loc = DataUtils.generateLocationAndFillMap(locationList, args.aliasMap); if (!args.toJoin.containsKey(loc)) { args.toJoin.put(loc, args.aliasMap.get(loc)); } } } return DataUtils.generateLocationAndFillMap(list, args.aliasMap); } else { if (!alreadySearched.contains(o)) { alreadySearched.add(o); objectStringMap.put(o, f.getName()); } } } } else { List tmp = new ArrayList(list); tmp.add(f.getName()); locationsMightBeJoined.add(new ArrayList(tmp)); // is plain object if (obj == toFind) { list.add(f.getName()); if (toFind != args.entity) { for (List locationList : locationsMightBeJoined) { Location loc = DataUtils.generateLocationAndFillMap(locationList, args.aliasMap); if (!args.toJoin.containsKey(loc)) { args.toJoin.put(loc, args.aliasMap.get(loc)); } } } return DataUtils.generateLocationAndFillMap(list, args.aliasMap); } else { if (!alreadySearched.contains(obj)) { alreadySearched.add(obj); objectStringMap.put(obj, f.getName()); } } } } } } // not found for (Object obj : objectStringMap.keySet()) { List nextList = new ArrayList(list); nextList.add(objectStringMap.get(obj)); List> nextLocationsMightBeJoined = new ArrayList>(locationsMightBeJoined); Location location = findEntity(obj, toFind, nextList, args, alreadySearched, nextLocationsMightBeJoined); if (null != location) { // found return location; } } return null; } catch (IllegalAccessException e) { throw new RuntimeException(e); } } /** * 获取Entity位置,若没有找到则抛出异常 * * @param toFind 要寻找的实体 * @param args Args对象 * @return 实体的位置(Location对象) */ private Location findEntity(Object toFind, Args args) { Location l = findEntity(args.entity, toFind, new ArrayList(), args, new HashSet(), new ArrayList>()); if (l == null) { throw new IllegalArgumentException("Cannot find location of " + toFind); } return l; } /** * 将IData转化为字符串
* 调用DataUtils.findFieldNameByIData * * @param data 要转换的IData对象 * @param args Args对象 * @return 生成的字符串 * @see DataUtils#findFieldNameByIData(IData) */ private String dataToString(IData data, Args args) { Object entity = data.getEntity(); String alias = args.aliasMap.get(new Location(new ArrayList())); if (entity != args.entity) { Location location = findEntity(entity, args); alias = args.aliasMap.get(location); } return alias + "." + DataUtils.findFieldNameByIData(data); } /** * 生成condition类型对应的语句,例如 u.age > 18
* 生成过程中调用objToString * * @param args Args对象 * @return 生成的条件语句 * @see ConditionTypes * @see JPQLDataAccess#objToString(Args) */ private String generateCondition(Args args) { if (args.condition.type == ConditionTypes.between) { return objToString(args.fillObj(args.condition.data)) + " BETWEEN " + objToString(args.fillObj(args.condition.args.get(0))) + " AND " + objToString(args.fillObj(args.condition.args.get(1))); } else if (args.condition.type == ConditionTypes.eq) { return objToString(args.fillObj(args.condition.data)) + " = " + objToString(args.fillObj(args.condition.args.get(0))); } else if (args.condition.type == ConditionTypes.ge) { return objToString(args.fillObj(args.condition.data)) + " >= " + objToString(args.fillObj(args.condition.args.get(0))); } else if (args.condition.type == ConditionTypes.gt) { return objToString(args.fillObj(args.condition.data)) + " > " + objToString(args.fillObj(args.condition.args.get(0))); } else if (args.condition.type == ConditionTypes.in) { Args a = args.prepareForSubQuery((PreResult) args.condition.args.get(0)); String subQuery = generateSelect(a, false); args.aliasMap.setAliasCount(a.aliasMap.getAliasCount()); return objToString(args.fillObj(args.condition.data)) + " IN (" + subQuery + ")"; } else if (args.condition.type == ConditionTypes.isNotNull) { return objToString(args.fillObj(args.condition.data)) + " IS NOT NULL"; } else if (args.condition.type == ConditionTypes.isNull) { return objToString(args.fillObj(args.condition.data)) + " IS NULL"; } else if (args.condition.type == ConditionTypes.le) { return objToString(args.fillObj(args.condition.data)) + " <= " + objToString(args.fillObj(args.condition.args.get(0))); } else if (args.condition.type == ConditionTypes.like) { StringBuilder sb = new StringBuilder(); sb.append(objToString(args.fillObj(args.condition.data))); sb.append(" LIKE "); boolean isFirst = true; for (Object o : args.condition.args) { if (isFirst) { isFirst = false; } else { sb.append(" + "); } sb.append(objToString(args.fillObj(o))); } return sb.toString(); } else if (args.condition.type == ConditionTypes.lt) { return objToString(args.fillObj(args.condition.data)) + " < " + objToString(args.fillObj(args.condition.args.get(0))); } else if (args.condition.type == ConditionTypes.member) { return objToString(args.fillObj(args.condition.data)) + " MEMBER " + objToString(args.fillObj(args.condition.args.get(0))); } else if (args.condition.type == ConditionTypes.ne) { return objToString(args.fillObj(args.condition.data)) + " <> " + objToString(args.fillObj(args.condition.args.get(0))); } else if (args.condition.type == ConditionTypes.notIn) { Args a = args.prepareForSubQuery((PreResult) args.condition.args.get(0)); String subQuery = generateSelect(a, false); args.aliasMap.setAliasCount(a.aliasMap.getAliasCount()); return objToString(args.fillObj(args.condition.data)) + " NOT IN (" + subQuery + ")"; } else if (args.condition.type == ConditionTypes.notMember) { return objToString(args.fillObj(args.condition.data)) + " NOT MEMBER " + objToString(args.fillObj(args.condition.args.get(0))); } else if (args.condition.type == ConditionTypes.reverseMember) { return objToString(args.fillObj(args.condition.args.get(0))) + " MEMBER " + objToString(args.fillObj(args.condition.data)); } else if (args.condition.type == ConditionTypes.reverseNotMember) { return objToString(args.fillObj(args.condition.args.get(0))) + " NOT MEMBER " + objToString(args.fillObj(args.condition.data)); } else { throw new UnsupportedOperationException(args.condition.type + " not supported"); } } /** * 生成where子句
* 若给定where为 And 类型,对每一个分支递归执行本方法,并用and连接 * 若给定where为 Or 类型,对每一个分支递归执行本方法,并用or连接 * 若给定where为 Condition 类型,则调用generateCondition * 若给定where为 IExpression 类型,则调用generateExpression * * @param args Args对象 * @param having 向args中添加having项 * @return where子句内容(不包括where这个词) */ private String generateWhere(Args args, boolean having) { StringBuilder sb = new StringBuilder(); boolean isFirst = true; if (args.whereClause.isAnd()) { if (having) { Where Optionalhaving = DataUtils.getAggregate(args.whereClause); if (Optionalhaving != null) args.aggregateFunctions = generateWhere(args.fillWhere(Optionalhaving), false); if (Optionalhaving == null) having = false; } for (Or or : ((And) args.whereClause).getOrList()) { if (having && DataUtils.getAggregate(or) != null) continue; if (isFirst) { isFirst = false; } else { sb.append(" AND "); } sb.append("(").append(generateWhere(args.fillWhere(or), false)).append(")"); } for (Condition condition : ((And) args.whereClause).getConditionList()) { if (having && DataUtils.getAggregate(condition) != null) continue; if (isFirst) { isFirst = false; } else { sb.append(" AND "); } sb.append(generateWhere(args.fillWhere(condition), false)); } for (ExpressionBoolean expBool : ((And) args.whereClause).getExpBoolList()) { if (having && DataUtils.getAggregate(expBool) != null) continue; if (isFirst) { isFirst = false; } else { sb.append(" AND "); } sb.append(generateWhere(args.fillWhere(expBool), false)); } } else if (args.whereClause.isOr()) { for (And and : ((Or) args.whereClause).getAndList()) { if (isFirst) { isFirst = false; } else { sb.append(" OR "); } sb.append(generateWhere(args.fillWhere(and), false)); } for (Condition condition : ((Or) args.whereClause).getConditionList()) { if (isFirst) { isFirst = false; } else { sb.append(" OR "); } sb.append(generateWhere(args.fillWhere(condition), false)); } for (ExpressionBoolean expBool : ((Or) args.whereClause).getExpBoolList()) { if (isFirst) { isFirst = false; } else { sb.append(" OR "); } sb.append(generateWhere(args.fillWhere(expBool), false)); } } else if (args.whereClause.isCondition()) { sb.append(generateCondition(args.fillCondition((Condition) args.whereClause))); } else if (args.whereClause.isExpression()) { sb.append(generateExpression(args.fillExp((IExpression) args.whereClause))); } return sb.toString(); } /** * 生成join子句
* 根据args.toJoin生成 * * @param args Args对象 * @return join子句内容 */ private String generateJoin(Args args) { StringBuilder sb = new StringBuilder(); for (Location joinLocation : args.toJoin.keySet()) { sb.append(" JOIN "); if (joinLocation.getLocation().size() == 1) { sb.append(args.aliasMap.get(new Location(null))).append("."); } sb.append(joinLocation.toString()).append(" ").append(args.toJoin.get(joinLocation)); } return sb.toString(); } /** * 生成join和where子句
* 单个Expression或者And的第二个语句可能是having子句 * 调用generateWhere和generateJoin * * @param args Args对象 */ private void generateJoinWhere(Args args) { if (args.whereClause != null) { if (args.whereClause instanceof IExpression && DataUtils.expressionIsAggregate((IExpression) args.whereClause)) { args.aggregateFunctions = generateWhere(args, false); args.sb.append(generateJoin(args)); } else if (args.whereClause instanceof Condition && null != DataUtils.getAggregate(args.whereClause)) { args.aggregateFunctions = generateWhere(args, false); args.sb.append(generateJoin(args)); } else { String where = " WHERE " + generateWhere(args, true); args.sb.append(generateJoin(args)).append(where); } } else if (args.toJoin.size() != 0) { args.sb.append(generateJoin(args)); } } /** * 生成group by和having子句 * * @param args Args对象 */ private void generateGroupByHaving(Args args) { if (args.aggregateFunctions != null || (args.doGroupBy && args.selectNonAggregationAliases.size() != 0)) { args.sb.append(" GROUP BY "); boolean isFirst = true; for (String s : args.selectNonAggregationAliases) { if (isFirst) { isFirst = false; } else { args.sb.append(", "); } args.sb.append(s); } } if (args.aggregateFunctions != null) { args.sb.append(" HAVING ").append(args.aggregateFunctions); } } /** * 生成select语句
*
    *
  • 根据传入的queryParameter确定是否查询部分字段,调用DataUtils.findFieldNameByIData
  • *
  • 根据entity类型生成from子句
  • *
  • 调用generateJoinWhere生成join和where子句
  • *
  • 调用generateGroupByHaving生成groupby和having子句
  • *
  • 根据传入的queryParameter生成末尾的语句,例如order by
  • *
* * @param args Args对象 * @return 生成的语句 */ private String generateSelect(Args args, boolean isProjection) { if (args.queryParameter != null && args.queryParameter.parameters.containsKey(QueryParameterTypes.distinct)) { args.notDistinctOrAlreadyDone = false; } args.generatingSelect = true; String entityAlias = args.aliasMap.get(new Location(new ArrayList(0))); args.sb.append("SELECT "); if (isProjection) { // generate focus if (args.queryParameter == null || !(args.queryParameter instanceof QueryParameterWithFocus) || ((QueryParameterWithFocus) args.queryParameter).focusMap.size() == 0) { args.queryParameter = new QueryParameterWithFocus(args.queryParameter, null); QueryParameterWithFocus qpwf = (QueryParameterWithFocus) args.queryParameter; try { for (Field f : args.entityClass.getFields()) { if (IData.class.isAssignableFrom(f.getType()) && !ParameterAggregate.class.isAssignableFrom(f.getType())) { qpwf.focus((IData) f.get(args.entity)); } } } catch (Exception e) { throw new RuntimeException(e); } } boolean isFirst = true; for (Selectable o : ((QueryParameterWithFocus) args.queryParameter).focusMap.keySet()) { if (isFirst) { isFirst = false; } else { args.sb.append(", "); } if (o instanceof IData) { IData d = (IData) o; if (d.getEntity() == args.entity) { String alias = entityAlias + "." + DataUtils.findFieldNameByIData(d); if (!args.notDistinctOrAlreadyDone) { args.sb.append("DISTINCT "); args.notDistinctOrAlreadyDone = true; } args.sb.append(alias); args.selectNonAggregationAliases.add(alias); } else { Location loc = findEntity(d.getEntity(), args); String alias = args.aliasMap.get(loc) + "." + DataUtils.findFieldNameByIData(d); if (!args.notDistinctOrAlreadyDone) { args.sb.append("DISTINCT "); args.notDistinctOrAlreadyDone = true; } args.sb.append(alias); args.selectNonAggregationAliases.add(alias); args.toJoin.put(loc, args.aliasMap.get(loc)); } } else if (o instanceof IExpression) { args.sb.append(generateExpression(args.fillExp((IExpression) o))); if (DataUtils.expressionIsAggregate((IExpression) o)) { args.doGroupBy = true; } else { // analyse IData IExpression exp = (IExpression) o; Object[] objs = exp.expArgs(); for (Object obj : objs) { if (obj instanceof IData) { Location location = findEntity(((IData) obj).getEntity(), args); List locList = location.getLocation(); locList.add(DataUtils.findFieldNameByIData((IData) obj)); Location loc = DataUtils.generateLocationAndFillMap(locList, args.aliasMap); args.selectNonAggregationAliases.add(args.aliasMap.get(loc)); } } } } } } else { if (!args.notDistinctOrAlreadyDone) { args.sb.append("DISTINCT "); args.notDistinctOrAlreadyDone = true; } args.sb.append(entityAlias); args.selectNonAggregationAliases.add(entityAlias); } args.generatingSelect = false; args.sb.append(" FROM ").append(args.entityClass.getSimpleName()).append(" ").append(entityAlias); generateJoinWhere(args); // where generateGroupByHaving(args); // group by having if (args.queryParameter != null) { for (QueryParameterTypes type : args.queryParameter.parameters.keySet()) { Object[] argsArr = args.queryParameter.parameters.get(type); if (type == QueryParameterTypes.orderBy) { args.sb.append(" ORDER BY "); for (Object o : argsArr) { OrderBase order = (OrderBase) o; Location loc = findEntity(order.data.getEntity(), args); Field f = DataUtils.findFieldByContainedEntity(order.data.getEntity(), args.entity); args.sb.append(args.aliasMap.get(loc)).append(".").append(f.getName()); } } else if (type != QueryParameterTypes.limit && type != QueryParameterTypes.top && type != QueryParameterTypes.distinct) { throw new UnsupportedOperationException(type + " not supported"); } } } return args.sb.toString(); } /** * 向Query填入额外信息,例如limit,top,以及填入需要填写的常量
* 调用setConstants * * @param query Query对象 * @param parameter 查询信息 * @param constantMap 常量Map * @see JPQLDataAccess#setConstants(Query, Map) */ private void setParametersToQuery(Query query, QueryParameter parameter, ConstantMap constantMap) { if (parameter != null) { for (QueryParameterTypes type : parameter.parameters.keySet()) { Object[] args = parameter.parameters.get(type); if (type == QueryParameterTypes.limit) { query.setFirstResult((Integer) args[0]).setMaxResults(((Integer) args[1]) - ((Integer) args[0]) + 1); } else if (type == QueryParameterTypes.top) { query.setMaxResults((Integer) args[0]); } else if (type != QueryParameterTypes.orderBy && type != QueryParameterTypes.distinct) { throw new UnsupportedOperationException(type + " not supported"); } } } setConstants(query, constantMap); } /** * 向Query填入常量 * * @param query Query对象 * @param constantMap 常量Map */ private void setConstants(Query query, Map constantMap) { for (Integer i : constantMap.keySet()) { query.setParameter(i, constantMap.get(i)); } } /** * 初始化Args对象
* 初始化args.sb/entity/entityClass/entityAlias/whereClause/queryParameter/aliasMap/constantMap/toJoin * * @param args 要初始化的Args对象 * @param entity 目标实体 * @param whereClause 条件 * @param parameter 查询参数 */ private void initArgs(Args args, Object entity, Where whereClause, QueryParameter parameter) { args.sb = new StringBuilder(); args.entity = entity; args.entityClass = entity.getClass(); args.whereClause = whereClause; args.queryParameter = parameter; args.aliasMap = new AliasMap(aliasPrefix); args.constantMap = new ConstantMap(); args.toJoin = new LinkedHashMap(); args.selectNonAggregationAliases = new ArrayList(); } @Override public En find(Class entityClass, Object pkValue) { return entityManager.find(entityClass, pkValue); } /** * 执行查询,注入实体并返回结果List
* 调用initArgs,generateSelect,[createQuery],setParametersToQuery * * @param entity 要查询的实体 * @param whereClause 查询条件 * @param parameter 查询参数(可以为空) * @param 实体类型 * @return 查询的实体结果List * @see JPQLDataAccess#initArgs(Args, Object, Where, QueryParameter) * @see JPQLDataAccess#generateSelect(Args, boolean) * @see EntityManager#createQuery(String) * @see JPQLDataAccess#setParametersToQuery(Query, QueryParameter, ConstantMap) */ @SuppressWarnings("unchecked") @Override public List list(En entity, Where whereClause, QueryParameter parameter) { Args args = new Args(); initArgs(args, entity, whereClause, parameter); String selectQuery = generateSelect(args, false); logger.debug("Generated JPQL Query is : {} ---- WITH PARAMETERS : {}", selectQuery, args.constantMap); javax.persistence.Query query = entityManager.createQuery(selectQuery); setParametersToQuery(query, parameter, args.constantMap); return (List) query.getResultList(); } /** * 检查parameter,若为空则返回一个"查询所有非Iterable字段"的parameter.若不为空则直接返回 * * @param entity 要查询的实体 * @param parameter 查询参数 * @return 非空的parameter */ private QueryParameterWithFocus validateQueryParameterWithFocus(Object entity, QueryParameterWithFocus parameter) { if (parameter == null) { try { Focus focus = new Focus(); for (Field f : entity.getClass().getFields()) { if (IData.class.isAssignableFrom(f.getType()) && !ParameterAggregate.class.isAssignableFrom(f.getType())) { focus.focus((IData) f.get(entity)); } } parameter = new QueryParameterWithFocus(null, focus); } catch (Exception e) { throw new RuntimeException(e); } } return parameter; } /** * 查询部分字段的查询的初始化 * * @param args Args对象 * @param entity 要查询实体 * @param whereClause 查询条件 * @param parameter 查询参数 * @return 生成的查询语句 */ private String mapInit(Args args, Object entity, Where whereClause, QueryParameterWithFocus parameter) { initArgs(args, entity, whereClause, parameter); return generateSelect(args, true); } /** * 将JPA返回的List<Object[]>转化为List<Map<字段名,对象>> * * @param resultList JPA返回List * @param parameter 查询参数 * @return 转换后的List<Map> */ private List> listToMap(List resultList, QueryParameterWithFocus parameter) { List> list = new ArrayList>(resultList.size()); for (Object res : resultList) { Map map = new LinkedHashMap(); if (res.getClass().isArray()) { int i = 0; for (String alias : parameter.focusMap.values()) { map.put(alias, ((Object[]) res)[i]); ++i; } } else { map.put(parameter.focusMap.values().iterator().next(), res); } list.add(map); } return list; } /** * 执行查询,生成List<Map<字段名,对象>>形式的结果
* 调用validateQueryParameterWithFocus,mapInit,[createQuery],setParametersToQuery * * @param entity 要查询的实体 * @param whereClause 条件 * @param parameter 要查询的字段以及查询参数(可以为空,若空则查询所有非Iterable的字段) * @return 查询的Map结果 * @see JPQLDataAccess#validateQueryParameterWithFocus(Object, QueryParameterWithFocus) * @see JPQLDataAccess#mapInit(Args, Object, Where, QueryParameterWithFocus) * @see EntityManager#createQuery(String) * @see JPQLDataAccess#setParametersToQuery(Query, QueryParameter, ConstantMap) */ @SuppressWarnings("unchecked") @Override public List> projection(Object entity, Where whereClause, QueryParameterWithFocus parameter) { Args args = new Args(); parameter = validateQueryParameterWithFocus(entity, parameter); String selectQuery = mapInit(args, entity, whereClause, parameter); logger.debug("Generated JPQL Query is : {} ---- WITH PARAMETERS : {}", selectQuery, args.constantMap); javax.persistence.Query query = entityManager.createQuery(selectQuery); setParametersToQuery(query, parameter, args.constantMap); return listToMap(query.getResultList(), (QueryParameterWithFocus) args.queryParameter); } /** * 初始化更新
* 在args.sb中生成完整Update语句 * * @param args Args对象 * @param entity 要更新实体 * @param whereClause 更新条件 * @param entries 更新内容 */ private void updateInit(Args args, Object entity, Where whereClause, UpdateEntry[] entries) { initArgs(args, entity, whereClause, null); args.sb.append("UPDATE ").append(entity.getClass().getSimpleName()).append(" ").append(args.aliasMap.get(new Location(null))).append(" SET "); boolean isFirst = true; for (UpdateEntry entry : entries) { if (isFirst) { isFirst = false; } else { args.sb.append(", "); } args.sb.append(DataUtils.findFieldNameByIData(entry.data)).append(" = ").append(objToString(args.fillObj(entry.updateValue))); } if (args.whereClause != null) { args.sb.append(" WHERE ").append(generateWhere(args, false)); } } /** * 更新
* 调用updateInit,setConstants * * @param entity 要更新的实体 * @param whereClause 更新条件 * @param entries 更新内容(set) * @see JPQLDataAccess#updateInit(Args, Object, Where, UpdateEntry[]) * @see JPQLDataAccess#setConstants(Query, Map) */ @Override public void update(Object entity, Where whereClause, UpdateEntry[] entries) { Args args = new Args(); updateInit(args, entity, whereClause, entries); logger.debug("Generated JPQL Query is : {} ---- WITH PARAMETERS {}", args.sb.toString(), args.constantMap); Query query = entityManager.createQuery(args.sb.toString()); setConstants(query, args.constantMap); query.executeUpdate(); } /** * 删除初始化
* 生成完整Delete语句 * * @param args Args对象 * @param entity 删除实体 * @param whereClause 删除条件 */ private void removeInit(Args args, Object entity, Where whereClause) { initArgs(args, entity, whereClause, null); args.sb.append("DELETE FROM ").append(entity.getClass().getSimpleName()).append(" ").append(args.aliasMap.get(new Location(null))); if (args.whereClause != null) { args.sb.append(" WHERE ").append(generateWhere(args, false)); } } /** * 删除
* 调用removeInit,setConstants * * @param entity 要删除实体 * @param whereClause 删除条件 * @see JPQLDataAccess#removeInit(Args, Object, Where) * @see JPQLDataAccess#setConstants(Query, Map) */ @Override public void remove(Object entity, Where whereClause) { Args args = new Args(); removeInit(args, entity, whereClause); logger.debug("Generated JPQL Query is : {} ---- WITH PARAMETERS {}", args.sb.toString(), args.constantMap); Query query = entityManager.createQuery(args.sb.toString()); setConstants(query, args.constantMap); query.executeUpdate(); } @Override public void save(Object[] entities) { for (Object e : entities) { entityManager.persist(e); } } @Override public void txBegin() { tx = entityManager.getTransaction(); tx.begin(); } @Override public void txCommit() { tx.commit(); } @Override public void txRollback() { tx.rollback(); } @Override public void destroy() { entityManager.close(); } }