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 }

 

posted @ 2017-08-09 09:39  傳奇  阅读(394)  评论(0)    收藏  举报