增加ColumnValue功能
This commit is contained in:
@@ -64,28 +64,13 @@ public class DataSourceService implements DataSource, Service, AutoCloseable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
||||||
source.updateColumn(clazz, id, values);
|
source.updateColumns(clazz, id, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
||||||
source.updateColumn(clazz, node, values);
|
source.updateColumns(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ package org.redkale.source;
|
|||||||
*/
|
*/
|
||||||
public enum ColumnExpress {
|
public enum ColumnExpress {
|
||||||
MOV, //直接赋值 col = val
|
MOV, //直接赋值 col = val
|
||||||
INCR, //追加值 col = col + val
|
INC, //追加值 col = col + val
|
||||||
|
MUL, //乘值 col = col * val
|
||||||
AND, //与值 col = col & val
|
AND, //与值 col = col & val
|
||||||
OR; //或值 col = col | val
|
ORR; //或值 col = col | val
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.redkale.source;
|
package org.redkale.source;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import static org.redkale.source.ColumnExpress.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ColumnValue主要用于多个字段更新的表达式。
|
* ColumnValue主要用于多个字段更新的表达式。
|
||||||
@@ -36,6 +37,30 @@ public class ColumnValue {
|
|||||||
this.value = value;
|
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() {
|
public String getColumn() {
|
||||||
return column;
|
return column;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -740,7 +740,7 @@ public final class DataDefaultSource implements DataSource, Function<Class, Enti
|
|||||||
* @param values 字段值
|
* @param values 字段值
|
||||||
*/
|
*/
|
||||||
@Override
|
@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);
|
final EntityInfo<T> info = loadEntityInfo(clazz);
|
||||||
if (info.isVirtualEntity()) {
|
if (info.isVirtualEntity()) {
|
||||||
updateColumn(null, info, id, values);
|
updateColumn(null, info, id, values);
|
||||||
@@ -768,7 +768,8 @@ public final class DataDefaultSource implements DataSource, Function<Class, Enti
|
|||||||
cols.add(col);
|
cols.add(col);
|
||||||
if (!virtual) {
|
if (!virtual) {
|
||||||
if (setsql.length() > 0) setsql.append(", ");
|
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) {
|
if (!virtual) {
|
||||||
@@ -797,7 +798,7 @@ public final class DataDefaultSource implements DataSource, Function<Class, Enti
|
|||||||
* @param values 字段值
|
* @param values 字段值
|
||||||
*/
|
*/
|
||||||
@Override
|
@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);
|
final EntityInfo<T> info = loadEntityInfo(clazz);
|
||||||
if (info.isVirtualEntity()) {
|
if (info.isVirtualEntity()) {
|
||||||
updateColumn(null, info, node, values);
|
updateColumn(null, info, node, values);
|
||||||
@@ -825,7 +826,8 @@ public final class DataDefaultSource implements DataSource, Function<Class, Enti
|
|||||||
cols.add(col);
|
cols.add(col);
|
||||||
if (!virtual) {
|
if (!virtual) {
|
||||||
if (setsql.length() > 0) setsql.append(", ");
|
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) {
|
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对应的值 & andvalue, 必须是Entity Class
|
|
||||||
* 等价SQL: UPDATE {clazz} SET {column} = {column} & {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对象
|
* 更新对象指定的一些字段, 必须是Entity对象
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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 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 updateColumns(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 T bean, final String... columns);
|
public <T> void updateColumns(final T bean, final String... columns);
|
||||||
|
|
||||||
|
|||||||
@@ -465,7 +465,7 @@ public final class EntityCache<T> {
|
|||||||
T rs = this.map.get(id);
|
T rs = this.map.get(id);
|
||||||
if (rs == null) return rs;
|
if (rs == null) return rs;
|
||||||
synchronized (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);
|
T rs = this.map.get(id);
|
||||||
if (rs == null) return rs;
|
if (rs == null) return rs;
|
||||||
synchronized (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;
|
Number numb = null;
|
||||||
Serializable newval = null;
|
Serializable newval = null;
|
||||||
switch (express) {
|
switch (express) {
|
||||||
case INCR:
|
case INC:
|
||||||
numb = (Number) attr.get(rs);
|
numb = (Number) attr.get(rs);
|
||||||
if (numb == null) {
|
if (numb == null) {
|
||||||
numb = (Number) val;
|
numb = (Number) val;
|
||||||
@@ -500,6 +500,14 @@ public final class EntityCache<T> {
|
|||||||
numb = numb.longValue() + ((Number) val).longValue();
|
numb = numb.longValue() + ((Number) val).longValue();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MUL:
|
||||||
|
numb = (Number) attr.get(rs);
|
||||||
|
if (numb == null) {
|
||||||
|
numb = 0;
|
||||||
|
} else {
|
||||||
|
numb = numb.longValue() * ((Number) val).floatValue();
|
||||||
|
}
|
||||||
|
break;
|
||||||
case AND:
|
case AND:
|
||||||
numb = (Number) attr.get(rs);
|
numb = (Number) attr.get(rs);
|
||||||
if (numb == null) {
|
if (numb == null) {
|
||||||
@@ -508,7 +516,7 @@ public final class EntityCache<T> {
|
|||||||
numb = numb.longValue() & ((Number) val).longValue();
|
numb = numb.longValue() & ((Number) val).longValue();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OR:
|
case ORR:
|
||||||
numb = (Number) attr.get(rs);
|
numb = (Number) attr.get(rs);
|
||||||
if (numb == null) {
|
if (numb == null) {
|
||||||
numb = 0;
|
numb = 0;
|
||||||
|
|||||||
@@ -424,6 +424,23 @@ public final class EntityInfo<T> {
|
|||||||
return getSQLColumn(tabalis, this.primary.field());
|
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() {
|
protected Map<String, Attribute<T, Serializable>> getAttributes() {
|
||||||
return attributeMap;
|
return attributeMap;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user