日期:2014-05-16  浏览次数:20465 次

dbunit入门 (二)数据的备份与恢复
这里讲如何将我们将要测试的数据库的表的数据进行备份,然后测试, 最后恢复数据库数据。


这里的核心过程就是
-> QueryDataSet获取数据库信息。
-> FlatXmlDataSet.write写入数据库数据到xml文件中。
-> 进行测试
-> 测试完成, 从xml文件恢复数据到数据库中

这里的几个核心的Dbunit类:

1. org.dbunit.dataset.IDataSet
这个接口是关于存放所有table信息的,包括xml文件的table数据信息以及数据库中读取到的table数据信息。

2. org.dbunit.dataset.xml.FlatXmlDataSet
这个类用于读写上面的IDataSet所存储的信息。
它可以从xml文件中读取信息,并写入到IDataSet中。
或者从IDataSet中读取信息,并写入到xml文件中。

3. org.dbunit.database.QueryDataSet
这个类保存所有根据sql语句查询到的表的内容。
它通过如下的构造函数获取IDatabaseConnection。
private final IDatabaseConnection _connection;
  public QueryDataSet(IDatabaseConnection connection)。

这个类的核心方法是addTable(), 源码如下:
 
  /**
     *  Adds a table and it's associated query to this dataset.
     *
     * @param tableName The name of the table
     * @param query The query to retrieve data with for this table. Can be null which will select
     * all data (see {@link #addTable(String)} for details)
     * @throws AmbiguousTableNameException 
     */
    public void addTable(String tableName, String query) throws AmbiguousTableNameException
    {
        logger.debug("addTable(tableName={}, query={}) - start", tableName, query);
        _tables.add(tableName, new TableEntry(tableName, query));
    }

    /**
     *  Adds a table with using 'SELECT * FROM <code>tableName</code>' as query.
     *
     * @param tableName The name of the table
     * @throws AmbiguousTableNameException 
     */
    public void addTable(String tableName) throws AmbiguousTableNameException
    {
        logger.debug("addTable(tableName={}) - start", tableName);
        this.addTable(tableName, null);
    }


它会将select语句和自己的OrderedTableNameMap对象绑定在一起。在后面需要查询数据库数据时, 便会执行SQL语句。(跟hibernate的session比较类似吧)。

================================================

完整的AbstractDbUnitTestCase代码:

package com.lj.basic.test.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;

import junit.framework.Assert;

import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.database.QueryDataSet;
import org.dbunit.dataset.DataSetException;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.dataset.xml.FlatXmlProducer;
import org.dbunit.operation.DatabaseOperation;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.xml.sax.InputSource;

import com.lj.basic.test.util.AbstractDbUnitTestCase;
import com.lj.basic.test.util.DbUtil;
import com.lj.basic.util.MyLog4jLogger;


/**
 * 此处我们使用lingling这个数据库schema来专门进行测试
 * alleni用来存储我们的正式信息。
 * lingling->在dbutil中配置的  -jdbc connection
 * alleni-> 在beans.xml中配置的 -hibernate
 * @author Administrator
 *
 */
public class AbstractDbUnitTestCase {
	public static IDatabaseConnection dbunitCon;
	
	
	/**
	 * tempFile用来存放备份的数据信息<br/>
	 * 当测试数据时,会将数据信息存放到这个文件中。<br/>
	 * 测试完成之后,再将数据导回数据库。
	 */
	private File tempFile;
	
	/**
	 * Beforeclass是在创建这个类之前所做的操作<br/>
	 * 这个方法必须为static<br/>
	 * 该方法在junit测试中会被最先调用,并且只会调用一次。
	 */
	@BeforeClass
	public static void init() throws DatabaseUnitException{
		//System.out.println("BEFOREclass init");
		MyLog4jLogger.debug("AbstractDbUnitTestCase init() BeforeClass");
		//在测试运行之前,便给dbunitCon初始化并赋值。
		dbunitCon=new DatabaseConnection(DbUtil.getCon());
	}
	
	/**
	 * 测试完成之后,此方法便会被运行,关闭dbunitCon
	 */
	@AfterClass
	public static void destory(){
		try {
			if(dbunitCon!=null)dbunitCon.close();
			
		} catch (Exception e) {
			 e.printStackTrace();
		}
		MyLog4jLogger.debug("AbstractDbUnitTestC