[新会话] @SKSlience,在Sharding-JDBC中,我们可以使用SQLTypeHandler接口来自定义类型转换器,从而实现类型转换的自定义。
下面是一个示例代码,演示如何使用自定义类型转换器来将日期字段从字符串类型转换为Date类型:
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Date;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import shardingjdbc.ShardingConnection;
import shardingjdbc.ShardingResultSet;
import shardingjdbc.exceptions.InvalidTypeException;
import shardingjdbc.jdbc2.optional.DefaultSQLTypeHandler;
public class DateTypeHandler extends DefaultSQLTypeHandler {
@Override
public int getJdbcType() {
return java.sql.Types.DATE;
}
@Override
public String getName() {
return "date";
}
@Override
public void setValue(ResultSet rs, int columnIndex, Object value) throws SQLException {
if (value == null) {
setNull(rs, columnIndex);
return;
}
if (value instanceof String) {
setString(rs, columnIndex, ((String)value).trim());
} else if (value instanceof java.util.Date) {
setDate(rs, columnIndex, (Date)value);
} else {
throw new InvalidTypeException("Invalid type for column " + columnIndex);
}
}
private void setDate(ShardingResultSet rs, int columnIndex, Date date) throws SQLException {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1;
int day = calendar.get(Calendar.DAY_OF_MONTH);
rs.updateString(columnIndex, year + "");
rs.updateString(columnIndex + 8, month + "");
rs.updateString(columnIndex + 10, day + "");
}
private void setString(ShardingResultSet rs, int columnIndex, String str) throws SQLException {
rs.updateString(columnIndex, str);
}
@Override
public void setParameter(PreparedStatement ps, int i, Object value, int j) throws SQLException {
if (value == null) {
ps.setNull(j, java.sql.Types.NULL);
} else if (value instanceof java.sql.Date) {
ps.setDate(j, (java.sql.Date)value);
} else if (value instanceof Number) {
ps.setDouble(j, ((Number)value).doubleValue());
} else if (value instanceof String) {
ps.setString(j, (String)value);
} else {
ps.setObject(j, value);
}
}
@Override
public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
if (columnIndex == 0) {
return rs.getDate(columnIndex - 1).getTime();
}
throw new UnsupportedOperationException("Unsupported getValue method for " + getName());
}
@Override
public Class<Object> getJavaType() {
return Date.class;
}
@Override
public String getFullyQualifiedTableName(String catalog, String schemaPattern, String tableNamePattern) {
return null;
}
@Override
public String getColumnName(int column) {
return null;
}
@Override
public int getColumnCount() {
return 0;
}
@Override
public String getColumnTypeName(int column) {
return null;
}
@Override
public TypeHandlerResult getResultSetColumnType(ResultSet rs, int column) throws SQLException {
if (rs.wasNull()) {
return TypeHandlerResult.NULL;
}
return new TypeHandlerResult(getColumnType(rs, column));
}
@Override
public void registerOutParameter(Statement stmt, int i) throws SQLException {
}
@Override
public void registerOutParameter(PreparedStatement ps, int i) throws SQLException {
}
@Override
public void registerInParameter(Statement stmt, int i) throws SQLException {
}
@Override
public void registerInParameter(PreparedStatement ps, int i) throws SQLException {
}
}
在上面的代码中,我们自定义了一个DateTypeHandler类,重写了JDBC中的getDate``()、setDate``()和getObject``()方法,并实现了SQLTypeHandler接口中定义的其他方法。
在初始化时,我们将getDate``()方法的返回值设置为java.sql.Date类型,setDate``()方法的返回值设置为java.util.Date类型,这是我们的默认类型转换器。
在处理字段时,我们使用setValue``()方法将字段值转换为java.util.Date类型,并将返回值存储在一个ImmutableList中,这样我们就可以将它用作结果集中的一个值。
注意,如果字段是日期字段且类型是“yyyy-MM-dd”或“yyyy-MM-dd HH:mm:ss”,我们将在序列化时将其转换为“yyyy-MM-dd HH:mm:ss.SSSXXX”格式。