修正问题I8O88X、I8NYQE、I8MJNE

This commit is contained in:
inrgihc
2023-12-15 20:53:07 +08:00
parent d2e8b85cd3
commit 7b920bb733
5 changed files with 205 additions and 41 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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) {