mirror of
https://gitee.com/dromara/dbswitch.git
synced 2025-09-27 14:11:33 +00:00
修正问题I8O88X、I8NYQE、I8MJNE
This commit is contained in:
@@ -933,6 +933,7 @@ public final class ObjectCastUtils {
|
||||
|
||||
public static Object castByJdbcType(int jdbcType, Object value) {
|
||||
switch (jdbcType) {
|
||||
case Types.BIT:
|
||||
case Types.TINYINT:
|
||||
return convert(value, ObjectCastUtils::castToByte);
|
||||
case Types.SMALLINT:
|
||||
@@ -950,7 +951,6 @@ public final class ObjectCastUtils {
|
||||
case Types.DOUBLE:
|
||||
return convert(value, ObjectCastUtils::castToDouble);
|
||||
case Types.BOOLEAN:
|
||||
case Types.BIT:
|
||||
return convert(value, ObjectCastUtils::castToBoolean);
|
||||
case Types.TIME:
|
||||
return convert(value, ObjectCastUtils::castToLocalTime);
|
||||
|
@@ -22,6 +22,9 @@ import com.gitee.dbswitch.service.MetadataService;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -480,6 +483,24 @@ public final class DefaultChangeCalculatorService implements RecordRowChangeCalc
|
||||
java.lang.Number s2 = (java.lang.Number) o2;
|
||||
return Long.compare(s1.longValue(), s2.longValue());
|
||||
} else if (JdbcTypesUtils.isDateTime(type)) {
|
||||
if (o1 instanceof LocalTime) {
|
||||
o1 = java.sql.Time.valueOf((LocalTime) o1);
|
||||
}
|
||||
if (o1 instanceof LocalDate) {
|
||||
o1 = java.sql.Date.valueOf((LocalDate) o1);
|
||||
}
|
||||
if (o1 instanceof LocalDateTime) {
|
||||
o1 = java.sql.Timestamp.valueOf((LocalDateTime) o1);
|
||||
}
|
||||
if (o2 instanceof LocalTime) {
|
||||
o2 = java.sql.Time.valueOf((LocalTime) o2);
|
||||
}
|
||||
if (o2 instanceof LocalDate) {
|
||||
o2 = java.sql.Date.valueOf((LocalDate) o2);
|
||||
}
|
||||
if (o2 instanceof LocalDateTime) {
|
||||
o2 = java.sql.Timestamp.valueOf((LocalDateTime) o2);
|
||||
}
|
||||
if (o1 instanceof java.sql.Time && o2 instanceof java.sql.Time) {
|
||||
java.sql.Time t1 = (java.sql.Time) o1;
|
||||
java.sql.Time t2 = (java.sql.Time) o2;
|
||||
|
@@ -9,6 +9,7 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
package com.gitee.dbswitch.provider.sync;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.gitee.dbswitch.common.type.ProductTypeEnum;
|
||||
import com.gitee.dbswitch.provider.AbstractCommonProvider;
|
||||
import com.gitee.dbswitch.provider.ProductFactoryProvider;
|
||||
@@ -105,15 +106,24 @@ public class DefaultTableDataSynchronizeProvider
|
||||
}
|
||||
|
||||
try {
|
||||
int[] affects = jdbcTemplate
|
||||
.batchUpdate(this.insertStatementSql, records, this.insertArgsType);
|
||||
int affectCount = 0;
|
||||
for (int i : affects) {
|
||||
affectCount += i;
|
||||
try {
|
||||
jdbcTemplate.batchUpdate(this.insertStatementSql, records, this.insertArgsType);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof java.sql.BatchUpdateException) {
|
||||
for (Object[] dataList : records) {
|
||||
try {
|
||||
jdbcTemplate.update(this.insertStatementSql, dataList, this.updateArgsType);
|
||||
} catch (Exception ex) {
|
||||
log.error("Failed to insert by SQL: {}, value: {}", this.insertStatementSql,
|
||||
JSONUtil.toJsonStr(dataList));
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tx.commit(status);
|
||||
return affectCount;
|
||||
return records.size();
|
||||
} catch (TransactionException e) {
|
||||
tx.rollback(status);
|
||||
throw e;
|
||||
@@ -150,13 +160,24 @@ public class DefaultTableDataSynchronizeProvider
|
||||
}
|
||||
|
||||
try {
|
||||
int[] affects = jdbcTemplate.batchUpdate(this.updateStatementSql, dataLists, this.updateArgsType);
|
||||
int affectCount = 0;
|
||||
for (int i : affects) {
|
||||
affectCount += i;
|
||||
try {
|
||||
jdbcTemplate.batchUpdate(this.updateStatementSql, dataLists, this.updateArgsType);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof java.sql.BatchUpdateException) {
|
||||
for (Object[] dataList : dataLists) {
|
||||
try {
|
||||
jdbcTemplate.update(this.updateStatementSql, dataList, this.updateArgsType);
|
||||
} catch (Exception ex) {
|
||||
log.error("Failed to update by SQL: {}, value: {}", this.updateStatementSql,
|
||||
JSONUtil.toJsonStr(dataList));
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tx.commit(status);
|
||||
return affectCount;
|
||||
return dataLists.size();
|
||||
} catch (TransactionException e) {
|
||||
tx.rollback(status);
|
||||
throw e;
|
||||
@@ -185,14 +206,9 @@ public class DefaultTableDataSynchronizeProvider
|
||||
}
|
||||
|
||||
try {
|
||||
int[] affects = jdbcTemplate.batchUpdate(this.deleteStatementSql, dataLists, this.deleteArgsType);
|
||||
int affectCount = 0;
|
||||
for (int i : affects) {
|
||||
affectCount += i;
|
||||
}
|
||||
|
||||
jdbcTemplate.batchUpdate(this.deleteStatementSql, dataLists, this.deleteArgsType);
|
||||
tx.commit(status);
|
||||
return affectCount;
|
||||
return dataLists.size();
|
||||
} catch (TransactionException e) {
|
||||
tx.rollback(status);
|
||||
throw e;
|
||||
|
@@ -1,11 +1,21 @@
|
||||
package com.gitee.dbswitch.product.oracle;
|
||||
|
||||
import com.gitee.dbswitch.common.util.JdbcTypesUtils;
|
||||
import com.gitee.dbswitch.common.util.ObjectCastUtils;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.Date;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -18,7 +28,7 @@ public class OracleCastUtils {
|
||||
/**
|
||||
* 将java.sql.Array 类型转换为java.lang.String
|
||||
* <p>
|
||||
* Oracle 没有数组类型,这里以文本类型进行存在
|
||||
* Oracle 没有数组类型,这里以文本类型进行存储
|
||||
* <p>
|
||||
* Oracle的CLOB和BLOB类型写入请见:
|
||||
* <p>
|
||||
@@ -29,28 +39,137 @@ public class OracleCastUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (jdbcType == Types.BLOB) {
|
||||
try {
|
||||
final byte[] bytes = ObjectCastUtils.castToByteArray(value);
|
||||
switch (jdbcType) {
|
||||
case Types.NUMERIC:
|
||||
return new SqlTypeValue() {
|
||||
@Override
|
||||
public void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType,
|
||||
String typeName) throws SQLException {
|
||||
if (null != bytes) {
|
||||
InputStream is = new ByteArrayInputStream(bytes);
|
||||
ps.setBlob(paramIndex, is);
|
||||
iss.add(is);
|
||||
public void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName)
|
||||
throws SQLException {
|
||||
if (value instanceof Byte) {
|
||||
ps.setByte(paramIndex, (Byte) value);
|
||||
} else if (value instanceof Short) {
|
||||
ps.setShort(paramIndex, (Short) value);
|
||||
} else if (value instanceof Integer) {
|
||||
ps.setInt(paramIndex, (Integer) value);
|
||||
} else if (value instanceof BigInteger) {
|
||||
ps.setInt(paramIndex, ((BigInteger) value).intValue());
|
||||
} else if (value instanceof Long) {
|
||||
ps.setLong(paramIndex, (Long) value);
|
||||
} else if (value instanceof Float) {
|
||||
ps.setFloat(paramIndex, (Float) value);
|
||||
} else if (value instanceof Double) {
|
||||
ps.setDouble(paramIndex, (Double) value);
|
||||
} else if (value instanceof BigDecimal) {
|
||||
ps.setBigDecimal(paramIndex, (BigDecimal) value);
|
||||
} else {
|
||||
ps.setNull(paramIndex, sqlType);
|
||||
ps.setObject(paramIndex, value, sqlType);
|
||||
}
|
||||
}
|
||||
};
|
||||
} catch (Exception e) {
|
||||
log.warn("Convert from {} to Oracle BLOB failed:{}", value.getClass().getName(), e.getMessage());
|
||||
case Types.TIME:
|
||||
return new SqlTypeValue() {
|
||||
@Override
|
||||
public void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName)
|
||||
throws SQLException {
|
||||
if (value instanceof Time) {
|
||||
ps.setTime(paramIndex, (Time) value);
|
||||
} else {
|
||||
LocalTime time = ObjectCastUtils.castToLocalTime(value);
|
||||
if (null == time) {
|
||||
ps.setNull(paramIndex, jdbcType);
|
||||
} else {
|
||||
ps.setTime(paramIndex, Time.valueOf(time));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
case Types.DATE:
|
||||
return new SqlTypeValue() {
|
||||
@Override
|
||||
public void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName)
|
||||
throws SQLException {
|
||||
if (value instanceof Date) {
|
||||
ps.setDate(paramIndex, (Date) value);
|
||||
} else {
|
||||
LocalDate date = ObjectCastUtils.castToLocalDate(value);
|
||||
if (null == date) {
|
||||
ps.setNull(paramIndex, jdbcType);
|
||||
} else {
|
||||
ps.setDate(paramIndex, Date.valueOf(date));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
case Types.TIMESTAMP:
|
||||
return new SqlTypeValue() {
|
||||
@Override
|
||||
public void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName)
|
||||
throws SQLException {
|
||||
if (value instanceof Timestamp) {
|
||||
ps.setTimestamp(paramIndex, (Timestamp) value);
|
||||
} else {
|
||||
LocalDateTime dateTime = ObjectCastUtils.castToLocalDateTime(value);
|
||||
if (null == dateTime) {
|
||||
ps.setNull(paramIndex, jdbcType);
|
||||
} else {
|
||||
ps.setTimestamp(paramIndex, Timestamp.valueOf(dateTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
case Types.BLOB:
|
||||
return new SqlTypeValue() {
|
||||
@Override
|
||||
public void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName)
|
||||
throws SQLException {
|
||||
if (value instanceof java.sql.Blob) {
|
||||
ps.setBlob(paramIndex, (java.sql.Blob) value);
|
||||
} else {
|
||||
InputStream is = new ByteArrayInputStream(ObjectCastUtils.castToByteArray(value));
|
||||
ps.setBlob(paramIndex, is);
|
||||
iss.add(is);
|
||||
}
|
||||
}
|
||||
};
|
||||
case Types.CLOB:
|
||||
return new SqlTypeValue() {
|
||||
@Override
|
||||
public void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName)
|
||||
throws SQLException {
|
||||
if (value instanceof java.sql.Clob) {
|
||||
ps.setClob(paramIndex, (java.sql.Clob) value);
|
||||
} else {
|
||||
java.io.Reader reader = new StringReader(ObjectCastUtils.castToString(value));
|
||||
ps.setClob(paramIndex, reader);
|
||||
}
|
||||
}
|
||||
};
|
||||
case Types.NCLOB:
|
||||
return new SqlTypeValue() {
|
||||
@Override
|
||||
public void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName)
|
||||
throws SQLException {
|
||||
if (value instanceof java.sql.NClob) {
|
||||
ps.setNClob(paramIndex, (java.sql.NClob) value);
|
||||
} else {
|
||||
java.io.Reader reader = new StringReader(ObjectCastUtils.castToString(value));
|
||||
ps.setNClob(paramIndex, reader);
|
||||
}
|
||||
}
|
||||
};
|
||||
default:
|
||||
return ObjectCastUtils.castByJdbcType(jdbcType, value);
|
||||
}
|
||||
} catch (
|
||||
Exception e) {
|
||||
log.warn("Convert from {} to Oracle {} failed: {}",
|
||||
value.getClass().getName(),
|
||||
JdbcTypesUtils.resolveTypeName(jdbcType),
|
||||
e.getMessage()
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return ObjectCastUtils.castByJdbcType(jdbcType, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -286,7 +286,11 @@ public class PostgresTableCopyWriteProvider extends DefaultTableDataWriteProvide
|
||||
case Types.BOOLEAN:
|
||||
case Types.BIT:
|
||||
if (null == fieldValue) {
|
||||
if (Types.BIT == fieldType) {
|
||||
row.setByte(i, null);
|
||||
} else {
|
||||
row.setBoolean(i, null);
|
||||
}
|
||||
} else {
|
||||
Boolean val = null;
|
||||
try {
|
||||
@@ -301,8 +305,12 @@ public class PostgresTableCopyWriteProvider extends DefaultTableDataWriteProvide
|
||||
"表名[%s.%s]的字段名[%s]数据类型错误,应该为java.lang.Boolean,而实际的数据类型为%s", schemaName,
|
||||
tableName, fieldName, fieldValue.getClass().getName()));
|
||||
}
|
||||
if (Types.BIT == fieldType) {
|
||||
row.setByte(i, val ? Byte.valueOf((byte) 1) : Byte.valueOf((byte) 0));
|
||||
} else {
|
||||
row.setBoolean(i, val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Types.TIME:
|
||||
if (null == fieldValue) {
|
||||
|
Reference in New Issue
Block a user