DataSource增加部分JSON功能

This commit is contained in:
Redkale
2018-11-28 11:17:55 +08:00
parent d7e7113201
commit 32d8515bf4
6 changed files with 210 additions and 32 deletions

View File

@@ -167,27 +167,35 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
final PreparedStatement prestmt = info.autoGenerated ? conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) : conn.prepareStatement(sql);
for (final T value : values) {
int i = 0;
if (info.autouuid) info.createPrimaryValue(value);
for (Attribute<T, Serializable> attr : attrs) {
Serializable val = attr.get(value);
if (val instanceof byte[]) {
Blob blob = conn.createBlob();
blob.setBytes(1, (byte[]) val);
prestmt.setObject(++i, blob);
} else if (val instanceof AtomicInteger) {
prestmt.setObject(++i, ((AtomicInteger) val).get());
} else if (val instanceof AtomicLong) {
prestmt.setObject(++i, ((AtomicLong) val).get());
} else {
prestmt.setObject(++i, val);
}
}
batchStatementParameters(conn, prestmt, info, attrs, value);
prestmt.addBatch();
}
return prestmt;
}
protected <T> int batchStatementParameters(Connection conn, PreparedStatement prestmt, EntityInfo<T> info, Attribute<T, Serializable>[] attrs, T value) throws SQLException {
int i = 0;
for (Attribute<T, Serializable> attr : attrs) {
Serializable val = attr.get(value);
if (val instanceof byte[]) {
Blob blob = conn.createBlob();
blob.setBytes(1, (byte[]) val);
prestmt.setObject(++i, blob);
} else if (val instanceof AtomicInteger) {
prestmt.setObject(++i, ((AtomicInteger) val).get());
} else if (val instanceof AtomicLong) {
prestmt.setObject(++i, ((AtomicLong) val).get());
} else if (val != null && !(val instanceof Number) && !(val instanceof CharSequence) && !(value instanceof java.util.Date)
&& !val.getClass().getName().startsWith("java.sql.") && !val.getClass().getName().startsWith("java.time.")) {
prestmt.setObject(++i, info.jsonConvert.convertTo(attr.genericType(), val));
} else {
prestmt.setObject(++i, val);
}
}
return i;
}
@Override
protected <T> CompletableFuture<Integer> deleteDB(EntityInfo<T> info, Flipper flipper, String sql) {
Connection conn = null;
@@ -224,21 +232,7 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
char[] sqlchars = debugfinest ? updateSQL.toCharArray() : null;
final Attribute<T, Serializable> primary = info.getPrimary();
for (final T value : values) {
int k = 0;
for (Attribute<T, Serializable> attr : attrs) {
Serializable val = attr.get(value);
if (val instanceof byte[]) {
Blob blob = conn.createBlob();
blob.setBytes(1, (byte[]) val);
prestmt.setObject(++k, blob);
} else if (val instanceof AtomicInteger) {
prestmt.setObject(++k, ((AtomicInteger) val).get());
} else if (val instanceof AtomicLong) {
prestmt.setObject(++k, ((AtomicLong) val).get());
} else {
prestmt.setObject(++k, val);
}
}
int k = batchStatementParameters(conn, prestmt, info, attrs, value);
prestmt.setObject(++k, primary.get(value));
prestmt.addBatch();//------------------------------------------------------------
if (debugfinest) { //打印调试信息
@@ -434,6 +428,9 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
if (blob != null) val = blob.getBytes(1, (int) blob.length());
} else {
val = (Serializable) set.getObject(1);
if (val != null && !CharSequence.class.isAssignableFrom(attr.type()) && (val instanceof CharSequence)) {
val = info.jsonConvert.convertFrom(attr.genericType(), val.toString());
}
}
}
set.close();

View File

@@ -56,11 +56,11 @@ public final class DataSources {
private DataSources() {
}
public static DataSource createDataSource2(final String unitName, Properties prop) throws IOException {
public static DataSource createDataSource(final String unitName, Properties prop) throws IOException {
return new DataJdbcSource(unitName, null, prop, prop);
}
public static DataSource createDataSource2(final String unitName, Properties readprop, Properties writeprop) throws IOException {
public static DataSource createDataSource(final String unitName, Properties readprop, Properties writeprop) throws IOException {
return new DataJdbcSource(unitName, null, readprop, writeprop);
}

View File

@@ -14,6 +14,7 @@ import java.util.concurrent.atomic.*;
import java.util.function.*;
import java.util.logging.*;
import javax.persistence.*;
import org.redkale.convert.json.*;
import org.redkale.util.*;
/**
@@ -28,6 +29,8 @@ import org.redkale.util.*;
@SuppressWarnings("unchecked")
public final class EntityInfo<T> {
private static final JsonConvert DEFAULT_JSON_CONVERT = JsonFactory.create().skipAllIgnore(true).getConvert();
//全局静态资源
private static final ConcurrentHashMap<Class, EntityInfo> entityInfos = new ConcurrentHashMap<>();
@@ -40,6 +43,9 @@ public final class EntityInfo<T> {
//类对应的数据表名, 如果是VirtualEntity 类, 则该字段为null
final String table;
//JsonConvert
final JsonConvert jsonConvert;
//Entity构建器
private final Creator<T> creator;
@@ -330,6 +336,25 @@ public final class EntityInfo<T> {
}
} while ((cltmp = cltmp.getSuperclass()) != Object.class);
if (idAttr0 == null) throw new RuntimeException(type.getName() + " have no primary column by @javax.persistence.Id");
cltmp = type;
JsonConvert convert = DEFAULT_JSON_CONVERT;
do {
for (Method method : cltmp.getDeclaredMethods()) {
if (method.getAnnotation(SourceConvert.class) == null) continue;
if (!Modifier.isStatic(method.getModifiers())) throw new RuntimeException("@SourceConvert method(" + method + ") must be static");
if (method.getReturnType() != JsonConvert.class) throw new RuntimeException("@SourceConvert method(" + method + ") must be return JsonConvert.class");
if (method.getParameterCount() > 0) throw new RuntimeException("@SourceConvert method(" + method + ") must be 0 parameter");
try {
method.setAccessible(true);
convert = (JsonConvert) method.invoke(null);
} catch (Exception e) {
throw new RuntimeException(method + " invoke error", e);
}
if (convert != null) break;
}
} while ((cltmp = cltmp.getSuperclass()) != Object.class);
this.jsonConvert = convert == null ? DEFAULT_JSON_CONVERT : convert;
this.primary = idAttr0;
this.aliasmap = aliasmap0;
this.attributes = attributeMap.values().toArray(new Attribute[attributeMap.size()]);
@@ -929,6 +954,9 @@ public final class EntityInfo<T> {
if (value == null) return null;
if (value instanceof CharSequence) {
return new StringBuilder().append('\'').append(value.toString().replace("'", "\\'")).append('\'').toString();
} else if (!(value instanceof Number) && !(value instanceof java.util.Date)
&& !value.getClass().getName().startsWith("java.sql.") && !value.getClass().getName().startsWith("java.time.")) {
return new StringBuilder().append('\'').append(jsonConvert.convertTo(value).replace("'", "\\'")).append('\'').toString();
}
return String.valueOf(value);
}
@@ -1026,6 +1054,8 @@ public final class EntityInfo<T> {
} else {
o = new AtomicLong();
}
} else if (o != null && !t.isAssignableFrom(o.getClass()) && o instanceof CharSequence) {
o = ((CharSequence) o).length() == 0 ? null : jsonConvert.convertFrom(attr.genericType(), o.toString());
}
}
return o;

View File

@@ -0,0 +1,28 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.source;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 用于定制Source操作JSON字段的转换策略。 <br>
* 只能依附在Entity类的静态无参数方法上, 且返回值必须是JsonConvert。 <br>
* 注意: 如果一个类有两个静态方法标记为&#64;SourceConvert 框架只会识别第一个。
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
*/
@Inherited
@Documented
@Target({METHOD})
@Retention(RUNTIME)
public @interface SourceConvert {
}