This commit is contained in:
wentch
2016-01-26 11:22:01 +08:00
parent 4a9958f106
commit c9f319a3df
6 changed files with 121 additions and 10 deletions

View File

@@ -71,6 +71,8 @@ public final class DataDefaultSource implements DataSource, Function<Class, Enti
@Resource(name = "$")
private DataCacheListener cacheListener;
private final Properties props = new Properties();
private final Function<Class, List> fullloader = (t) -> querySheet(false, false, t, null, null, (FilterNode) null).list(true);
public DataDefaultSource() throws IOException {
@@ -119,6 +121,14 @@ public final class DataDefaultSource implements DataSource, Function<Class, Enti
this.readPool = new JDBCPoolSource(this, "read", readprop);
this.writePool = new JDBCPoolSource(this, "write", writeprop);
this.mysql = this.writePool.isMysql();
if (this.readPool.isOracle()) {
this.props.setProperty("contain-sql-template", "INSTR(${keystr}, ${column}) > 0");
this.props.setProperty("notcontain-sql-template", "INSTR(${keystr}, ${column}) = 0");
} else if (this.readPool.isSqlserver()) {
this.props.setProperty("contain-sql-template", "CHARINDEX(${column}, ${keystr}) > 0");
this.props.setProperty("notcontain-sql-template", "CHARINDEX(${column}, ${keystr}) = 0");
}
this.props.putAll(readprop);
this.cacheForbidden = "NONE".equalsIgnoreCase(readprop.getProperty("shared-cache-mode"));
}
@@ -128,6 +138,14 @@ public final class DataDefaultSource implements DataSource, Function<Class, Enti
this.readPool = new JDBCPoolSource(this, "read", readprop);
this.writePool = new JDBCPoolSource(this, "write", writeprop);
this.mysql = this.writePool.isMysql();
if (this.readPool.isOracle()) {
this.props.setProperty("contain-sql-template", "INSTR(${keystr}, ${column}) > 0");
this.props.setProperty("notcontain-sql-template", "INSTR(${keystr}, ${column}) = 0");
} else if (this.readPool.isSqlserver()) {
this.props.setProperty("contain-sql-template", "CHARINDEX(${column}, ${keystr}) > 0");
this.props.setProperty("notcontain-sql-template", "CHARINDEX(${column}, ${keystr}) = 0");
}
this.props.putAll(readprop);
this.cacheForbidden = "NONE".equalsIgnoreCase(readprop.getProperty("shared-cache-mode"));
}
@@ -288,7 +306,7 @@ public final class DataDefaultSource implements DataSource, Function<Class, Enti
}
private <T> EntityInfo<T> loadEntityInfo(Class<T> clazz) {
return EntityInfo.load(clazz, this.nodeid, this.cacheForbidden, fullloader);
return EntityInfo.load(clazz, this.nodeid, this.cacheForbidden, this.props, fullloader);
}
/**

View File

@@ -57,6 +57,10 @@ public final class EntityInfo<T> {
private final Map<String, Attribute<T, Serializable>> updateAttributeMap = new HashMap<>();
final String containSQL; //用于反向LIKE使用
final String notcontainSQL; //用于反向LIKE使用
final String querySQL;
private final Attribute<T, Serializable>[] queryAttributes; //数据库中所有字段
@@ -91,7 +95,7 @@ public final class EntityInfo<T> {
final int allocationSize;
//------------------------------------------------------------
public static <T> EntityInfo<T> load(Class<T> clazz, final int nodeid, final boolean cacheForbidden,
public static <T> EntityInfo<T> load(Class<T> clazz, final int nodeid, final boolean cacheForbidden, final Properties conf,
Function<Class, List> fullloader) {
EntityInfo rs = entityInfos.get(clazz);
if (rs != null) return rs;
@@ -99,7 +103,7 @@ public final class EntityInfo<T> {
rs = entityInfos.get(clazz);
if (rs == null) {
if (nodeid < 0) throw new IllegalArgumentException("nodeid(" + nodeid + ") is illegal");
rs = new EntityInfo(clazz, nodeid, cacheForbidden);
rs = new EntityInfo(clazz, nodeid, cacheForbidden, conf);
entityInfos.put(clazz, rs);
AutoLoad auto = clazz.getAnnotation(AutoLoad.class);
if (rs.cache != null && auto != null && auto.value()) {
@@ -115,7 +119,7 @@ public final class EntityInfo<T> {
return entityInfos.get(clazz);
}
private EntityInfo(Class<T> type, int nodeid, final boolean cacheForbidden) {
private EntityInfo(Class<T> type, int nodeid, final boolean cacheForbidden, Properties conf) {
this.type = type;
//---------------------------------------------
this.nodeid = nodeid >= 0 ? nodeid : 0;
@@ -239,6 +243,9 @@ public final class EntityInfo<T> {
} else {
this.cache = null;
}
if (conf == null) conf = new Properties();
this.containSQL = conf.getProperty("contain-sql-template", "LOCATE(${keystr}, ${column}) > 0");
this.notcontainSQL = conf.getProperty("notcontain-sql-template", "LOCATE(${keystr}, ${column}) = 0");
}
public void createPrimaryValue(T src) {

View File

@@ -7,7 +7,9 @@ package org.redkale.source;
/**
*
* <p> 详情见: http://www.redkale.org
* <p>
* 详情见: http://www.redkale.org
*
* @author zhangjx
*/
public enum FilterExpress {
@@ -18,10 +20,17 @@ public enum FilterExpress {
LESSTHAN("<"),
GREATERTHANOREQUALTO(">="),
LESSTHANOREQUALTO("<="),
LIKE("LIKE"),
NOTLIKE("NOT LIKE"),
IGNORECASELIKE("LIKE"), //不区分大小写的 LIKE
IGNORECASELIKE("LIKE"), //不区分大小写的 LIKE
IGNORECASENOTLIKE("NOT LIKE"), //不区分大小写的 NOT LIKE
CONTAIN("CONTAIN"), //包含, 相当于反向LIKE
NOTCONTAIN("NOT CONTAIN"), //不包含, 相当于反向LIKE
IGNORECASECONTAIN("CONTAIN"), //不区分大小写的 CONTAIN
IGNORECASENOTCONTAIN("NOT CONTAIN"), //不区分大小写的 NOT CONTAIN
BETWEEN("BETWEEN"),
NOTBETWEEN("NOT BETWEEN"),
IN("IN"),

View File

@@ -217,9 +217,14 @@ public class FilterNode {
if (express == ISNULL || express == ISNOTNULL) {
return new StringBuilder().append(info.getSQLColumn(talis, column)).append(' ').append(express.value());
}
final CharSequence val = formatToString(express, getValue());
CharSequence val = formatToString(express, getValue());
if (val == null) return null;
StringBuilder sb = new StringBuilder(32);
if (express == CONTAIN) return info.containSQL.replace("${column}", info.getSQLColumn(talis, column)).replace("${keystr}", val);
if (express == IGNORECASECONTAIN) return info.containSQL.replace("${column}", "LOWER(" + info.getSQLColumn(talis, column) + ")").replace("${keystr}", val);
if (express == NOTCONTAIN) return info.notcontainSQL.replace("${column}", info.getSQLColumn(talis, column)).replace("${keystr}", val);
if (express == IGNORECASENOTCONTAIN) return info.notcontainSQL.replace("${column}", "LOWER(" + info.getSQLColumn(talis, column) + ")").replace("${keystr}", val);
if (express == IGNORECASELIKE || express == IGNORECASENOTLIKE) {
sb.append("LOWER(").append(info.getSQLColumn(talis, column)).append(')');
} else {
@@ -594,6 +599,64 @@ public class FilterNode {
return "LOWER(" + field + ") " + express.value() + ' ' + formatToString(valstr2);
}
};
case CONTAIN:
return new Predicate<T>() {
@Override
public boolean test(T t) {
Object rs = attr.get(t);
return rs != null && val.toString().contains(rs.toString());
}
@Override
public String toString() {
return "" + formatToString(val) + ' ' + express.value() + ' ' + field;
}
};
case IGNORECASECONTAIN:
final String valstr3 = val.toString().toLowerCase();
return new Predicate<T>() {
@Override
public boolean test(T t) {
Object rs = attr.get(t);
return rs != null && valstr3.contains(rs.toString().toLowerCase());
}
@Override
public String toString() {
return "" + formatToString(valstr3) + express.value() + ' ' + "LOWER(" + field + ") ";
}
};
case NOTCONTAIN:
return new Predicate<T>() {
@Override
public boolean test(T t) {
Object rs = attr.get(t);
return rs == null || !val.toString().contains(rs.toString());
}
@Override
public String toString() {
return "" + formatToString(val) + ' ' + express.value() + ' ' + field;
}
};
case IGNORECASENOTCONTAIN:
final String valstr4 = val.toString().toLowerCase();
return new Predicate<T>() {
@Override
public boolean test(T t) {
Object rs = attr.get(t);
return rs == null || !valstr4.contains(rs.toString().toLowerCase());
}
@Override
public String toString() {
return "" + formatToString(valstr4) + express.value() + ' ' + "LOWER(" + field + ") ";
}
};
case BETWEEN:
case NOTBETWEEN:
Range range = (Range) val;
@@ -844,7 +907,8 @@ public class FilterNode {
if (express == ISNULL || express == ISNOTNULL) {
sb.append(col).append(' ').append(express.value());
} else if (ev != null) {
sb.append((express == IGNORECASELIKE || express == IGNORECASENOTLIKE) ? ("LOWER(" + col + ')') : col).append(' ').append(express.value()).append(' ').append(formatToString(express, ev));
boolean lower = (express == IGNORECASELIKE || express == IGNORECASENOTLIKE || express == IGNORECASECONTAIN || express == IGNORECASENOTCONTAIN);
sb.append(lower ? ("LOWER(" + col + ')') : col).append(' ').append(express.value()).append(' ').append(formatToString(express, ev));
}
}
return sb;
@@ -863,6 +927,8 @@ public class FilterNode {
value = "%" + value + '%';
} else if (express == IGNORECASELIKE || express == IGNORECASENOTLIKE) {
value = "%" + value.toString().toLowerCase() + '%';
} else if (express == IGNORECASECONTAIN || express == IGNORECASENOTCONTAIN) {
value = value.toString().toLowerCase();
}
return new StringBuilder().append('\'').append(value.toString().replace("'", "\\'")).append('\'');
} else if (value instanceof Range) {

View File

@@ -347,7 +347,8 @@ public final class FilterNodeBean<T> implements Comparable<FilterNodeBean<T>> {
if (express == ISNULL || express == ISNOTNULL) {
sb.append(col).append(' ').append(express.value());
} else {
sb.append((express == IGNORECASELIKE || express == IGNORECASENOTLIKE) ? ("LOWER(" + col + ')') : col).append(' ').append(express.value()).append(" ?");
boolean lower = (express == IGNORECASELIKE || express == IGNORECASENOTLIKE || express == IGNORECASECONTAIN || express == IGNORECASENOTCONTAIN);
sb.append(lower ? ("LOWER(" + col + ')') : col).append(' ').append(express.value()).append(" ?");
}
}
return sb;

View File

@@ -20,7 +20,9 @@ import javax.sql.*;
/**
*
* <p> 详情见: http://www.redkale.org
* <p>
* 详情见: http://www.redkale.org
*
* @author zhangjx
*/
public class JDBCPoolSource {
@@ -88,6 +90,14 @@ public class JDBCPoolSource {
return source != null && source.getClass().getName().contains(".mysql.");
}
public boolean isOracle() {
return source != null && source.getClass().getName().contains("oracle.");
}
public boolean isSqlserver() {
return source != null && source.getClass().getName().contains(".sqlserver.");
}
private void watch() throws IOException {
if (dataSource.conf == null || dataSource.name == null) return;
final String file = dataSource.conf.getFile();