增加ColumnValue功能

This commit is contained in:
Redkale
2016-10-31 14:04:45 +08:00
parent 19150e9f9c
commit ecd827e3b4
7 changed files with 69 additions and 184 deletions

View File

@@ -64,28 +64,13 @@ public class DataSourceService implements DataSource, Service, AutoCloseable {
}
@Override
public <T> void updateColumn(final Class<T> clazz, final Serializable id, final ColumnValue... values) {
source.updateColumn(clazz, id, values);
public <T> void updateColumns(final Class<T> clazz, final Serializable id, final ColumnValue... values) {
source.updateColumns(clazz, id, values);
}
@Override
public <T> void updateColumn(final Class<T> clazz, final FilterNode node, final ColumnValue... values) {
source.updateColumn(clazz, node, values);
}
@Override
public <T> void updateColumnIncrement(final Class<T> clazz, final Serializable id, final String column, long incvalue) {
source.updateColumnIncrement(clazz, id, column, incvalue);
}
@Override
public <T> void updateColumnAnd(final Class<T> clazz, final Serializable id, final String column, long incvalue) {
source.updateColumnAnd(clazz, id, column, incvalue);
}
@Override
public <T> void updateColumnOr(final Class<T> clazz, final Serializable id, final String column, long incvalue) {
source.updateColumnOr(clazz, id, column, incvalue);
public <T> void updateColumns(final Class<T> clazz, final FilterNode node, final ColumnValue... values) {
source.updateColumns(clazz, node, values);
}
@Override

View File

@@ -15,7 +15,8 @@ package org.redkale.source;
*/
public enum ColumnExpress {
MOV, //直接赋值 col = val
INCR, //追加值 col = col + val
INC, //追加值 col = col + val
MUL, //乘值 col = col * val
AND, //与值 col = col & val
OR; //或值 col = col | val
ORR; //或值 col = col | val
}

View File

@@ -6,6 +6,7 @@
package org.redkale.source;
import java.io.Serializable;
import static org.redkale.source.ColumnExpress.*;
/**
* ColumnValue主要用于多个字段更新的表达式。
@@ -36,6 +37,30 @@ public class ColumnValue {
this.value = value;
}
public static ColumnValue create(String column, Serializable value) {
return new ColumnValue(column, value);
}
public static ColumnValue createMov(String column, Serializable value) {
return new ColumnValue(column, MOV, value);
}
public static ColumnValue createInc(String column, Serializable value) {
return new ColumnValue(column, INC, value);
}
public static ColumnValue createMul(String column, Serializable value) {
return new ColumnValue(column, MUL, value);
}
public static ColumnValue createAnd(String column, Serializable value) {
return new ColumnValue(column, AND, value);
}
public static ColumnValue createOrr(String column, Serializable value) {
return new ColumnValue(column, ORR, value);
}
public String getColumn() {
return column;
}

View File

@@ -740,7 +740,7 @@ public final class DataDefaultSource implements DataSource, Function<Class, Enti
* @param values 字段值
*/
@Override
public <T> void updateColumn(final Class<T> clazz, final Serializable id, final ColumnValue... values) {
public <T> void updateColumns(final Class<T> clazz, final Serializable id, final ColumnValue... values) {
final EntityInfo<T> info = loadEntityInfo(clazz);
if (info.isVirtualEntity()) {
updateColumn(null, info, id, values);
@@ -768,7 +768,8 @@ public final class DataDefaultSource implements DataSource, Function<Class, Enti
cols.add(col);
if (!virtual) {
if (setsql.length() > 0) setsql.append(", ");
setsql.append(info.getSQLColumn(null, col.getColumn())).append(" = ").append(info.formatToString(col.getValue()));
String c = info.getSQLColumn(null, col.getColumn());
setsql.append(c).append(" = ").append(info.formatSQLValue(c, col));
}
}
if (!virtual) {
@@ -797,7 +798,7 @@ public final class DataDefaultSource implements DataSource, Function<Class, Enti
* @param values 字段值
*/
@Override
public <T> void updateColumn(final Class<T> clazz, final FilterNode node, final ColumnValue... values) {
public <T> void updateColumns(final Class<T> clazz, final FilterNode node, final ColumnValue... values) {
final EntityInfo<T> info = loadEntityInfo(clazz);
if (info.isVirtualEntity()) {
updateColumn(null, info, node, values);
@@ -825,7 +826,8 @@ public final class DataDefaultSource implements DataSource, Function<Class, Enti
cols.add(col);
if (!virtual) {
if (setsql.length() > 0) setsql.append(", ");
setsql.append(info.getSQLColumn("a", col.getColumn())).append(" = ").append(info.formatToString(col.getValue()));
String c = info.getSQLColumn("a", col.getColumn());
setsql.append(c).append(" = ").append(info.formatSQLValue(c, col));
}
}
if (!virtual) {
@@ -849,153 +851,6 @@ public final class DataDefaultSource implements DataSource, Function<Class, Enti
}
}
/**
* 根据主键值给对象的column对应的值+incvalue 必须是Entity Class
* 等价SQL: UPDATE {clazz} SET {column} = {column} + {incvalue} WHERE {primary} = {id}
*
* @param <T> Entity类的泛型
* @param clazz Entity类
* @param id 主键值
* @param column 字段名
* @param incvalue 字段加值
*/
@Override
public <T> void updateColumnIncrement(Class<T> clazz, Serializable id, String column, long incvalue) {
final EntityInfo<T> info = loadEntityInfo(clazz);
if (info.isVirtualEntity()) {
updateColumnIncrement(null, info, id, column, incvalue);
return;
}
Connection conn = createWriteSQLConnection();
try {
updateColumnIncrement(conn, info, id, column, incvalue);
} finally {
closeSQLConnection(conn);
}
}
private <T> void updateColumnIncrement(Connection conn, final EntityInfo<T> info, Serializable id, String column, long incvalue) {
try {
if (!info.isVirtualEntity()) {
String col = info.getSQLColumn(null, column);
String sql = "UPDATE " + info.getTable(id) + " SET " + col + " = " + col + " + (" + incvalue
+ ") WHERE " + info.getPrimarySQLColumn() + " = " + FilterNode.formatToString(id);
if (debug.get()) logger.finest(info.getType().getSimpleName() + " update sql=" + sql);
final Statement stmt = conn.createStatement();
stmt.execute(sql);
stmt.close();
}
//---------------------------------------------------
final EntityCache<T> cache = info.getCache();
if (cache == null) return;
Attribute<T, Serializable> attr = info.getAttribute(column);
T value = cache.updateColumnIncrement(id, attr, incvalue);
if (value != null && cacheListener != null) cacheListener.updateCache(info.getType(), value);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
if (conn != null) closeSQLConnection(conn);
}
}
/**
* 根据主键值给对象的column对应的值 &#38; andvalue 必须是Entity Class
* 等价SQL: UPDATE {clazz} SET {column} = {column} &#38; {incvalue} WHERE {primary} = {id}
*
* @param <T> Entity类的泛型
* @param clazz Entity类
* @param id 主键值
* @param column 字段名
* @param andvalue 字段与值
*/
@Override
public <T> void updateColumnAnd(Class<T> clazz, Serializable id, String column, long andvalue) {
final EntityInfo<T> info = loadEntityInfo(clazz);
if (info.isVirtualEntity()) {
updateColumnAnd(null, info, id, column, andvalue);
return;
}
Connection conn = createWriteSQLConnection();
try {
updateColumnAnd(conn, info, id, column, andvalue);
} finally {
closeSQLConnection(conn);
}
}
private <T> void updateColumnAnd(Connection conn, final EntityInfo<T> info, Serializable id, String column, long andvalue) {
try {
if (!info.isVirtualEntity()) {
String col = info.getSQLColumn(null, column);
String sql = "UPDATE " + info.getTable(id) + " SET " + col + " = " + col + " & (" + andvalue
+ ") WHERE " + info.getPrimarySQLColumn() + " = " + FilterNode.formatToString(id);
if (debug.get()) logger.finest(info.getType().getSimpleName() + " update sql=" + sql);
final Statement stmt = conn.createStatement();
stmt.execute(sql);
stmt.close();
}
//---------------------------------------------------
final EntityCache<T> cache = info.getCache();
if (cache == null) return;
Attribute<T, Serializable> attr = info.getAttribute(column);
T value = cache.updateColumnAnd(id, attr, andvalue);
if (value != null && cacheListener != null) cacheListener.updateCache(info.getType(), value);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
if (conn != null) closeSQLConnection(conn);
}
}
/**
* 根据主键值给对象的column对应的值 | andvalue 必须是Entity Class
* 等价SQL: UPDATE {clazz} SET {column} = {column} | {incvalue} WHERE {primary} = {id}
*
* @param <T> Entity类的泛型
* @param clazz Entity类
* @param id 主键值
* @param column 字段名
* @param orvalue 字段或值
*/
@Override
public <T> void updateColumnOr(Class<T> clazz, Serializable id, String column, long orvalue) {
final EntityInfo<T> info = loadEntityInfo(clazz);
if (info.isVirtualEntity()) {
updateColumnOr(null, info, id, column, orvalue);
return;
}
Connection conn = createWriteSQLConnection();
try {
updateColumnOr(conn, info, id, column, orvalue);
} finally {
closeSQLConnection(conn);
}
}
private <T> void updateColumnOr(Connection conn, final EntityInfo<T> info, Serializable id, String column, long orvalue) {
try {
if (!info.isVirtualEntity()) {
String col = info.getSQLColumn(null, column);
String sql = "UPDATE " + info.getTable(id) + " SET " + col + " = " + col + " | (" + orvalue
+ ") WHERE " + info.getPrimarySQLColumn() + " = " + FilterNode.formatToString(id);
if (debug.get()) logger.finest(info.getType().getSimpleName() + " update sql=" + sql);
final Statement stmt = conn.createStatement();
stmt.execute(sql);
stmt.close();
}
//---------------------------------------------------
final EntityCache<T> cache = info.getCache();
if (cache == null) return;
Attribute<T, Serializable> attr = info.getAttribute(column);
T value = cache.updateColumnOr(id, attr, orvalue);
if (value != null && cacheListener != null) cacheListener.updateCache(info.getType(), value);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
if (conn != null) closeSQLConnection(conn);
}
}
/**
* 更新对象指定的一些字段, 必须是Entity对象
*

View File

@@ -66,15 +66,9 @@ public interface DataSource {
public <T> void updateColumn(final Class<T> clazz, final String column, final Serializable value, final FilterNode node);
public <T> void updateColumn(final Class<T> clazz, final Serializable id, final ColumnValue... values);
public <T> void updateColumns(final Class<T> clazz, final Serializable id, final ColumnValue... values);
public <T> void updateColumn(final Class<T> clazz, final FilterNode node, final ColumnValue... values);
public <T> void updateColumnIncrement(final Class<T> clazz, final Serializable id, final String column, long incvalue);
public <T> void updateColumnAnd(final Class<T> clazz, final Serializable id, final String column, long incvalue);
public <T> void updateColumnOr(final Class<T> clazz, final Serializable id, final String column, long incvalue);
public <T> void updateColumns(final Class<T> clazz, final FilterNode node, final ColumnValue... values);
public <T> void updateColumns(final T bean, final String... columns);

View File

@@ -465,7 +465,7 @@ public final class EntityCache<T> {
T rs = this.map.get(id);
if (rs == null) return rs;
synchronized (rs) {
return updateColumn(attr, rs, ColumnExpress.OR, orvalue);
return updateColumn(attr, rs, ColumnExpress.ORR, orvalue);
}
}
@@ -483,7 +483,7 @@ public final class EntityCache<T> {
T rs = this.map.get(id);
if (rs == null) return rs;
synchronized (rs) {
return updateColumn(attr, rs, ColumnExpress.INCR, incvalue);
return updateColumn(attr, rs, ColumnExpress.INC, incvalue);
}
}
@@ -492,7 +492,7 @@ public final class EntityCache<T> {
Number numb = null;
Serializable newval = null;
switch (express) {
case INCR:
case INC:
numb = (Number) attr.get(rs);
if (numb == null) {
numb = (Number) val;
@@ -500,6 +500,14 @@ public final class EntityCache<T> {
numb = numb.longValue() + ((Number) val).longValue();
}
break;
case MUL:
numb = (Number) attr.get(rs);
if (numb == null) {
numb = 0;
} else {
numb = numb.longValue() * ((Number) val).floatValue();
}
break;
case AND:
numb = (Number) attr.get(rs);
if (numb == null) {
@@ -508,7 +516,7 @@ public final class EntityCache<T> {
numb = numb.longValue() & ((Number) val).longValue();
}
break;
case OR:
case ORR:
numb = (Number) attr.get(rs);
if (numb == null) {
numb = 0;

View File

@@ -424,6 +424,23 @@ public final class EntityInfo<T> {
return getSQLColumn(tabalis, this.primary.field());
}
protected CharSequence formatSQLValue(String col, final ColumnValue cv) {
if (cv == null) return null;
switch (cv.getExpress()) {
case INC:
return new StringBuilder().append(col).append(" + ").append(cv.getValue());
case MUL:
return new StringBuilder().append(col).append(" * ").append(cv.getValue());
case AND:
return new StringBuilder().append(col).append(" & ").append(cv.getValue());
case ORR:
return new StringBuilder().append(col).append(" | ").append(cv.getValue());
case MOV:
return formatToString(cv.getValue());
}
return formatToString(cv.getValue());
}
protected Map<String, Attribute<T, Serializable>> getAttributes() {
return attributeMap;
}