DBUnit扩展自定类型实现
原文地址:http://zhengkaifl.iteye.com/blog/752286
首先,要扩展DBUnit支持的数据类型,我们必须知道,自己要扩展的数据类型的一些工作情况:
a)驱动程序为该列返回什么JDBC类型;
b)驱动程序为这些对象返回什么Java类;
要解答上面的问题,我们可以用下面的方法来进行测试:
1 Public class PrintMetaData{ 2 public static void main(String[] args) throws SQLException 3 { 4 5 String sql = “select * from tableName order by 1”; 6 7 Connnection conn = DataSourceUtils.getDataSource().getConnection(); 8 9 ResultSet rs = conn.createStatement().executeQuery(sql); 10 11 ResultSetMetaData metaData = rs.getMetaData(); 12 13 System.out.println(“metaData.getColumnType”+metaData.getColumnType(列号,计数从1开始)); 14 15 while(rs.next()) 16 17 { 18 19 Object o = rs.getObject(1); 20 21 System.out.println(“c.getClass() = ” + c.getClass()); 22 23 System.out.println(“c.toString() = ” + c.toString()); 24 25 } 26 27 } 28 29 }
通过这样的方式我们可以清楚的知道自己需要扩展的类型,在驱动里的表现形式。有了这样的基础我们就可以开始扩展我们想要的数据类型了。(以下的内容我们以扩展一个Oracle里面的特殊字段类型TimeStamp with time zone为例)
首先我们需要为我们要扩展的类型定义出自己的OracleTimeStampTZDataType类,该类的实现如下:
1 import java.sql.Timestamp; 2 3 import java.text.SimpleDateFormat; 4 5 import java.util.Date; 6 7 import oracle.jdbc.OracleTypes; 8 9 import oracle.sql.TIMESTAMP; 10 11 import org.dbunit.dataset.datatype.AbstractDataType; 12 13 import org.dbunit.dataset.datatype.TypeCastException; 14 15 16 17 public class OracleTimeStampTZDataType extends AbstractDataType 18 19 { 20 21 private static final String DATE_FORMATE = "yyyy-MM-dd hh:mm:ss"; 22 23 24 25 public OracleTimeStampTZDataType() 26 27 { 28 29 super("TIMESTAMPTZ", OracleTypes.TIMESTAMP, TIMESTAMP.class, false); 30 31 } 32 33 34 35 @Override 36 37 public Object typeCast(Object value) throws TypeCastException 38 39 { 40 41 42 43 SimpleDateFormat formate = new SimpleDateFormat(DATE_FORMATE); 44 45 Timestamp stamp =null; 46 47 try 48 49 { 50 51 Date date = formate.parse((String)value); 52 53 stamp = new Timestamp(date.getTime()); 54 55 } 56 57 catch(Exception ex) 58 59 { 60 61 ex.printStackTrace(); 62 63 } 64 65 return stamp; 66 67 } 68 69 70 71 public int compare(Object o1, Object o2) throws TypeCastException 72 73 { 74 75 return o1.toString().equals(o2.toString()) ? 0 : 1; 76 77 } 78 79 }
定义完我们自己的数据类型后,我们还需要为自定义类型实现一个创建这个自定义对象的类型的工厂类,该类需要继承DBUnit中的DefaultDataTypeFactory类,具体实现如下:
1 import java.sql.Types; 2 import org.dbunit.dataset.datatype.BinaryStreamDataType; 3 import org.dbunit.dataset.datatype.DataType; 4 import org.dbunit.dataset.datatype.DataTypeException; 5 import org.dbunit.dataset.datatype.DefaultDataTypeFactory; 6 import org.dbunit.ext.oracle.OracleBlobDataType; 7 import org.dbunit.ext.oracle.OracleClobDataType; 8 import org.dbunit.ext.oracle.OracleNClobDataType; 9 import org.slf4j.Logger; 10 import org.slf4j.LoggerFactory; 11 12 public class OracleTimeStampTZDataTypeFactory extends DefaultDataTypeFactory 13 { 14 /** 15 * Logger for this class 16 */ 17 private static final Logger logger = LoggerFactory.getLogger(OracleTimeStampTZDataTypeFactory.class); 18 19 public static final DataType ORACLE_BLOB = new OracleBlobDataType(); 20 public static final DataType ORACLE_CLOB = new OracleClobDataType(); 21 public static final DataType ORACLE_NCLOB = new OracleNClobDataType(); 22 public static final DataType LONG_RAW = new BinaryStreamDataType( 23 "LONG RAW", Types.LONGVARBINARY); 24 public static final DataType ORACLE_TIMESTAMPTZ = new OracleTimeStampTZDataType(); 25 26 public DataType createDataType(int sqlType, String sqlTypeName) throws DataTypeException 27 { 28 logger.debug("createDataType(sqlType=" + sqlType + ", sqlTypeName=" + sqlTypeName + ") - start"); 29 30 // Map Oracle DATE to TIMESTAMP 31 if (sqlType == Types.DATE) 32 { 33 return DataType.TIMESTAMP; 34 } 35 36 // TIMESTAMOTZ 37 if(sqlTypeName.startsWith("TIMESTAMP(6) WITH TIME ZONE")) 38 { 39 return ORACLE_TIMESTAMPTZ; 40 } 41 42 // TIMESTAMP 43 if (sqlTypeName.startsWith("TIMESTAMP")) 44 { 45 return DataType.TIMESTAMP; 46 } 47 48 // BLOB 49 if ("BLOB".equals(sqlTypeName)) 50 { 51 return ORACLE_BLOB; 52 } 53 54 // CLOB 55 if ("CLOB".equals(sqlTypeName)) 56 { 57 return ORACLE_CLOB; 58 } 59 60 // NCLOB 61 if ("NCLOB".equals(sqlTypeName)) 62 { 63 return ORACLE_NCLOB; 64 } 65 66 // NVARCHAR2 67 if ("NVARCHAR2".equals(sqlTypeName)) 68 { 69 return DataType.VARCHAR; 70 } 71 72 // NCHAR 73 if (sqlTypeName.startsWith("NCHAR")) 74 { 75 return DataType.CHAR; 76 } 77 78 // FLOAT 79 if ("FLOAT".equals(sqlTypeName)) 80 { 81 return DataType.FLOAT; 82 } 83 84 // LONG RAW 85 if (LONG_RAW.toString().equals(sqlTypeName)) 86 { 87 return LONG_RAW; 88 } 89 90 return super.createDataType(sqlType, sqlTypeName); 91 } 92 }
至此我们已经完成了自定义类型的相关定义,但是要让DBUnit支持我们的自定义类型,我们还需要实现一个针对我们自定义类型的数据库连接对象OracleTZConnection,同样该类需要继承DBUnit的DatabaseConnection类,具体的实现如下:
1 import java.sql.Connection; 2 import org.dbunit.database.DatabaseConfig; 3 import org.dbunit.database.DatabaseConnection; 4 5 public class OracleTZConnection extends DatabaseConnection{ 6 7 public OracleTZConnection(Connection connection, String schema) 8 { 9 super(connection, schema != null ? schema.toUpperCase() : null); 10 getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, 11 new OracleTimeStampTZDataTypeFactory()); 12 } 13 }
OK,完成上面这些定义之后,我们已经完成了一个自定义类型在DBUnit中的扩展。最后给出一个使用该自定义类型做DBUnit测试的小的demo代码:
1 import org.dbunit.DBTestCase; 2 import org.dbunit.database.IDatabaseConnection; 3 import org.dbunit.dataset.IDataSet; 4 import org.dbunit.dataset.xml.FlatXmlDataSet; 5 import org.dbunit.operation.DatabaseOperation; 6 import org.junit.Before; 7 8 import delete.Test; 9 10 public class MyTest extends DBTestCase{ 11 12 @Override 13 protected IDataSet getDataSet() throws Exception { 14 return new FlatXmlDataSet(this.getClass().getResourceAsStream("MyTest.xml")); 15 } 16 17 @Override 18 protected IDatabaseConnection getConnection() throws Exception 19 { 20 return new OracleTZConnection(Test.getConnection(), "ZK"); 21 } 22 23 @Before 24 public void setUp() throws Exception 25 { 26 DatabaseOperation.INSERT.execute(getConnection(), getDataSet()); 27 } 28 29 public void testTT() 30 {} 31 }

浙公网安备 33010602011771号