Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.cassite.daf4j.jpa.JPQLDataAccess Maven / Gradle / Ivy
Go to download
A library provides implementation of DAF4J DataAccess using JPA
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();
}
}