diff --git a/hsweb-easy-orm-core/src/main/java/org/hswebframework/ezorm/core/ValueCodec.java b/hsweb-easy-orm-core/src/main/java/org/hswebframework/ezorm/core/ValueCodec.java index 0a09e05e..91359feb 100644 --- a/hsweb-easy-orm-core/src/main/java/org/hswebframework/ezorm/core/ValueCodec.java +++ b/hsweb-easy-orm-core/src/main/java/org/hswebframework/ezorm/core/ValueCodec.java @@ -12,6 +12,10 @@ default E encodeNull(){ D decode(Object data); + default E encodeNull(ColumnMetadata column){ + return encodeNull(); + } + default E encode(Object value, ColumnMetadata column){ return encode(value); } diff --git a/hsweb-easy-orm-core/src/main/java/org/hswebframework/ezorm/core/meta/AbstractColumnMetadata.java b/hsweb-easy-orm-core/src/main/java/org/hswebframework/ezorm/core/meta/AbstractColumnMetadata.java index b53f49c0..72dca46e 100644 --- a/hsweb-easy-orm-core/src/main/java/org/hswebframework/ezorm/core/meta/AbstractColumnMetadata.java +++ b/hsweb-easy-orm-core/src/main/java/org/hswebframework/ezorm/core/meta/AbstractColumnMetadata.java @@ -58,7 +58,7 @@ public Object decode(Object data) { public Object encode(Object data) { if (data == null) { if (valueCodec != null) { - return valueCodec.encodeNull(); + return valueCodec.encodeNull(this); } return null; } diff --git a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/codec/ClobValueCodec.java b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/codec/ClobValueCodec.java index bad3dc56..32b109c9 100644 --- a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/codec/ClobValueCodec.java +++ b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/codec/ClobValueCodec.java @@ -5,7 +5,10 @@ import lombok.SneakyThrows; import org.hswebframework.ezorm.core.ValueCodec; import org.hswebframework.ezorm.core.meta.ColumnMetadata; +import org.hswebframework.ezorm.rdb.executor.NullValue; +import org.hswebframework.ezorm.rdb.metadata.DataType; import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata; +import org.hswebframework.ezorm.rdb.supports.oracle.OracleDialect; import org.hswebframework.ezorm.rdb.utils.FeatureUtils; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -21,14 +24,29 @@ public class ClobValueCodec implements ValueCodec { public static final ClobValueCodec INSTANCE = new ClobValueCodec(); + public static boolean isClobType(DataType type) { + return type.getSqlType() == JDBCType.LONGVARCHAR || + type.getSqlType() == JDBCType.LONGNVARCHAR || + type.getSqlType() == JDBCType.CLOB; + } + + @Override + public Object encodeNull(ColumnMetadata column) { + if (column instanceof RDBColumnMetadata col) { + if (ClobValueCodec.isClobType(col.getType())) { + return NullValue.of(LongCharSequence.class, col.getType()); + } + return NullValue.of(col.getType()); + } + return null; + } + @Override public Object encode(Object value, ColumnMetadata column) { Object val = this.encode(value); if (val instanceof CharSequence cs && column instanceof RDBColumnMetadata col) { - if (col.getType().getSqlType() == JDBCType.LONGVARCHAR || - col.getType().getSqlType() == JDBCType.LONGNVARCHAR || - col.getType().getSqlType() == JDBCType.CLOB) { - return new ClobValue(cs); + if (ClobValueCodec.isClobType(col.getType())) { + return new LongCharSequence(cs); } } return val; diff --git a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/codec/JsonValueCodec.java b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/codec/JsonValueCodec.java index 1a384c82..4fb23001 100644 --- a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/codec/JsonValueCodec.java +++ b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/codec/JsonValueCodec.java @@ -11,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import org.hswebframework.ezorm.core.ValueCodec; import org.hswebframework.ezorm.core.meta.ColumnMetadata; +import org.hswebframework.ezorm.rdb.executor.NullValue; import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata; import org.hswebframework.ezorm.rdb.utils.FeatureUtils; import org.reactivestreams.Publisher; @@ -18,13 +19,13 @@ import reactor.core.publisher.Mono; import java.io.InputStream; +import java.io.Reader; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.nio.ByteBuffer; import java.sql.Blob; import java.sql.Clob; -import java.sql.JDBCType; import java.util.Collection; import java.util.Map; import java.util.TimeZone; @@ -104,15 +105,25 @@ public JsonValueCodec(Class targetType, JavaType type) { this.targetType = targetType; } + @Override + public Object encodeNull(ColumnMetadata column) { + if (column instanceof RDBColumnMetadata col) { + // clob 类型 + if (ClobValueCodec.isClobType(col.getType())) { + return NullValue.of(LongCharSequence.class, col.getType()); + } + return NullValue.of(col.getType()); + } + return ValueCodec.super.encodeNull(column); + } + @Override public Object encode(Object value, ColumnMetadata column) { Object data = encode(value); if (data instanceof CharSequence cs && column instanceof RDBColumnMetadata col) { // clob 类型 - if (col.getType().getSqlType() == JDBCType.LONGVARCHAR || - col.getType().getSqlType() == JDBCType.LONGNVARCHAR || - col.getType().getSqlType() == JDBCType.CLOB) { - return new ClobValue(cs); + if (ClobValueCodec.isClobType(col.getType())) { + return new LongCharSequence(cs); } } return data; @@ -149,27 +160,29 @@ public Object decode(Object data) { try { Object target = data; - if (data instanceof Clob) { - target = mapper.readValue(((Clob) data).getCharacterStream(), jacksonType); - } else if (data instanceof Blob) { - target = mapper.readValue(((Blob) data).getBinaryStream(), jacksonType); + if (data instanceof Clob _clob) { + target = mapper.readValue(_clob.getCharacterStream(), jacksonType); + } else if (data instanceof Blob _blob) { + target = mapper.readValue(_blob.getBinaryStream(), jacksonType); } else if (data instanceof InputStream) { target = mapper.readValue((InputStream) data, jacksonType); - } else if (data instanceof byte[]) { - target = mapper.readValue((byte[]) data, jacksonType); - } else if (data instanceof String) { - target = doRead(((String) data)); + } else if (data instanceof byte[] bytes) { + target = mapper.readValue(bytes, jacksonType); + } else if (data instanceof CharSequence) { + target = doRead(String.valueOf(data)); + } else if (data instanceof Reader reader) { + target = mapper.readValue(reader, jacksonType); } else if (data instanceof ByteBuffer) { return doRead(new ByteBufferBackedInputStream(((ByteBuffer) data))); } else if (FeatureUtils.r2dbcIsAlive()) { Mono mono = null; - if (data instanceof io.r2dbc.spi.Clob) { - mono = Flux.from(((io.r2dbc.spi.Clob) data).stream()) + if (data instanceof io.r2dbc.spi.Clob _clob) { + mono = Flux.from(_clob.stream()) .collect(Collectors.joining()) .map(this::doRead); - } else if (data instanceof io.r2dbc.spi.Blob) { - mono = Mono.from(((io.r2dbc.spi.Blob) data).stream()) + } else if (data instanceof io.r2dbc.spi.Blob _blob) { + mono = Mono.from(_blob.stream()) .map(ByteBufferBackedInputStream::new) .map(this::doRead); } @@ -194,6 +207,9 @@ public Object decode(Object data) { if (targetType == Flux.class) { return target == null ? Flux.empty() : Flux.just(target); } + if (target == null) { + return null; + } log.warn("unsupported json format:{}", data); return target; } catch (Throwable e) { diff --git a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/codec/ClobValue.java b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/codec/LongCharSequence.java similarity index 87% rename from hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/codec/ClobValue.java rename to hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/codec/LongCharSequence.java index 25ea44ac..9202cfff 100644 --- a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/codec/ClobValue.java +++ b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/codec/LongCharSequence.java @@ -1,18 +1,16 @@ package org.hswebframework.ezorm.rdb.codec; -import org.reactivestreams.Publisher; import reactor.util.annotation.NonNull; -import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.util.stream.IntStream; -public class ClobValue implements CharSequence { +public class LongCharSequence implements CharSequence { private final CharSequence charSequence; - public ClobValue(CharSequence charSequence) { + public LongCharSequence(CharSequence charSequence) { this.charSequence = charSequence; } diff --git a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/executor/NullValue.java b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/executor/NullValue.java index 1e5c16cd..762a4ac3 100644 --- a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/executor/NullValue.java +++ b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/executor/NullValue.java @@ -8,18 +8,21 @@ @Getter @AllArgsConstructor(staticName = "of") public class NullValue { - @Deprecated - private Class type; - @NonNull + private Class type; + private DataType dataType; - public static NullValue of(DataType dataType){ - return of(dataType.getJavaType(),dataType); + public static NullValue of(DataType dataType) { + return of(dataType.getJavaType(), dataType); + } + + public Class getType() { + return type == null ? dataType.getJavaType() : type; } @Override public String toString() { - return "null" + (dataType==null?"": (type != null ? "(" + dataType.getId() + ")" : "")); + return "null" + (type != null ? "("+type.getSimpleName()+")" : (dataType != null ? "(" + dataType.getId() + ")" : "")); } } diff --git a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/executor/jdbc/JdbcSqlExecutorHelper.java b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/executor/jdbc/JdbcSqlExecutorHelper.java index 17d02002..1f1e4123 100644 --- a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/executor/jdbc/JdbcSqlExecutorHelper.java +++ b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/executor/jdbc/JdbcSqlExecutorHelper.java @@ -1,12 +1,11 @@ package org.hswebframework.ezorm.rdb.executor.jdbc; import lombok.SneakyThrows; -import org.hswebframework.ezorm.rdb.codec.ClobValue; +import org.hswebframework.ezorm.rdb.codec.LongCharSequence; import org.hswebframework.ezorm.rdb.executor.NullValue; -import javax.sql.rowset.serial.SerialClob; import java.io.ByteArrayInputStream; -import java.io.CharArrayReader; +import java.io.StringReader; import java.sql.*; import java.util.ArrayList; import java.util.Date; @@ -38,18 +37,17 @@ protected static void preparedStatementParameter(PreparedStatement statement, Ob for (Object object : parameter) { if (object == null) { statement.setNull(index++, Types.NULL); - } else if (object instanceof NullValue) { - statement.setNull(index++, ((NullValue) object).getDataType().getSqlType().getVendorTypeNumber()); + } else if (object instanceof NullValue nullValue) { + statement.setNull(index++, nullValue.getDataType().getSqlType().getVendorTypeNumber()); } else if (object instanceof Date) { statement.setTimestamp(index++, new java.sql.Timestamp(((Date) object).getTime())); } else if (object instanceof byte[] b) { statement.setBlob(index++, new ByteArrayInputStream(b)); - } else if (object instanceof ClobValue cb) { + } else if (object instanceof LongCharSequence cb) { statement.setCharacterStream(index++, cb.reader()); } else { statement.setObject(index++, object); } - } } diff --git a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/executor/reactive/r2dbc/R2dbcReactiveSqlExecutor.java b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/executor/reactive/r2dbc/R2dbcReactiveSqlExecutor.java index 1f5d87fd..cd3bfbf0 100644 --- a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/executor/reactive/r2dbc/R2dbcReactiveSqlExecutor.java +++ b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/executor/reactive/r2dbc/R2dbcReactiveSqlExecutor.java @@ -5,7 +5,7 @@ import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.hswebframework.ezorm.core.CastUtil; -import org.hswebframework.ezorm.rdb.codec.ClobValue; +import org.hswebframework.ezorm.rdb.codec.LongCharSequence; import org.hswebframework.ezorm.rdb.executor.BatchSqlRequest; import org.hswebframework.ezorm.rdb.executor.DefaultColumnWrapperContext; import org.hswebframework.ezorm.rdb.executor.NullValue; @@ -251,11 +251,18 @@ protected Statement prepareStatement(Statement statement, SqlRequest request) { for (Object parameter : request.getParameters()) { if (parameter == null) { bindNull(statement, index, String.class); - } else if (parameter instanceof NullValue) { - bindNull(statement, index, ((NullValue) parameter).getDataType().getJavaType()); + } else if (parameter instanceof NullValue nullValue) { + Class javaType = nullValue.getType(); + if (javaType == LongCharSequence.class) { + // 空字符,批量保存时,有的数据库不同行不能有的设置null有的不设置. + bindNull(statement, index, Clob.class); + }else { + bindNull(statement, index, javaType); + } + } else { // convert clob - if (parameter instanceof ClobValue cb) { + if (parameter instanceof LongCharSequence cb) { parameter = Clob.from(Mono.just(cb.source())); } bind(statement, index, parameter); diff --git a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/metadata/RDBColumnMetadata.java b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/metadata/RDBColumnMetadata.java index 4755e227..7799c3bb 100644 --- a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/metadata/RDBColumnMetadata.java +++ b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/metadata/RDBColumnMetadata.java @@ -221,7 +221,7 @@ public RDBColumnMetadata clone() { public Object encode(Object data) { if (data == null || data instanceof NullValue) { if (valueCodec != null) { - Object newVal = valueCodec.encodeNull(); + Object newVal = valueCodec.encodeNull(this); if (newVal != null) { return newVal; } diff --git a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleBatchUpsertOperator.java b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleBatchUpsertOperator.java index bd825b2a..ca9a3a5e 100644 --- a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleBatchUpsertOperator.java +++ b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleBatchUpsertOperator.java @@ -1,8 +1,11 @@ package org.hswebframework.ezorm.rdb.supports.oracle; +import io.r2dbc.mssql.codec.ClobCodec; import lombok.AllArgsConstructor; import org.hswebframework.ezorm.core.RuntimeDefaultValue; import org.hswebframework.ezorm.core.param.Term; +import org.hswebframework.ezorm.rdb.codec.ClobValueCodec; +import org.hswebframework.ezorm.rdb.codec.LongCharSequence; import org.hswebframework.ezorm.rdb.executor.NullValue; import org.hswebframework.ezorm.rdb.executor.SqlRequest; import org.hswebframework.ezorm.rdb.executor.SyncSqlExecutor; @@ -188,9 +191,15 @@ public SqlRequest build(InsertOperatorParameter parameter) { value = NullValue.of(column.getType()); } } - + value = column.encode(value); + // 适配 clob字段 不支持设置null + if (valueSize > 1 && (value == null || value instanceof NullValue)) { + if (ClobValueCodec.isClobType(column.getType())) { + value = new LongCharSequence(""); + } + } fragments.addSql("? as ", column.getQuoteName()) - .addParameter(column.encode(value)); + .addParameter(value); valueIndex++; } diff --git a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleInsertSqlBuilder.java b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleInsertSqlBuilder.java index fbb42000..6b2ade05 100644 --- a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleInsertSqlBuilder.java +++ b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleInsertSqlBuilder.java @@ -3,6 +3,8 @@ import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.hswebframework.ezorm.core.RuntimeDefaultValue; +import org.hswebframework.ezorm.rdb.codec.ClobValueCodec; +import org.hswebframework.ezorm.rdb.codec.LongCharSequence; import org.hswebframework.ezorm.rdb.executor.NullValue; import org.hswebframework.ezorm.rdb.executor.SqlRequest; import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata; @@ -126,7 +128,14 @@ public SqlRequest build(InsertOperatorParameter parameter) { if (value == null) { value = NullValue.of(column.getType()); } - valuesSql.add(SqlFragments.QUESTION_MARK).addParameter(column.encode(value)); + value = column.encode(value); + // 适配 clob字段 不支持设置null + if (valueSize > 1 && (value == null || value instanceof NullValue)) { + if (ClobValueCodec.isClobType(column.getType())) { + value = new LongCharSequence(""); + } + } + valuesSql.add(SqlFragments.QUESTION_MARK).addParameter(value); } intoSql.add(SqlFragments.RIGHT_BRACKET); valuesSql.add(SqlFragments.RIGHT_BRACKET); diff --git a/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/BasicCommonTests.java b/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/BasicCommonTests.java index be08cd8d..c799a072 100644 --- a/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/BasicCommonTests.java +++ b/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/BasicCommonTests.java @@ -14,6 +14,7 @@ import org.hswebframework.ezorm.rdb.mapping.MappingFeatureType; import org.hswebframework.ezorm.rdb.mapping.SyncRepository; import org.hswebframework.ezorm.rdb.mapping.defaults.DefaultSyncRepository; +import org.hswebframework.ezorm.rdb.mapping.defaults.SaveResult; import org.hswebframework.ezorm.rdb.mapping.defaults.record.Record; import org.hswebframework.ezorm.rdb.mapping.defaults.record.RecordResultWrapper; import org.hswebframework.ezorm.rdb.mapping.jpa.JpaEntityTableMetadataParser; @@ -107,8 +108,8 @@ public void init() { }); RDBTableMetadata table = parser - .parseTableMetadata(BasicTestEntity.class) - .orElseThrow(NullPointerException::new); + .parseTableMetadata(BasicTestEntity.class) + .orElseThrow(NullPointerException::new); // table.addFeature((EventListener) (type, context) -> log.debug("event:{},context:{}", type, context)); @@ -117,10 +118,10 @@ public void init() { .commit() .sync(); NestedEntityResultWrapper wrapper = - table - .getFeature(MappingFeatureType.columnPropertyMapping.createFeatureId(BasicTestEntity.class)) - .map(mapping -> new NestedEntityResultWrapper(mapping)) - .orElseThrow(NullPointerException::new); + table + .getFeature(MappingFeatureType.columnPropertyMapping.createFeatureId(BasicTestEntity.class)) + .map(mapping -> new NestedEntityResultWrapper(mapping)) + .orElseThrow(NullPointerException::new); repository = new DefaultSyncRepository<>(operator, table, BasicTestEntity.class, wrapper); addressRepository = operator.dml().createRepository("test_address"); @@ -145,17 +146,17 @@ public void after() { @Test public void testRepositoryInsertBach() { List entities = Flux - .range(0, 100) - .map(integer -> BasicTestEntity.builder() - // .id("test_id_" + integer) - .balance(1000L) - .name("test:" + integer) - .createTime(new Date()) - .tags(Arrays.asList("a", "b", "c", "d")) - .state((byte) 1) - // .stateEnum(StateEnum.enabled) - .build()) - .collectList().block(); + .range(0, 100) + .map(integer -> BasicTestEntity.builder() + // .id("test_id_" + integer) + .balance(1000L) + .name("test:" + integer) + .createTime(new Date()) + .tags(Arrays.asList("a", "b", "c", "d")) + .state((byte) 1) + // .stateEnum(StateEnum.enabled) + .build()) + .collectList().block(); Assert.assertEquals(100, repository.insertBatch(entities)); } @@ -163,19 +164,19 @@ public void testRepositoryInsertBach() { public void testInsertDuplicate() { //10次insert Assert.assertEquals(3, repository.insertBatch( - Stream - .of(1, 2, 2, 3, 1, 3) - .map(integer -> BasicTestEntity - .builder() - .id("test_dup_" + integer) - .balance(1000L) - .name("test2:" + integer) - .createTime(new Date()) - .tags(Arrays.asList("a", "b", "c", "d")) - .state((byte) 1) - .stateEnum(StateEnum.enabled) - .build()) - .collect(Collectors.toList()) + Stream + .of(1, 2, 2, 3, 1, 3) + .map(integer -> BasicTestEntity + .builder() + .id("test_dup_" + integer) + .balance(1000L) + .name("test2:" + integer) + .createTime(new Date()) + .tags(Arrays.asList("a", "b", "c", "d")) + .state((byte) 1) + .stateEnum(StateEnum.enabled) + .build()) + .collect(Collectors.toList()) )); ; @@ -185,32 +186,77 @@ public void testInsertDuplicate() { .execute()); } + @Test + public void testRepositoryBatchSave() { + BasicTestEntity e1 = BasicTestEntity + .builder() + .id("test_id_batch_save") +// .balance(1000L) + .name("test") +// .createTime(new Date()) + .tags(Arrays.asList("a", "b", "c", "d")) + .state((byte) 1) +// .addressId("test") +// .stateEnum(StateEnum.enabled) +// .enabled(true) + .build(); + + BasicTestEntity e2 = BasicTestEntity + .builder() + .id("test_id_batch_save_2") +// .balance(1000L) + .name("test") +// .createTime(new Date()) + .tags(null) + .state((byte) 1) +// .addressId("test") +// .stateEnum(StateEnum.enabled) +// .enabled(true) + .build(); + + + Assert.assertEquals(2, repository.save(e1, e2).getTotal()); + + getSqlExecutor() + .select("select * from entity_test_table where id in(?,?)",e1.getId(),e2.getId()) + .forEach(System.out::println); + + repository + .createQuery() + .select("id","tags") + .where() + .in("id", Arrays.asList(e1.getId(), e2.getId())) + .fetch() + .forEach(System.out::println); + + } + @Test public void testRepositorySave() { BasicTestEntity entity = BasicTestEntity - .builder() - .id("test_id_save") - .balance(1000L) - .name("test") - .createTime(new Date()) - .tags(Arrays.asList("a", "b", "c", "d")) - .state((byte) 1) + .builder() + .id("test_id_save") + .balance(1000L) + .name("test") + .createTime(new Date()) + .tags(Arrays.asList("a", "b", "c", "d")) + .state((byte) 1) // .aTest("test") - .addressId("test") - .doubleVal(1D) - .bigDecimal(new BigDecimal("1.2")) - .stateEnum(StateEnum.enabled) - .stateEnums(new StateEnum[]{StateEnum.enabled}) - .build(); + .addressId("test") + .doubleVal(1D) + .bigDecimal(new BigDecimal("1.2")) + .stateEnum(StateEnum.enabled) + .stateEnums(new StateEnum[]{StateEnum.enabled}) + .build(); Assert.assertEquals(repository.save(entity).getTotal(), 1); { BasicTestEntity inBase = repository - .createQuery() - .select("*") - .where("id", entity.getId()) - .fetchOne() - .orElseThrow(UnsupportedOperationException::new); + .createQuery() + .select("*") + .where("id", entity.getId()) + .fetchOne() + .orElseThrow(UnsupportedOperationException::new); Assert.assertEquals(entity, inBase); @@ -220,11 +266,11 @@ public void testRepositorySave() { Assert.assertEquals(repository.save(entity).getTotal(), 1); BasicTestEntity inBase = repository - .createQuery() - .select("*") - .where("id", entity.getId()) - .fetchOne() - .orElseThrow(UnsupportedOperationException::new); + .createQuery() + .select("*") + .where("id", entity.getId()) + .fetchOne() + .orElseThrow(UnsupportedOperationException::new); Assert.assertEquals(StateEnum.enabled, inBase.getStateEnum()); @@ -234,48 +280,48 @@ public void testRepositorySave() { @Test public void testEnums() { BasicTestEntity entity = BasicTestEntity - .builder() - .id("enums_id") - .balance(1000L) - .name("test") - .createTime(new Date()) - .tags(Arrays.asList("a", "b", "c", "d")) - .state((byte) 1) - .addressId("test") - .stateEnum(StateEnum.enabled) - .stateEnums(new StateEnum[]{StateEnum.enabled, StateEnum.disabled}) - .build(); + .builder() + .id("enums_id") + .balance(1000L) + .name("test") + .createTime(new Date()) + .tags(Arrays.asList("a", "b", "c", "d")) + .state((byte) 1) + .addressId("test") + .stateEnum(StateEnum.enabled) + .stateEnums(new StateEnum[]{StateEnum.enabled, StateEnum.disabled}) + .build(); repository.insert(entity); Assert.assertFalse(repository - .createQuery() - .select("id", "stateEnums") - .in(BasicTestEntity::getStateEnums, StateEnum.enabled) - .fetchOne() - .isPresent()); + .createQuery() + .select("id", "stateEnums") + .in(BasicTestEntity::getStateEnums, StateEnum.enabled) + .fetchOne() + .isPresent()); Assert.assertTrue(repository - .createQuery() - .select("id", "stateEnums") - .in(BasicTestEntity::getStateEnums, StateEnum.enabled, StateEnum.disabled) - .fetchOne() - .isPresent()); + .createQuery() + .select("id", "stateEnums") + .in(BasicTestEntity::getStateEnums, StateEnum.enabled, StateEnum.disabled) + .fetchOne() + .isPresent()); Assert.assertTrue(repository - .createQuery() - .select("id", "stateEnums") - .where(Terms.enumInAny(BasicTestEntity::getStateEnums, StateEnum.disabled)) - .fetchOne() - .isPresent()); + .createQuery() + .select("id", "stateEnums") + .where(Terms.enumInAny(BasicTestEntity::getStateEnums, StateEnum.disabled)) + .fetchOne() + .isPresent()); Assert.assertTrue(repository - .createQuery() - .select("id", "stateEnums") - .where(Terms.enumNotInAny(BasicTestEntity::getStateEnums, StateEnum.warn)) - .fetchOne() - .isPresent()); + .createQuery() + .select("id", "stateEnums") + .where(Terms.enumNotInAny(BasicTestEntity::getStateEnums, StateEnum.warn)) + .fetchOne() + .isPresent()); } @@ -284,16 +330,16 @@ public void testEnums() { public void testJoin() { BasicTestEntity entity = BasicTestEntity - .builder() - .id("joinTest") - .balance(1000L) - .name("test") - .createTime(new Date()) - .tags(Arrays.asList("a", "b", "c", "d")) - .state((byte) 1) - .addressId("joinTest") - .stateEnum(StateEnum.enabled) - .build(); + .builder() + .id("joinTest") + .balance(1000L) + .name("test") + .createTime(new Date()) + .tags(Arrays.asList("a", "b", "c", "d")) + .state((byte) 1) + .addressId("joinTest") + .stateEnum(StateEnum.enabled) + .build(); addressRepository.insert(Record.newRecord().putValue("id", "joinTest").putValue("name", "joinTest")); repository.insert(entity); @@ -309,16 +355,16 @@ public void testRepositoryCurd() { BasicTestEntity entity = BasicTestEntity - .builder() - .id("test_id") - .balance(1000L) - .name("test") - .createTime(new Date()) - .tags(Arrays.asList("a", "b", "c", "d")) - .state((byte) 1) - .addressId("test") - .stateEnum(StateEnum.enabled) - .build(); + .builder() + .id("test_id") + .balance(1000L) + .name("test") + .createTime(new Date()) + .tags(Arrays.asList("a", "b", "c", "d")) + .state((byte) 1) + .addressId("test") + .stateEnum(StateEnum.enabled) + .build(); addressRepository.insert(Record.newRecord().putValue("id", "test").putValue("name", "test_address")); repository.insert(entity); @@ -392,9 +438,9 @@ public void testPager() { } finally { try { operator - .sql() - .sync() - .execute(SqlRequests.of("drop table " + database.getCurrentSchema().getName() + ".test_pager")); + .sql() + .sync() + .execute(SqlRequests.of("drop table " + database.getCurrentSchema().getName() + ".test_pager")); } catch (Exception e) { e.printStackTrace(); } @@ -454,11 +500,11 @@ public void testCrud() { } finally { try { operator - .sql() - .sync() - .execute(SqlRequests.of("drop table " + database - .getCurrentSchema() - .getName() + ".test_dml_crud")); + .sql() + .sync() + .execute(SqlRequests.of("drop table " + database + .getCurrentSchema() + .getName() + ".test_dml_crud")); } catch (Exception e) { e.printStackTrace(); } @@ -512,11 +558,11 @@ public void testDDL() { } finally { try { operator - .sql() - .sync() - .execute(SqlRequests.of("drop table " + database - .getCurrentSchema() - .getName() + ".test_ddl_create")); + .sql() + .sync() + .execute(SqlRequests.of("drop table " + database + .getCurrentSchema() + .getName() + ".test_ddl_create")); } catch (Exception e) { e.printStackTrace(); } diff --git a/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/BasicReactiveTests.java b/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/BasicReactiveTests.java index 6cb5e1a1..0fba4bea 100644 --- a/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/BasicReactiveTests.java +++ b/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/BasicReactiveTests.java @@ -359,6 +359,43 @@ public void testRepositoryInsertBach() { } + @Test + public void testReactiveRepositoryBatchSave() { + BasicTestEntity e1 = BasicTestEntity + .builder() + .id("test_id_batch_save") +// .balance(1000L) + .name("test") +// .createTime(new Date()) + .tags(Arrays.asList("a", "b", "c", "d")) + .state((byte) 1) +// .addressId("test") +// .stateEnum(StateEnum.enabled) +// .enabled(true) + .build(); + + BasicTestEntity e2 = BasicTestEntity + .builder() + .id("test_id_batch_save_2") +// .balance(1000L) + .name("test") +// .createTime(new Date()) + .tags(null) + .state((byte) 1) +// .addressId("test") +// .stateEnum(StateEnum.enabled) +// .enabled(true) + .build(); + + + repository.save(Flux.just(e1, e2)) + .map(SaveResult::getTotal) + .as(StepVerifier::create) + .expectNext(2) + .verifyComplete(); + + + } @Test public void testReactiveRepositorySave() { diff --git a/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleConnectionProvider.java b/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleConnectionProvider.java index e06de83c..6da859c4 100644 --- a/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleConnectionProvider.java +++ b/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleConnectionProvider.java @@ -23,25 +23,23 @@ public class OracleConnectionProvider implements ConnectionProvider { static { try { Class.forName("oracle.jdbc.driver.OracleDriver"); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - GenericContainer container = Containers.newOracle(); - - container.start(); - port = container.getMappedPort(1521); - - String username = System.getProperty("oracle.username", "system"); - String password = System.getProperty("oracle.password", "oracle"); - String url = System.getProperty("oracle.url", "127.0.0.1:" + port); - String db = System.getProperty("oracle.db", "orcl"); - connectionSupplier = () -> DriverManager.getConnection("jdbc:oracle:thin:@" + url + ":" + db, username, password); - for (int i = 0; i < 10; i++) { - try { + + GenericContainer container = Containers.newOracle(); + + container.start(); + port = container.getMappedPort(1521); + + String username = System.getProperty("oracle.username", "system"); + String password = System.getProperty("oracle.password", "oracle"); + String url = System.getProperty("oracle.url", "127.0.0.1:" + port); + String db = System.getProperty("oracle.db", "orcl"); + connectionSupplier = () -> DriverManager.getConnection("jdbc:oracle:thin:@" + url + ":" + db, username, password); + for (int i = 0; i < 10; i++) { connectionQueue.add(connectionSupplier.call()); - } catch (Exception e) { - throw new RuntimeException(e); + } + } catch (Throwable e) { + e.printStackTrace(); } } diff --git a/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleR2dbcConnectionProvider.java b/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleR2dbcConnectionProvider.java index f13659fd..819587b8 100644 --- a/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleR2dbcConnectionProvider.java +++ b/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleR2dbcConnectionProvider.java @@ -33,15 +33,16 @@ public OracleR2dbcConnectionProvider() { URL hostUrl = new URL("file://" + url); - connectionFactory = ConnectionFactories.get(ConnectionFactoryOptions - .builder() - .option(DRIVER, "oracle") - .option(HOST, hostUrl.getHost()) - .option(PORT, hostUrl.getPort()) - .option(USER, username) - .option(PASSWORD, password) - .option(DATABASE, db) - .build()); + connectionFactory = ConnectionFactories + .get(ConnectionFactoryOptions + .builder() + .option(DRIVER, "oracle") + .option(HOST, hostUrl.getHost()) + .option(PORT, hostUrl.getPort()) + .option(USER, username) + .option(PASSWORD, password) + .option(DATABASE, db) + .build()); connectionSupplier = Mono.from(connectionFactory.create()); diff --git a/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleReactiveTests.java b/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleReactiveTests.java index 5029e69f..c8aa0f2f 100644 --- a/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleReactiveTests.java +++ b/hsweb-easy-orm-rdb/src/test/java/org/hswebframework/ezorm/rdb/supports/oracle/OracleReactiveTests.java @@ -36,7 +36,7 @@ protected Dialect getDialect() { protected ReactiveSqlExecutor getSqlExecutor() { return new TestJdbcReactiveSqlExecutor(new OracleConnectionProvider()); - +// // return new TestReactiveSqlExecutor(":",new OracleR2dbcConnectionProvider()){ // @Override // protected void bindNull(Statement statement, int index, Class type) {