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 = "$") @Resource(name = "$")
private DataCacheListener cacheListener; 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); private final Function<Class, List> fullloader = (t) -> querySheet(false, false, t, null, null, (FilterNode) null).list(true);
public DataDefaultSource() throws IOException { 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.readPool = new JDBCPoolSource(this, "read", readprop);
this.writePool = new JDBCPoolSource(this, "write", writeprop); this.writePool = new JDBCPoolSource(this, "write", writeprop);
this.mysql = this.writePool.isMysql(); 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")); 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.readPool = new JDBCPoolSource(this, "read", readprop);
this.writePool = new JDBCPoolSource(this, "write", writeprop); this.writePool = new JDBCPoolSource(this, "write", writeprop);
this.mysql = this.writePool.isMysql(); 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")); 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) { 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<>(); private final Map<String, Attribute<T, Serializable>> updateAttributeMap = new HashMap<>();
final String containSQL; //用于反向LIKE使用
final String notcontainSQL; //用于反向LIKE使用
final String querySQL; final String querySQL;
private final Attribute<T, Serializable>[] queryAttributes; //数据库中所有字段 private final Attribute<T, Serializable>[] queryAttributes; //数据库中所有字段
@@ -91,7 +95,7 @@ public final class EntityInfo<T> {
final int allocationSize; 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) { Function<Class, List> fullloader) {
EntityInfo rs = entityInfos.get(clazz); EntityInfo rs = entityInfos.get(clazz);
if (rs != null) return rs; if (rs != null) return rs;
@@ -99,7 +103,7 @@ public final class EntityInfo<T> {
rs = entityInfos.get(clazz); rs = entityInfos.get(clazz);
if (rs == null) { if (rs == null) {
if (nodeid < 0) throw new IllegalArgumentException("nodeid(" + nodeid + ") is illegal"); 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); entityInfos.put(clazz, rs);
AutoLoad auto = clazz.getAnnotation(AutoLoad.class); AutoLoad auto = clazz.getAnnotation(AutoLoad.class);
if (rs.cache != null && auto != null && auto.value()) { if (rs.cache != null && auto != null && auto.value()) {
@@ -115,7 +119,7 @@ public final class EntityInfo<T> {
return entityInfos.get(clazz); 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.type = type;
//--------------------------------------------- //---------------------------------------------
this.nodeid = nodeid >= 0 ? nodeid : 0; this.nodeid = nodeid >= 0 ? nodeid : 0;
@@ -239,6 +243,9 @@ public final class EntityInfo<T> {
} else { } else {
this.cache = null; 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) { 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 * @author zhangjx
*/ */
public enum FilterExpress { public enum FilterExpress {
@@ -18,10 +20,17 @@ public enum FilterExpress {
LESSTHAN("<"), LESSTHAN("<"),
GREATERTHANOREQUALTO(">="), GREATERTHANOREQUALTO(">="),
LESSTHANOREQUALTO("<="), LESSTHANOREQUALTO("<="),
LIKE("LIKE"), LIKE("LIKE"),
NOTLIKE("NOT LIKE"), NOTLIKE("NOT LIKE"),
IGNORECASELIKE("LIKE"), //不区分大小写的 LIKE IGNORECASELIKE("LIKE"), //不区分大小写的 LIKE
IGNORECASENOTLIKE("NOT LIKE"), //不区分大小写的 NOT LIKE IGNORECASENOTLIKE("NOT LIKE"), //不区分大小写的 NOT LIKE
CONTAIN("CONTAIN"), //包含, 相当于反向LIKE
NOTCONTAIN("NOT CONTAIN"), //不包含, 相当于反向LIKE
IGNORECASECONTAIN("CONTAIN"), //不区分大小写的 CONTAIN
IGNORECASENOTCONTAIN("NOT CONTAIN"), //不区分大小写的 NOT CONTAIN
BETWEEN("BETWEEN"), BETWEEN("BETWEEN"),
NOTBETWEEN("NOT BETWEEN"), NOTBETWEEN("NOT BETWEEN"),
IN("IN"), IN("IN"),

View File

@@ -217,9 +217,14 @@ public class FilterNode {
if (express == ISNULL || express == ISNOTNULL) { if (express == ISNULL || express == ISNOTNULL) {
return new StringBuilder().append(info.getSQLColumn(talis, column)).append(' ').append(express.value()); 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; if (val == null) return null;
StringBuilder sb = new StringBuilder(32); 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) { if (express == IGNORECASELIKE || express == IGNORECASENOTLIKE) {
sb.append("LOWER(").append(info.getSQLColumn(talis, column)).append(')'); sb.append("LOWER(").append(info.getSQLColumn(talis, column)).append(')');
} else { } else {
@@ -594,6 +599,64 @@ public class FilterNode {
return "LOWER(" + field + ") " + express.value() + ' ' + formatToString(valstr2); 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 BETWEEN:
case NOTBETWEEN: case NOTBETWEEN:
Range range = (Range) val; Range range = (Range) val;
@@ -844,7 +907,8 @@ public class FilterNode {
if (express == ISNULL || express == ISNOTNULL) { if (express == ISNULL || express == ISNOTNULL) {
sb.append(col).append(' ').append(express.value()); sb.append(col).append(' ').append(express.value());
} else if (ev != null) { } 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; return sb;
@@ -863,6 +927,8 @@ public class FilterNode {
value = "%" + value + '%'; value = "%" + value + '%';
} else if (express == IGNORECASELIKE || express == IGNORECASENOTLIKE) { } else if (express == IGNORECASELIKE || express == IGNORECASENOTLIKE) {
value = "%" + value.toString().toLowerCase() + '%'; value = "%" + value.toString().toLowerCase() + '%';
} else if (express == IGNORECASECONTAIN || express == IGNORECASENOTCONTAIN) {
value = value.toString().toLowerCase();
} }
return new StringBuilder().append('\'').append(value.toString().replace("'", "\\'")).append('\''); return new StringBuilder().append('\'').append(value.toString().replace("'", "\\'")).append('\'');
} else if (value instanceof Range) { } 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) { if (express == ISNULL || express == ISNOTNULL) {
sb.append(col).append(' ').append(express.value()); sb.append(col).append(' ').append(express.value());
} else { } 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; return sb;

View File

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