改版EntityXInfo
This commit is contained in:
@@ -399,7 +399,7 @@ public final class DataJDBCSource implements DataSource {
|
|||||||
final Class primaryType = info.getPrimary().type();
|
final Class primaryType = info.getPrimary().type();
|
||||||
final Attribute primary = info.getPrimary();
|
final Attribute primary = info.getPrimary();
|
||||||
final boolean distributed = info.distributed;
|
final boolean distributed = info.distributed;
|
||||||
Attribute<T, ?>[] attrs = info.insertAttributes;
|
Attribute<T, Serializable>[] attrs = info.insertAttributes;
|
||||||
String[] sqls = null;
|
String[] sqls = null;
|
||||||
if (distributed && !info.initedPrimaryValue && primaryType.isPrimitive()) {
|
if (distributed && !info.initedPrimaryValue && primaryType.isPrimitive()) {
|
||||||
synchronized (info) {
|
synchronized (info) {
|
||||||
@@ -443,7 +443,7 @@ public final class DataJDBCSource implements DataSource {
|
|||||||
for (final T value : values) {
|
for (final T value : values) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
if (distributed) info.createPrimaryValue(value);
|
if (distributed) info.createPrimaryValue(value);
|
||||||
for (Attribute<T, ?> attr : attrs) {
|
for (Attribute<T, Serializable> attr : attrs) {
|
||||||
prestmt.setObject(++i, attr.get(value));
|
prestmt.setObject(++i, attr.get(value));
|
||||||
}
|
}
|
||||||
prestmt.addBatch();
|
prestmt.addBatch();
|
||||||
@@ -456,7 +456,7 @@ public final class DataJDBCSource implements DataSource {
|
|||||||
for (final T value : values) {
|
for (final T value : values) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
if (distributed) info.createPrimaryValue(value);
|
if (distributed) info.createPrimaryValue(value);
|
||||||
for (Attribute<T, ?> attr : attrs) {
|
for (Attribute<T, Serializable> attr : attrs) {
|
||||||
Object a = attr.get(value);
|
Object a = attr.get(value);
|
||||||
ps[i] = formatToString(a);
|
ps[i] = formatToString(a);
|
||||||
prestmt.setObject(++i, a);
|
prestmt.setObject(++i, a);
|
||||||
@@ -659,7 +659,7 @@ public final class DataJDBCSource implements DataSource {
|
|||||||
//------------------------------------
|
//------------------------------------
|
||||||
final EntityCache<T> cache = info.getCache();
|
final EntityCache<T> cache = info.getCache();
|
||||||
if (cache == null) return;
|
if (cache == null) return;
|
||||||
final Attribute<T, ?> attr = info.getAttribute(column);
|
final Attribute<T, Serializable> attr = info.getAttribute(column);
|
||||||
final Serializable[] keys2 = keys;
|
final Serializable[] keys2 = keys;
|
||||||
Serializable[] ids = cache.delete((T t) -> Arrays.binarySearch(keys2, attr.get(t)) >= 0);
|
Serializable[] ids = cache.delete((T t) -> Arrays.binarySearch(keys2, attr.get(t)) >= 0);
|
||||||
if (cacheListener != null) cacheListener.delete(name, clazz, ids);
|
if (cacheListener != null) cacheListener.delete(name, clazz, ids);
|
||||||
@@ -717,8 +717,8 @@ public final class DataJDBCSource implements DataSource {
|
|||||||
//------------------------------------
|
//------------------------------------
|
||||||
final EntityCache<T> cache = info.getCache();
|
final EntityCache<T> cache = info.getCache();
|
||||||
if (cache == null) return;
|
if (cache == null) return;
|
||||||
final Attribute<T, ?> attr1 = info.getAttribute(column1);
|
final Attribute<T, Serializable> attr1 = info.getAttribute(column1);
|
||||||
final Attribute<T, ?> attr2 = info.getAttribute(column2);
|
final Attribute<T, Serializable> attr2 = info.getAttribute(column2);
|
||||||
Serializable[] ids = cache.delete((T t) -> key1.equals(attr1.get(t)) && key2.equals(attr2.get(t)));
|
Serializable[] ids = cache.delete((T t) -> key1.equals(attr1.get(t)) && key2.equals(attr2.get(t)));
|
||||||
if (cacheListener != null) cacheListener.delete(name, clazz, ids);
|
if (cacheListener != null) cacheListener.delete(name, clazz, ids);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
@@ -771,12 +771,12 @@ public final class DataJDBCSource implements DataSource {
|
|||||||
final EntityInfo<T> info = loadEntityInfo(clazz);
|
final EntityInfo<T> info = loadEntityInfo(clazz);
|
||||||
if (debug.get()) logger.finest(clazz.getSimpleName() + " update sql=" + info.updateSQL);
|
if (debug.get()) logger.finest(clazz.getSimpleName() + " update sql=" + info.updateSQL);
|
||||||
final PreparedStatement prestmt = conn.prepareStatement(info.updateSQL);
|
final PreparedStatement prestmt = conn.prepareStatement(info.updateSQL);
|
||||||
Attribute<T, ?>[] attrs = info.updateAttributes;
|
Attribute<T, Serializable>[] attrs = info.updateAttributes;
|
||||||
String[] sqls = null;
|
String[] sqls = null;
|
||||||
if (writeListener == null) {
|
if (writeListener == null) {
|
||||||
for (final T value : values) {
|
for (final T value : values) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Attribute<T, ?> attr : attrs) {
|
for (Attribute<T, Serializable> attr : attrs) {
|
||||||
prestmt.setObject(++i, attr.get(value));
|
prestmt.setObject(++i, attr.get(value));
|
||||||
}
|
}
|
||||||
prestmt.addBatch();
|
prestmt.addBatch();
|
||||||
@@ -788,7 +788,7 @@ public final class DataJDBCSource implements DataSource {
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
for (final T value : values) {
|
for (final T value : values) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Attribute<T, ?> attr : attrs) {
|
for (Attribute<T, Serializable> attr : attrs) {
|
||||||
Object a = attr.get(value);
|
Object a = attr.get(value);
|
||||||
ps[i] = formatToString(a);
|
ps[i] = formatToString(a);
|
||||||
prestmt.setObject(++i, a);
|
prestmt.setObject(++i, a);
|
||||||
@@ -924,7 +924,7 @@ public final class DataJDBCSource implements DataSource {
|
|||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
final EntityCache<T> cache = info.getCache();
|
final EntityCache<T> cache = info.getCache();
|
||||||
if (cache == null) return;
|
if (cache == null) return;
|
||||||
Attribute<T, Object> attr = (Attribute<T, Object>) info.getAttribute(column);
|
Attribute<T, Serializable> attr = info.getAttribute(column);
|
||||||
T value = cache.updateColumnIncrement(id, attr, incvalue);
|
T value = cache.updateColumnIncrement(id, attr, incvalue);
|
||||||
if (value != null && cacheListener != null) cacheListener.update(name, clazz, value);
|
if (value != null && cacheListener != null) cacheListener.update(name, clazz, value);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
@@ -970,7 +970,7 @@ public final class DataJDBCSource implements DataSource {
|
|||||||
final Class<T> clazz = (Class<T>) value.getClass();
|
final Class<T> clazz = (Class<T>) value.getClass();
|
||||||
final EntityInfo<T> info = loadEntityInfo(clazz);
|
final EntityInfo<T> info = loadEntityInfo(clazz);
|
||||||
StringBuilder setsql = new StringBuilder();
|
StringBuilder setsql = new StringBuilder();
|
||||||
Attribute<T, ?>[] attrs = new Attribute[columns.length];
|
Attribute<T, Serializable>[] attrs = new Attribute[columns.length];
|
||||||
int i = - 1;
|
int i = - 1;
|
||||||
final Serializable id = (Serializable) info.getPrimary().get(value);
|
final Serializable id = (Serializable) info.getPrimary().get(value);
|
||||||
for (String col : columns) {
|
for (String col : columns) {
|
||||||
@@ -1206,8 +1206,8 @@ public final class DataJDBCSource implements DataSource {
|
|||||||
final EntityInfo<T> info = loadEntityInfo(clazz);
|
final EntityInfo<T> info = loadEntityInfo(clazz);
|
||||||
final EntityCache<T> cache = info.getCache();
|
final EntityCache<T> cache = info.getCache();
|
||||||
if (cache != null) {
|
if (cache != null) {
|
||||||
final Attribute<T, ?> attr1 = info.getAttribute(column1);
|
final Attribute<T, Serializable> attr1 = info.getAttribute(column1);
|
||||||
final Attribute<T, ?> attr2 = info.getAttribute(column2);
|
final Attribute<T, Serializable> attr2 = info.getAttribute(column2);
|
||||||
T r = cache.find((T t) -> key1.equals(attr1.get(t)) && key2.equals(attr2.get(t)));
|
T r = cache.find((T t) -> key1.equals(attr1.get(t)) && key2.equals(attr2.get(t)));
|
||||||
if (r != null || cache.isFullLoaded()) return r;
|
if (r != null || cache.isFullLoaded()) return r;
|
||||||
}
|
}
|
||||||
@@ -1278,7 +1278,7 @@ public final class DataJDBCSource implements DataSource {
|
|||||||
final EntityInfo<T> info = loadEntityInfo(clazz);
|
final EntityInfo<T> info = loadEntityInfo(clazz);
|
||||||
final EntityCache<T> cache = info.getCache();
|
final EntityCache<T> cache = info.getCache();
|
||||||
if (cache != null) {
|
if (cache != null) {
|
||||||
Attribute<T, ?> idattr = info.getAttribute(column);
|
Attribute<T, Serializable> idattr = info.getAttribute(column);
|
||||||
List<T> list = cache.queryList(selects, (x) -> Arrays.binarySearch(keys, idattr.get(x)) >= 0, null);
|
List<T> list = cache.queryList(selects, (x) -> Arrays.binarySearch(keys, idattr.get(x)) >= 0, null);
|
||||||
final T[] rs = (T[]) Array.newInstance(clazz, keys.length);
|
final T[] rs = (T[]) Array.newInstance(clazz, keys.length);
|
||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
@@ -1573,7 +1573,7 @@ public final class DataJDBCSource implements DataSource {
|
|||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> Predicate<T> genFilter(final Attribute<T, ?> attr, FilterExpress express, Serializable key) {
|
private <T> Predicate<T> genFilter(final Attribute<T, Serializable> attr, FilterExpress express, Serializable key) {
|
||||||
Predicate<T> filter = null;
|
Predicate<T> filter = null;
|
||||||
switch (express) {
|
switch (express) {
|
||||||
case EQUAL:
|
case EQUAL:
|
||||||
@@ -1749,7 +1749,7 @@ public final class DataJDBCSource implements DataSource {
|
|||||||
if (valid) filter = finfo.getFilterPredicate(info, bean);
|
if (valid) filter = finfo.getFilterPredicate(info, bean);
|
||||||
}
|
}
|
||||||
if (valid) {
|
if (valid) {
|
||||||
Sheet<T> sheet = cache.querySheet(selects, filter, flipper, FilterInfo.getSortComparator(info, flipper));
|
Sheet<T> sheet = cache.querySheet(selects, filter, flipper, FilterNode.getSortComparator(info, flipper));
|
||||||
if (!sheet.isEmpty() || cache.isFullLoaded()) return sheet;
|
if (!sheet.isEmpty() || cache.isFullLoaded()) return sheet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2296,7 +2296,7 @@ public final class DataJDBCSource implements DataSource {
|
|||||||
return inner.getAttribute(fieldname).field();
|
return inner.getAttribute(fieldname).field();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Attribute<T, ?> getAttribute(String fieldname) {
|
public Attribute<T, Serializable> getAttribute(String fieldname) {
|
||||||
return inner.getAttribute(fieldname);
|
return inner.getAttribute(fieldname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,14 +36,14 @@ final class EntityCache<T> {
|
|||||||
private final Attribute<T, Serializable> primary;
|
private final Attribute<T, Serializable> primary;
|
||||||
|
|
||||||
//key是field的name
|
//key是field的name
|
||||||
private final Map<String, Attribute<T, ?>> attributes;
|
private final Map<String, Attribute<T, Serializable>> attributes;
|
||||||
|
|
||||||
private final Reproduce<T, T> reproduce;
|
private final Reproduce<T, T> reproduce;
|
||||||
|
|
||||||
private boolean fullloaded;
|
private boolean fullloaded;
|
||||||
|
|
||||||
public EntityCache(final Class<T> type, Creator<T> creator,
|
public EntityCache(final Class<T> type, Creator<T> creator,
|
||||||
Attribute<T, Serializable> primary, Map<String, Attribute<T, ?>> attributes) {
|
Attribute<T, Serializable> primary, Map<String, Attribute<T, Serializable>> attributes) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.creator = creator;
|
this.creator = creator;
|
||||||
this.primary = primary;
|
this.primary = primary;
|
||||||
@@ -63,7 +63,7 @@ final class EntityCache<T> {
|
|||||||
|
|
||||||
public void fullLoad(List<T> all) {
|
public void fullLoad(List<T> all) {
|
||||||
clear();
|
clear();
|
||||||
all.stream().filter(x -> x != null).forEach(x -> this.map.put((Serializable) this.primary.get(x), x));
|
all.stream().filter(x -> x != null).forEach(x -> this.map.put(this.primary.get(x), x));
|
||||||
this.list.addAll(all);
|
this.list.addAll(all);
|
||||||
this.fullloaded = true;
|
this.fullloaded = true;
|
||||||
}
|
}
|
||||||
@@ -168,8 +168,8 @@ final class EntityCache<T> {
|
|||||||
if (selects == null) {
|
if (selects == null) {
|
||||||
stream.forEach(x -> rs.add(needcopy ? reproduce.copy(creator.create(), x) : x));
|
stream.forEach(x -> rs.add(needcopy ? reproduce.copy(creator.create(), x) : x));
|
||||||
} else {
|
} else {
|
||||||
final List<Attribute<T, ?>> attrs = new ArrayList<>();
|
final List<Attribute<T, Serializable>> attrs = new ArrayList<>();
|
||||||
for (Map.Entry<String, Attribute<T, ?>> en : this.attributes.entrySet()) {
|
for (Map.Entry<String, Attribute<T, Serializable>> en : this.attributes.entrySet()) {
|
||||||
if (selects.validate(en.getKey())) attrs.add(en.getValue());
|
if (selects.validate(en.getKey())) attrs.add(en.getValue());
|
||||||
}
|
}
|
||||||
stream.forEach(x -> {
|
stream.forEach(x -> {
|
||||||
@@ -207,8 +207,8 @@ final class EntityCache<T> {
|
|||||||
if (selects == null) {
|
if (selects == null) {
|
||||||
stream.forEach(x -> rs.add(needcopy ? reproduce.copy(creator.create(), x) : x));
|
stream.forEach(x -> rs.add(needcopy ? reproduce.copy(creator.create(), x) : x));
|
||||||
} else {
|
} else {
|
||||||
final List<Attribute<T, ?>> attrs = new ArrayList<>();
|
final List<Attribute<T, Serializable>> attrs = new ArrayList<>();
|
||||||
for (Map.Entry<String, Attribute<T, ?>> en : this.attributes.entrySet()) {
|
for (Map.Entry<String, Attribute<T, Serializable>> en : this.attributes.entrySet()) {
|
||||||
if (selects.validate(en.getKey())) attrs.add(en.getValue());
|
if (selects.validate(en.getKey())) attrs.add(en.getValue());
|
||||||
}
|
}
|
||||||
stream.forEach(x -> {
|
stream.forEach(x -> {
|
||||||
@@ -225,7 +225,7 @@ final class EntityCache<T> {
|
|||||||
public void insert(T value) {
|
public void insert(T value) {
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
T rs = reproduce.copy(this.creator.create(), value); //确保同一主键值的map与list中的对象必须共用。
|
T rs = reproduce.copy(this.creator.create(), value); //确保同一主键值的map与list中的对象必须共用。
|
||||||
T old = this.map.put((Serializable) this.primary.get(rs), rs);
|
T old = this.map.put(this.primary.get(rs), rs);
|
||||||
if (old != null) logger.log(Level.WARNING, "cache repeat insert data: " + value);
|
if (old != null) logger.log(Level.WARNING, "cache repeat insert data: " + value);
|
||||||
this.list.add(rs);
|
this.list.add(rs);
|
||||||
}
|
}
|
||||||
@@ -243,7 +243,7 @@ final class EntityCache<T> {
|
|||||||
int i = -1;
|
int i = -1;
|
||||||
for (Object o : rms) {
|
for (Object o : rms) {
|
||||||
T t = (T) o;
|
T t = (T) o;
|
||||||
ids[++i] = (Serializable) this.primary.get(t);
|
ids[++i] = this.primary.get(t);
|
||||||
this.map.remove(ids[i]);
|
this.map.remove(ids[i]);
|
||||||
this.list.remove(t);
|
this.list.remove(t);
|
||||||
}
|
}
|
||||||
@@ -252,14 +252,14 @@ final class EntityCache<T> {
|
|||||||
|
|
||||||
public void update(final T value) {
|
public void update(final T value) {
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
T rs = this.map.get((Serializable) this.primary.get(value));
|
T rs = this.map.get(this.primary.get(value));
|
||||||
if (rs == null) return;
|
if (rs == null) return;
|
||||||
this.reproduce.copy(rs, value);
|
this.reproduce.copy(rs, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(final T value, Attribute<T, ?>[] attrs) {
|
public void update(final T value, Attribute<T, Serializable>[] attrs) {
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
T rs = this.map.get((Serializable) this.primary.get(value));
|
T rs = this.map.get(this.primary.get(value));
|
||||||
if (rs == null) return;
|
if (rs == null) return;
|
||||||
for (Attribute attr : attrs) {
|
for (Attribute attr : attrs) {
|
||||||
attr.set(rs, attr.get(value));
|
attr.set(rs, attr.get(value));
|
||||||
|
|||||||
@@ -47,19 +47,21 @@ public final class EntityInfo<T> {
|
|||||||
|
|
||||||
//key是field的name, 不是sql字段。
|
//key是field的name, 不是sql字段。
|
||||||
//存放所有与数据库对应的字段, 包括主键
|
//存放所有与数据库对应的字段, 包括主键
|
||||||
private final Map<String, Attribute<T, ?>> attributes = new HashMap<>();
|
private final Map<String, Attribute<T, Serializable>> attributes = new HashMap<>();
|
||||||
|
|
||||||
|
private final Map<String, Attribute<T, Serializable>> updateAttributeMap = new HashMap<>();
|
||||||
|
|
||||||
final String querySQL;
|
final String querySQL;
|
||||||
|
|
||||||
private final Attribute<T, Object>[] queryAttributes; //数据库中所有字段
|
private final Attribute<T, Serializable>[] queryAttributes; //数据库中所有字段
|
||||||
|
|
||||||
final String insertSQL;
|
final String insertSQL;
|
||||||
|
|
||||||
final Attribute<T, Object>[] insertAttributes; //数据库中所有可新增字段
|
final Attribute<T, Serializable>[] insertAttributes; //数据库中所有可新增字段
|
||||||
|
|
||||||
final String updateSQL;
|
final String updateSQL;
|
||||||
|
|
||||||
final Attribute<T, Object>[] updateAttributes; //数据库中所有可更新字段
|
final Attribute<T, Serializable>[] updateAttributes; //数据库中所有可更新字段
|
||||||
|
|
||||||
final String deleteSQL;
|
final String deleteSQL;
|
||||||
|
|
||||||
@@ -120,11 +122,11 @@ public final class EntityInfo<T> {
|
|||||||
Map<String, String> aliasmap0 = null;
|
Map<String, String> aliasmap0 = null;
|
||||||
Class cltmp = type;
|
Class cltmp = type;
|
||||||
Set<String> fields = new HashSet<>();
|
Set<String> fields = new HashSet<>();
|
||||||
List<Attribute<T, ?>> queryattrs = new ArrayList<>();
|
List<Attribute<T, Serializable>> queryattrs = new ArrayList<>();
|
||||||
List<String> insertcols = new ArrayList<>();
|
List<String> insertcols = new ArrayList<>();
|
||||||
List<Attribute<T, ?>> insertattrs = new ArrayList<>();
|
List<Attribute<T, Serializable>> insertattrs = new ArrayList<>();
|
||||||
List<String> updatecols = new ArrayList<>();
|
List<String> updatecols = new ArrayList<>();
|
||||||
List<Attribute<T, ?>> updateattrs = new ArrayList<>();
|
List<Attribute<T, Serializable>> updateattrs = new ArrayList<>();
|
||||||
boolean auto = false;
|
boolean auto = false;
|
||||||
boolean sqldistribute = false;
|
boolean sqldistribute = false;
|
||||||
int allocationSize0 = 0;
|
int allocationSize0 = 0;
|
||||||
@@ -175,6 +177,7 @@ public final class EntityInfo<T> {
|
|||||||
if (col == null || col.updatable()) {
|
if (col == null || col.updatable()) {
|
||||||
updatecols.add(sqlfield);
|
updatecols.add(sqlfield);
|
||||||
updateattrs.add(attr);
|
updateattrs.add(attr);
|
||||||
|
updateAttributeMap.put(fieldname, attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
queryattrs.add(attr);
|
queryattrs.add(attr);
|
||||||
@@ -248,10 +251,14 @@ public final class EntityInfo<T> {
|
|||||||
return this.primary;
|
return this.primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Attribute<T, ?> getAttribute(String fieldname) {
|
public Attribute<T, Serializable> getAttribute(String fieldname) {
|
||||||
return this.attributes.get(fieldname);
|
return this.attributes.get(fieldname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Attribute<T, Serializable> getUpdateAttribute(String fieldname) {
|
||||||
|
return this.updateAttributeMap.get(fieldname);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isNoAlias() {
|
public boolean isNoAlias() {
|
||||||
return this.aliasmap == null;
|
return this.aliasmap == null;
|
||||||
}
|
}
|
||||||
@@ -266,7 +273,7 @@ public final class EntityInfo<T> {
|
|||||||
return getSQLColumn(this.primary.field());
|
return getSQLColumn(this.primary.field());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Attribute<T, ?>> getAttributes() {
|
public Map<String, Attribute<T, Serializable>> getAttributes() {
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,9 +283,9 @@ public final class EntityInfo<T> {
|
|||||||
|
|
||||||
public T getValue(SelectColumn sels, ResultSet set) throws SQLException {
|
public T getValue(SelectColumn sels, ResultSet set) throws SQLException {
|
||||||
T obj = creator.create();
|
T obj = creator.create();
|
||||||
for (Attribute<T, Object> attr : queryAttributes) {
|
for (Attribute<T, Serializable> attr : queryAttributes) {
|
||||||
if (sels == null || sels.validate(attr.field())) {
|
if (sels == null || sels.validate(attr.field())) {
|
||||||
Object o = set.getObject(this.getSQLColumn(attr.field()));
|
Serializable o = (Serializable) set.getObject(this.getSQLColumn(attr.field()));
|
||||||
if (o != null) {
|
if (o != null) {
|
||||||
if (type == long.class) {
|
if (type == long.class) {
|
||||||
o = ((Number) o).longValue();
|
o = ((Number) o).longValue();
|
||||||
|
|||||||
@@ -157,30 +157,6 @@ final class FilterInfo<T extends FilterBean> {
|
|||||||
return rootNode.getFilterPredicate(info, bean);
|
return rootNode.getFilterPredicate(info, bean);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <E> Comparator<E> getSortComparator(EntityInfo<E> info, Flipper flipper) {
|
|
||||||
if (flipper == null || flipper.getSort() == null || flipper.getSort().isEmpty()) return null;
|
|
||||||
Comparator<E> comparator = null;
|
|
||||||
for (String item : flipper.getSort().split(",")) {
|
|
||||||
if (item.isEmpty()) continue;
|
|
||||||
String[] sub = item.split("\\s+");
|
|
||||||
final Attribute<E, ?> attr = info.getAttribute(sub[0]);
|
|
||||||
Comparator<E> c = (E o1, E o2) -> {
|
|
||||||
Comparable c1 = (Comparable) attr.get(o1);
|
|
||||||
Comparable c2 = (Comparable) attr.get(o2);
|
|
||||||
return c1 == null ? -1 : c1.compareTo(c2);
|
|
||||||
};
|
|
||||||
if (sub.length > 1 && sub[1].equalsIgnoreCase("DESC")) {
|
|
||||||
c = c.reversed();
|
|
||||||
}
|
|
||||||
if (comparator == null) {
|
|
||||||
comparator = c;
|
|
||||||
} else {
|
|
||||||
comparator = comparator.thenComparing(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return comparator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StringBuilder createWhereSql(String primaryColumn, T obj) {
|
public StringBuilder createWhereSql(String primaryColumn, T obj) {
|
||||||
StringBuilder sb = rootNode.getFilterExpress(obj);
|
StringBuilder sb = rootNode.getFilterExpress(obj);
|
||||||
if (sb == null) return null;
|
if (sb == null) return null;
|
||||||
|
|||||||
@@ -114,6 +114,49 @@ public class FilterNode {
|
|||||||
return new FilterNode(column, express, value);
|
return new FilterNode(column, express, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final <T> StringBuilder createFilterSQLExpress(final EntityInfo<T> info, FilterBean bean) {
|
||||||
|
final Serializable val = getValue(bean);
|
||||||
|
if (val == null && express != ISNULL && express != ISNOTNULL) return null;
|
||||||
|
StringBuilder sb0 = createFilterSQLExpress(info, val);
|
||||||
|
if (nodes == null) return sb0;
|
||||||
|
final StringBuilder rs = new StringBuilder();
|
||||||
|
rs.append('(');
|
||||||
|
if (sb0 != null) rs.append(sb0);
|
||||||
|
for (FilterNode node : this.nodes) {
|
||||||
|
StringBuilder f = node.createFilterSQLExpress(info, bean);
|
||||||
|
if (f == null) continue;
|
||||||
|
if (rs.length() > 0) rs.append(signand ? " AND " : " OR ");
|
||||||
|
rs.append(f);
|
||||||
|
}
|
||||||
|
rs.append(')');
|
||||||
|
if (rs.length() < 3) return null;
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> StringBuilder createFilterSQLExpress(final EntityInfo<T> info, Serializable val0) {
|
||||||
|
final StringBuilder val = formatValue(val0);
|
||||||
|
if (val == null) return null;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(info.getSQLColumn(column)).append(' ');
|
||||||
|
switch (express) {
|
||||||
|
case ISNULL:
|
||||||
|
case ISNOTNULL:
|
||||||
|
sb.append(express.value());
|
||||||
|
break;
|
||||||
|
case OPAND:
|
||||||
|
case OPOR:
|
||||||
|
sb.append(express.value()).append(' ').append(val).append(" > 0)");
|
||||||
|
break;
|
||||||
|
case OPANDNO:
|
||||||
|
sb.append(express.value()).append(' ').append(val).append(" = 0)");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sb.append(express.value()).append(' ').append(val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
protected final <T> Predicate<T> createFilterPredicate(final EntityInfo<T> info, FilterBean bean) {
|
protected final <T> Predicate<T> createFilterPredicate(final EntityInfo<T> info, FilterBean bean) {
|
||||||
if (info == null) return null;
|
if (info == null) return null;
|
||||||
final Serializable val = getValue(bean);
|
final Serializable val = getValue(bean);
|
||||||
@@ -128,7 +171,7 @@ public class FilterNode {
|
|||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> Predicate<T> createFilterPredicate(final Attribute<T, ?> attr, final Serializable val) {
|
private <T> Predicate<T> createFilterPredicate(final Attribute<T, Serializable> attr, final Serializable val) {
|
||||||
if (attr == null) return null;
|
if (attr == null) return null;
|
||||||
switch (express) {
|
switch (express) {
|
||||||
case EQUAL: return (T t) -> val.equals(attr.get(t));
|
case EQUAL: return (T t) -> val.equals(attr.get(t));
|
||||||
@@ -218,13 +261,53 @@ public class FilterNode {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static String formatValue(Object value) {
|
protected static <E> Comparator<E> getSortComparator(EntityInfo<E> info, Flipper flipper) {
|
||||||
if (value == null) return null;
|
if (flipper == null || flipper.getSort() == null || flipper.getSort().isEmpty()) return null;
|
||||||
if (value instanceof Number) return value.toString();
|
Comparator<E> comparator = null;
|
||||||
if (value instanceof CharSequence) {
|
for (String item : flipper.getSort().split(",")) {
|
||||||
return new StringBuilder().append('"').append(value.toString().replace("\"", "\\\"")).append('"').toString();
|
if (item.isEmpty()) continue;
|
||||||
|
String[] sub = item.split("\\s+");
|
||||||
|
final Attribute<E, Serializable> attr = info.getAttribute(sub[0]);
|
||||||
|
Comparator<E> c = (E o1, E o2) -> {
|
||||||
|
Comparable c1 = (Comparable) attr.get(o1);
|
||||||
|
Comparable c2 = (Comparable) attr.get(o2);
|
||||||
|
return c1 == null ? -1 : c1.compareTo(c2);
|
||||||
|
};
|
||||||
|
if (sub.length > 1 && sub[1].equalsIgnoreCase("DESC")) {
|
||||||
|
c = c.reversed();
|
||||||
}
|
}
|
||||||
if (value.getClass().isArray()) {
|
if (comparator == null) {
|
||||||
|
comparator = c;
|
||||||
|
} else {
|
||||||
|
comparator = comparator.thenComparing(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return comparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected StringBuilder formatValue(Object value) {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) return new StringBuilder().append(value);
|
||||||
|
if (value instanceof CharSequence) {
|
||||||
|
if (express == LIKE || express == NOTLIKE) value = "%" + value + '%';
|
||||||
|
return new StringBuilder().append('\\').append(value.toString().replace("'", "\\'")).append('\'');
|
||||||
|
} else if (value instanceof Range) {
|
||||||
|
Range range = (Range) value;
|
||||||
|
boolean rangestring = range.getClass() == Range.StringRange.class;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
if (rangestring) {
|
||||||
|
sb.append('\'').append(range.getMin().toString().replace("'", "\\'")).append('\'');
|
||||||
|
} else {
|
||||||
|
sb.append(range.getMin());
|
||||||
|
}
|
||||||
|
sb.append(" AND ");
|
||||||
|
if (rangestring) {
|
||||||
|
sb.append('\'').append(range.getMax().toString().replace("'", "\\'")).append('\'');
|
||||||
|
} else {
|
||||||
|
sb.append(range.getMax());
|
||||||
|
}
|
||||||
|
return sb;
|
||||||
|
} else if (value.getClass().isArray()) {
|
||||||
int len = Array.getLength(value);
|
int len = Array.getLength(value);
|
||||||
if (len == 0) return null;
|
if (len == 0) return null;
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
@@ -233,14 +316,13 @@ public class FilterNode {
|
|||||||
Object o = Array.get(value, i);
|
Object o = Array.get(value, i);
|
||||||
if (sb.length() > 0) sb.append(',');
|
if (sb.length() > 0) sb.append(',');
|
||||||
if (o instanceof CharSequence) {
|
if (o instanceof CharSequence) {
|
||||||
sb.append('"').append(o.toString().replace("\"", "\\\"")).append('"');
|
sb.append('\'').append(o.toString().replace("'", "\\'")).append('\'');
|
||||||
} else {
|
} else {
|
||||||
sb.append(o);
|
sb.append(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sb.append(')').toString();
|
return sb.append(')');
|
||||||
}
|
} else if (value instanceof Collection) {
|
||||||
if (value instanceof Collection) {
|
|
||||||
Collection c = (Collection) value;
|
Collection c = (Collection) value;
|
||||||
if (c.isEmpty()) return null;
|
if (c.isEmpty()) return null;
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
@@ -248,14 +330,14 @@ public class FilterNode {
|
|||||||
for (Object o : c) {
|
for (Object o : c) {
|
||||||
if (sb.length() > 0) sb.append(',');
|
if (sb.length() > 0) sb.append(',');
|
||||||
if (o instanceof CharSequence) {
|
if (o instanceof CharSequence) {
|
||||||
sb.append('"').append(o.toString().replace("\"", "\\\"")).append('"');
|
sb.append('\'').append(o.toString().replace("'", "\\'")).append('\'');
|
||||||
} else {
|
} else {
|
||||||
sb.append(o);
|
sb.append(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sb.append(')').toString();
|
return sb.append(')');
|
||||||
}
|
}
|
||||||
return String.valueOf(value);
|
return new StringBuilder().append(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user