我正在为数据库组件编写一些单元测试.为此,我使用专用的测试数据库(Postgresql,与生产数据库相同)和dbUnit.现在我想创建整个测试数据库的XML转储.我目前使用的是FAQ page of dbUnit的代码IDatabaseConnection conne...

我正在为数据库组件编写一些单元测试.为此,我使用专用的测试数据库(Postgresql,与生产数据库相同)和dbUnit.
现在我想创建整个测试数据库的XML转储.我目前使用的是FAQ page of dbUnit的代码
IDatabaseConnection connection = new DatabaseConnection(conn);
connection.getConfig().setProperty("http://www.dbunit.org/properties/datatypeFactory", new PostgresqlDataTypeFactory());
IDataSet fullDataSet = connection.createDataSet();
FlatXmlDataSet.write(fullDataSet, new FileOutputStream("full.xml"));
这一切都很有效,除了Array类型的列.dbUnit只是将它们排除在外.我希望通过添加PostgresqlDataTypeFactory来修复它,但这并没有改变一件事.
有人知道如何在dbUnit中添加对postgresql数组的支持吗?
解决方法:
我在github上找到了这个项目:https://github.com/JarnTang/dbunit-ext
我正在使用其ArrayDataType类进行小修改:
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.datatype.AbstractDataType;
import org.dbunit.dataset.datatype.TypeCastException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.lang.invoke.MethodHandles;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class ArrayDataType extends AbstractDataType {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final Class CLASS_TYPE = Array.class;
public ArrayDataType(String name, int sqlType, boolean isNumber) {
super(name, sqlType, CLASS_TYPE, isNumber);
}
@Override
public Object typeCast(Object value) throws TypeCastException {
if (value == null || value == ITable.NO_VALUE) {
return null;
}
if (value instanceof String) {
return new String[]{(String) value};
}
if (value instanceof String[]) {
return value;
}
if (value instanceof Date ||
value instanceof Time ||
value instanceof Timestamp) {
return new String[]{value.toString()};
}
if (value instanceof Boolean) {
return new String[]{value.toString()};
}
if (value instanceof Number) {
try {
return new String[]{value.toString()};
} catch (NumberFormatException e) {
throw new TypeCastException(value, this, e);
}
}
if (value instanceof Array) {
try {
Array a = (Array) value;
return a.getArray();
} catch (Exception e) {
e.printStackTrace();
}
}
if (value instanceof Blob) {
try {
Blob blob = (Blob) value;
byte[] blobValue = blob.getBytes(1, (int) blob.length());
return typeCast(blobValue);
} catch (SQLException e) {
throw new TypeCastException(value, this, e);
}
}
if (value instanceof Clob) {
try {
Clob clobValue = (Clob) value;
int length = (int) clobValue.length();
if (length > 0) {
return clobValue.getSubString(1, length);
}
return "";
} catch (SQLException e) {
throw new TypeCastException(value, this, e);
}
}
log.warn("Unknown/unsupported object type '{}' - " +
"will invoke toString() as last fallback which " +
"might produce undesired results",
value.getClass().getName());
return value.toString();
}
@Override
public Object getSqlValue(int column, ResultSet resultSet)
throws SQLException, TypeCastException {
if (log.isDebugEnabled())
log.debug("getSqlValue(column={}, resultSet={}) - start", column, resultSet);
String value = resultSet.getString(column);
if (value == null || resultSet.wasNull()) {
return null;
}
return value;
}
@Override
public void setSqlValue(Object value, int column, PreparedStatement statement)
throws SQLException, TypeCastException {
if (log.isDebugEnabled())
log.debug("setSqlValue(value={}, column={}, statement={}) - start",
value, column, statement);
Array array = isNumber() ? statement.getConnection().createArrayOf("integer", toArray(value)) :
statement.getConnection().createArrayOf("text", toArray(value));
statement.setObject(column, array);
}
private Object[] toArray(Object value) {
List list = new ArrayList(0);
if (value instanceof String) {
String valueStr = (String) value;
if (!StringUtils.isEmpty(valueStr)) {
valueStr = valueStr.replaceAll("[{}]", "");
return valueStr.split(",");
}
}
return list.toArray();
}
}
然后你需要扩展PostgresqlDataTypeFactory,例如:
import org.dbunit.dataset.datatype.DataType;
import org.dbunit.dataset.datatype.DataTypeException;
import org.dbunit.ext.postgresql.PostgresqlDataTypeFactory;
public class CustomPostgresqlDataTypeFactory extends PostgresqlDataTypeFactory{
@Override
public DataType createDataType(int sqlType, String sqlTypeName, String tableName, String columnName) throws DataTypeException {
if (sqlType == 2003) {
if (sqlTypeName.equals("_text"))
return new ArrayDataType(sqlTypeName, sqlType, false);
if (sqlTypeName.contains("int"))
return new ArrayDataType(sqlTypeName, sqlType, true);
throw new UnsupportedSqlTypeException("Unsupported sql type: " + sqlTypeName);
}
return super.createDataType(sqlType, sqlTypeName, tableName, columnName);
}
}
并将CustomPostgresqlDataTypeFactory设置为IDatabaseConnection:
IDatabaseConnection conn = databaseTester.getConnection();
conn.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY,
new CustomPostgresqlDataTypeFactory());
本文标题为:java – 对Postgresql数组的dbUnit支持


基础教程推荐
- 用java代码帮朋友P图 2023-03-15
- Spring运行时手动注入bean的方法实例 2022-12-02
- jsp获取url路径的方法分析 2023-08-02
- SpringBoot后端数据校验实战操作指南 2023-02-19
- Spring 事务隔离与事务传播的详解与对比 2023-07-31
- springboot使用redisTemplate操作lua脚本 2023-04-16
- SpringBoot详解如何整合Redis缓存验证码 2023-02-11
- JSP通用高大上分页代码(超管用) 2023-08-03
- Java效率提升神器jOOR 2023-02-19
- JSP 开发之Struts2内建自定义拦截器 2023-07-31