您的位置:首页 > 其它

一个基于DBUnit的数据导出/导入工具类

2013-03-05 14:21 459 查看


转载自 积木

http://jim19770812.blogspot.com/2009/12/dbunit.html

DBUnit是基于JUnit的扩展,提供了基于数据库的测试数据的自动化测试,并且DBUnit提供了强大的导入导出数据功能,可以很容易的构造干净的数据测试环境。

除了使用DBUnit实现自动化的数据单元测试,还可以用来实现类似数据库备份/恢复的功能,道理都是差不多的。

网上常见的几个关于DBUnit的问题

1.因为外键约束造成导入失败

其实DBUnit是可以避免这个问题的,关键在于不要使用FlatXmlDataSet,改用CsvDataSetWriter就不会有外键问题了。

2.自己实现了基于SQL脚本的数据测试工具

我认为这种做法不可取,首先是测试数据的准备时间太长,数据量较少的话还可以用用,如果数据量比较大,写sql还不得累死?要是表结构再有了变化所有sql又得重新修改一遍。使用DBUnit就简单多了,数据库变了只要把新数据库重新导出一遍就可以了,非常容易。

代码如下:

package com.dbdata;

import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import javax.swing.JFileChooser;
import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.database.QueryDataSet;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.csv.CsvDataSet;
import org.dbunit.dataset.csv.CsvDataSetWriter;
import org.dbunit.operation.DatabaseOperation;

import com.gdw.common.util.FileUtil;

public class DBDataUtil {
private IDatabaseConnection connection =null;

/**
* 打开连接,相当于JDBC的DriverManager.getConnection()
* @param conn
* @return
*/
public boolean open(final Connection conn){
try {
this.connection = new DatabaseConnection(conn);
return connection != null;
} catch (DatabaseUnitException e) {
e.printStackTrace();
return false;
}
}

/**
* 关闭连接,相当于JDBC的connection.close;
* @return
*/
public boolean close(){
if (this.connection != null){
try {
this.connection.close();
return true;
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
return true;
}

/**
* 导出数据到指定的目录下
* @param tableNames 表名列表,注意外键关系,要按照顺序排列(先导出字典,再导出主表)
* @param destFolder 导出目录
* @return
*/
public boolean exp(final List tableNames, final File destFolder){
QueryDataSet dataSet = new QueryDataSet(connection);
try{
for(String tableName : tableNames){
dataSet.addTable(tableName);
}
CsvDataSetWriter.write(dataSet, destFolder);
this.saveDefaultPath(destFolder.getParent());
return true;
}catch(Exception e){
e.printStackTrace();
}
return false;
}

/**
* 导入数据,会根据导出时的顺序依次导入,如果出现了因外键约束而导入失败的情况,请调整导出时的表顺序
* @param sourceFolder
* @return
*/
public boolean imp(final File sourceFolder){
try{
IDataSet dataSet = new CsvDataSet(sourceFolder);
//准备读入数据
DatabaseOperation.CLEAN_INSERT.execute(connection, dataSet);
return true;
}catch(Exception e){
e.printStackTrace();
}
return false;
}

/**
* 选择打开目录
* @return
*/
public static String showOpenFolder(){
String defaultPath = loadDefaultPath();
JFileChooser jf = new JFileChooser(defaultPath);
jf.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int ret = jf.showOpenDialog(null);
if (ret != JFileChooser.APPROVE_OPTION){
return null;
}

return jf.getSelectedFile().getAbsolutePath();
}

/**
* 选择保存目录
* @param defaultPath 默认目录
* @return
*/
public static String showSaveFolder(){
String defaultPath = loadDefaultPath();
JFileChooser jf = new JFileChooser(defaultPath);
jf.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int ret = jf.showSaveDialog(null);
if (ret != JFileChooser.APPROVE_OPTION){
return null;
}

return jf.getSelectedFile().getAbsolutePath();
}

public static String loadDefaultPath(){
File f = new File(".lastpath");
System.out.println(f.getAbsolutePath());
if (f.isFile() && f.exists()){
return FileUtil.readAbsolutFile(f.getAbsolutePath());
}
return null;
}

public static void saveDefaultPath(final String defaultPath){
File f = new File(".lastpath");
FileUtil.writeFile(".lastpath", defaultPath);
System.out.println(f.getAbsolutePath());
}
}


导出代码

package com.dbdata;

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ResourceBundle;

import com.gdw.common.util.StringUtil;

public class DataImporter {
public boolean imp(final String jdbcClassName, final String url, final String userName, final String password, final String folder){
try{
Class.forName(jdbcClassName);
Connection conn = DriverManager.getConnection(url, userName, password);
DBDataUtil util = new DBDataUtil();
util.open(conn);
try{
boolean ret = util.imp(new File(folder));
return ret;
}finally{
util.close();
}
}catch(Exception e){
e.printStackTrace();
}
return false;
}

public static void main(String[] args) {
Connection conn = null;
try{
String folder = DBDataUtil.showOpenFolder();
if (StringUtil.isNull(folder)){
return;
}
ResourceBundle rs = ResourceBundle.getBundle("_dbutil");
boolean ret = new DataImporter().imp(rs.getString("db.classname"), rs.getString("db.url"), rs.getString("db.username"), rs.getString("db.password"), folder);
System.out.println(ret ? "导入成功!" : "导入失败");
}catch(Exception e){
e.printStackTrace();
}
}
}


导入代码

package com.dbdata;

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.LinkedList;
import java.util.List;
import java.util.ResourceBundle;

import com.gdw.common.util.StringUtil;

public class DataExporter {
public boolean exp(final String jdbcClassName, final String url, final String userName, final String password, final List tableNames, final String folder){
try{
Class.forName(jdbcClassName);
Connection conn = DriverManager.getConnection(url, userName, password);
DBDataUtil util = new DBDataUtil();
util.open(conn);
try{
boolean ret = util.exp(tableNames, new File(folder));
return ret;
//System.out.println(ret ? "导出成功!" : "导出失败");
}finally{
util.close();
}
}catch(Exception e){
e.printStackTrace();
}
return false;
}

public static void main(String[] args) {
Connection conn = null;
try{
ResourceBundle rs = ResourceBundle.getBundle("_dbutil");
List tableNames = new LinkedList();
tableNames.add("muser");
tableNames.add("mmenu");
tableNames.add("mtable1");
tableNames.add("mtable2");
tableNames.add("mtable3");
tableNames.add("mtable4");
tableNames.add("mtable5");
tableNames.add("mtable6");
tableNames.add("mtable7");
String folder = DBDataUtil.showSaveFolder();
if (StringUtil.isNull(folder)){
return;
}
boolean ret = new DataExporter().exp(rs.getString("db.classname"), rs.getString("db.url"), rs.getString("db.username"), rs.getString("db.password"), tableNames, folder);
System.out.println(ret ? "导出成功!" : "导出失败");
}catch(Exception e){
e.printStackTrace();
}
}
}


_dbutil.properties 内容如下

db.classname=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8
db.username=root
db.password=jim


用DBUnit实现数据测试的用法

1.在数据库中生成测试数据

2.用DataExporter导出测试数据

2.编写单元测试

2.1.测试执行前使用DataExporter把业务表备份到临时目录

2.2.使用DataImporter导入测试数据

2.3.执行单元测试

2.4.使用DataImporter将先前做的备份数据恢复

经过本人测试,以上代码可以在包含外键约束的mysql数据库环境下运行正常。

如果你有兴趣的话,还可以在此基础上改成基于命令行或者图形化界面的工具,这样用起来更容易。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐