📄 tableengine.java
字号:
package org.opencustomer.framework.db.util.engine;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.opencustomer.framework.db.HibernateContext;
import org.opencustomer.framework.db.util.Page;
import org.opencustomer.framework.db.util.engine.Order.OrderColumn;
import org.opencustomer.framework.db.util.engine.configuration.Configuration;
import org.opencustomer.framework.db.util.engine.configuration.Join;
import org.opencustomer.framework.db.util.engine.configuration.Property;
public final class TableEngine implements Cloneable {
private final static Logger log = Logger.getLogger(TableEngine.class);
private final static String ALIAS_PATTERN = "[^[\\p{Alnum}\\.]]*\\p{Alnum}+\\.+\\p{Alnum}+[^[\\p{Alnum}\\.]]*";
private Configuration configuration;
private String baseHql;
public TableEngine(Configuration configuration) {
this.configuration = configuration;
this.baseHql = createBaseHQL();
}
public void optimizeQuery() {
if(log.isDebugEnabled())
log.debug("optimize query for table engine");
HashSet<String> aliases = new HashSet<String>();
Pattern pattern = Pattern.compile(ALIAS_PATTERN);
for(Property property : configuration.getProperties()) {
Matcher matcher = pattern.matcher(property.getName());
while(matcher.find()) {
String name = property.getName().substring(matcher.start(), matcher.end());
aliases.add(name.substring(0, name.indexOf(".")));
}
if(property.getAltName() != null) {
Matcher matcher2 = pattern.matcher(property.getAltName());
while(matcher2.find()) {
String name = property.getAltName().substring(matcher2.start(), matcher2.end());
aliases.add(name.substring(0, name.indexOf(".")));
}
}
}
baseHql = createBaseHQL(aliases);
}
public Configuration getConfiguration() {
return configuration;
}
public List<Row> getList() {
return getList(null, null, null);
}
public List<Row> getList(Order order) {
return getList(null, null, order);
}
public List<Row> getList(Page page) {
return getList(null, page, null);
}
public List<Row> getList(Restriction[] restrictions, Page page, Order order) {
StringBuilder hql = new StringBuilder();
hql.append(" select ");
hql.append(configuration.getId().getName());
for(Property property : configuration.getProperties()) {
String column = property.getName();
if(property.getAltName() != null) {
column = "case when "+property.getName()+" is not null then "+property.getName()+" else "+property.getAltName()+" end ";
}
if(property.getAlias() != null)
column += " as "+property.getAlias();
hql.append(", ").append(column);
}
hql.append(baseHql);
addRestrictionsToHql(hql, restrictions);
addGroupToHql(hql, configuration.getGroupProperties());
addHavingToHql(hql, restrictions);
if(order != null) {
hql.append(" order by ");
boolean isFirst = true;
for(OrderColumn orderColumn : order.getOrderColumns()) {
if(isFirst) {
isFirst = false;
} else {
hql.append(", ");
}
hql.append((orderColumn.getColumn()+2));
if(orderColumn.isAscending()) {
hql.append(" asc");
} else {
hql.append(" desc");
}
}
}
Query query = HibernateContext.getSession().createQuery(hql.toString());
addRestrictionsToQuery(query, restrictions);
if (page != null) {
query.setFirstResult((int)((page.getPage() - 1) * page.getStep()));
query.setMaxResults((int)page.getStep());
}
List<Object[]> result = (List<Object[]>)query.list();
List<Row> rows = new ArrayList<Row>();
for(Object[] values : result) {
Row row = new Row();
row.setId((Integer)values[0]);
Object[] columns = new Object[values.length-1];
for(int i=1; i<values.length; i++) {
columns[i-1] = values[i];
}
row.setColumns(columns);
rows.add(row);
}
return rows;
}
public Long getCount() {
return this.getCount(null);
}
public Long getCount(Restriction[] restrictions) {
StringBuilder hql = new StringBuilder();
hql.append(" select count(").append(configuration.getId().getName()).append(")");
hql.append(baseHql);
addRestrictionsToHql(hql, restrictions);
addGroupToHql(hql, configuration.getGroupProperties());
addHavingToHql(hql, restrictions);
Query query = HibernateContext.getSession().createQuery(hql.toString());
addRestrictionsToQuery(query, restrictions);
if(configuration.getGroupProperties().isEmpty() || configuration.getGroupProperties().size() == configuration.getProperties().size()) {
return (Long)query.uniqueResult();
} else {
return new Long(query.list().size());
}
}
private String createBaseHQL() {
return createBaseHQL(null);
}
/**
* Identifies aliases used by joins (e.g. help tables).
*
* @param aliases the available aliases
*/
private void identifyAliases(Set<String> aliases) {
boolean found = false;
if(aliases != null) {
for(Join join : configuration.getJoins()) {
if(aliases.contains(join.getAlias())) {
String usedAlias = join.getName().substring(0, join.getName().indexOf('.'));
if(!aliases.contains(usedAlias)) {
aliases.add(usedAlias);
found = true;
}
}
}
}
if(found) {
identifyAliases(aliases);
}
}
private String createBaseHQL(Set<String> aliases) {
StringBuilder hql = new StringBuilder();
identifyAliases(aliases);
hql.append(" FROM ").append(configuration.getEntity().getClazz().getName()).append(" e ");
for(Join join : configuration.getJoins()) {
if(aliases == null || aliases.contains(join.getAlias())) {
String table = join.getName();
if(join.getAlias() != null)
table += " "+join.getAlias();
if(Join.Type.LEFT_JOIN.equals(join.getType()))
hql.append(" left join ").append(table);
}
}
hql.append(" WHERE 1=1 ");
if(aliases == null) {
for(String restriction : configuration.getRestrictions()) {
hql.append(" and ").append(restriction);
}
} else {
Pattern pattern = Pattern.compile(ALIAS_PATTERN);
for(String restriction : configuration.getRestrictions()) {
boolean valid = true;
Matcher matcher = pattern.matcher(restriction);
while(matcher.find()) {
String name = restriction.substring(matcher.start(), matcher.end());
String alias = name.substring(0, name.indexOf("."));
if(!aliases.contains(alias)) {
valid = false;
}
}
if(valid) {
hql.append(" and ").append(restriction);
}
}
}
return hql.toString();
}
private void addRestrictionsToHql(StringBuilder hql, Restriction[] restrictions) {
if(restrictions != null) {
boolean isGrouped = !configuration.getGroupProperties().isEmpty();
for(int i=0; i<restrictions.length; i++) {
if(!isGrouped || (isGrouped && restrictions[i].isGroup())) {
hql.append(" and "+replaceParams(restrictions[i].getHql(), i));
}
}
}
}
private void addHavingToHql(StringBuilder hql, Restriction[] restrictions) {
if(restrictions != null) {
boolean isGrouped = !configuration.getGroupProperties().isEmpty();
if(isGrouped) {
boolean havingNeeded = false;
for(Restriction restriction : restrictions) {
if(!restriction.isGroup()) {
havingNeeded = true;
break;
}
}
if(havingNeeded) {
hql.append(" having ");
boolean isFirst = true;
for(int i=0; i<restrictions.length; i++) {
if(!restrictions[i].isGroup()) {
if(isFirst) {
isFirst = false;
} else {
hql.append(" and ");
}
hql.append(replaceParams(restrictions[i].getHql(), i));
}
}
}
}
}
}
private void addRestrictionsToQuery(Query query, Restriction[] restrictions) {
if(restrictions != null) {
Pattern pattern = Pattern.compile("\\{\\d\\}");
for(int i=0; i<restrictions.length; i++) {
Matcher matcher = pattern.matcher(restrictions[i].getHql());
while(matcher.find()) {
String match = restrictions[i].getHql().substring(matcher.start(), matcher.end());
String param = replaceParams(match, i).substring(1);
int pos = Integer.parseInt(match.substring(1, match.length()-1));
query.setParameter(param, restrictions[i].getValues()[pos]);
}
}
}
}
private void addGroupToHql(StringBuilder hql, List<Property> groupProperties) {
if(!groupProperties.isEmpty() && groupProperties.size() != configuration.getProperties().size()) {
hql.append(" group by ");
boolean isFirst = true;
for(Property property : groupProperties) {
if(isFirst) {
isFirst = false;
} else {
hql.append(", ");
}
hql.append(property.getName());
}
}
}
private String replaceParams(String value, int pos) {
return value.replaceAll("\\{", ":param_"+pos+"_").replaceAll("\\}", "");
}
public static String decorate(Object[] array) {
ToStringBuilder builder = new ToStringBuilder(array);
for(int i=0; i<array.length; i++) {
builder.append(String.valueOf(i), array[i]);
}
return builder.toString();
}
@Override
public String toString() {
ToStringBuilder builder = new ToStringBuilder(this);
builder.append("configuration", configuration.getName());
return builder.toString();
}
@Override
public Object clone() {
try {
TableEngine engine = (TableEngine)super.clone();
engine.configuration = (Configuration)this.configuration.clone();
return engine;
} catch(CloneNotSupportedException e) {
throw new InternalError();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -