DBUnit最佳实践之数据备份与恢复
在做测试之前,我们需要对数据进行备份,用DBUnit可以很方便的对数据库中的数据进行备份和恢复。
目录结构
- 项目结构图
- 源代码
- 数据库工具类
- 导入导出类
- Maven工程文件
- 数据库配置属性文件
- 数据库脚本
- 日志配置文件
- 参考文档
- 完整项目源代码
项目结构图
源代码
数据库工具类
DBUtil.java
package com.coderdream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;
public class DBUtil {
public static Connection getConnection() {
Connection conn = null;
try {
ResourceBundle rs = ResourceBundle.getBundle("dbutil");
Class.forName(rs.getString("db.classname"));
conn = DriverManager.getConnection(rs.getString("db.url"), rs.getString("db.username"), rs.getString("db.password"));
} catch (ClassNotFoundException e) {
System.out.println("数据库驱动加载失败,堆栈轨迹如下");
e.printStackTrace();
} catch (SQLException e) {
System.out.println("数据库连接创建失败,堆栈轨迹如下");
e.printStackTrace();
}
return conn;
}
public static void closeAll(ResultSet rs, PreparedStatement pstmt, Connection conn) {
if (null != rs) {
try {
rs.close();
} catch (SQLException e) {
System.out.println("数据库操作的ResultSet关闭失败,堆栈轨迹如下");
e.printStackTrace();
}
}
if (null != pstmt) {
try {
pstmt.close();
} catch (SQLException e) {
System.out.println("数据库操作的PreparedStatement关闭失败,堆栈轨迹如下");
e.printStackTrace();
}
}
close(conn);
}
public static void close(Connection conn) {
if (null != conn) {
try {
conn.close();
if (conn.isClosed()) {
System.out.println("此数据库连接已关闭-->" + conn);
} else {
System.out.println("此数据库连接关闭失败-->" + conn);
}
} catch (SQLException e) {
System.out.println("数据库连接关闭失败,堆栈轨迹如下");
e.printStackTrace();
}
}
}
}
导入导出类
DBExportImport.java
package com.coderdream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.sql.Connection;
import java.sql.SQLException;
import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.database.QueryDataSet;
import org.dbunit.dataset.CachedDataSet;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.csv.CsvDataSetWriter;
import org.dbunit.dataset.stream.IDataSetProducer;
import org.dbunit.dataset.xml.XmlDataSetWriter;
import org.dbunit.dataset.xml.XmlProducer;
import org.dbunit.operation.DatabaseOperation;
import org.dbunit.util.FileHelper;
public class DBExportImport {
private static String TEST_DIR = DBExportImport.class.getResource("/").getPath();
public static void main(String[] args) throws Exception {
File file = new File(TEST_DIR + "backup.xml");
Connection connection = DBUtil.getConnection();
String[] tableNames = new String[] { "student" };
// 导出指定的表的数据到xml文件
exportTables(connection, tableNames, file);
// 导出所有表的数据到xml文件
// exportAllTables(file, connection);
// 将xml数据文件中的数据导入到数据库中
importData(file, connection);
}
/**
* <pre>
* 导出数据到指定文件
*
* 在这个方法中指定了一个表名"room",如果有多个表可以通过参数或其他的方式按照这种方式继续增加。
* 这个文件是XML格式的。
* 具体格式说明或其他格式参见http://www.dbunit.org/components.html
*
*
* </pre>
*
* @param connection
* 一个标准的java.sql.Connection
* @param tableNames
* 需要导出数据的表名数组
* @param file
* 一个标准的java.io.File
* @throws Exception
*/
public static void exportTables(Connection connection, String[] tableNames, File file) throws Exception {
IDatabaseConnection databaseConnection = new DatabaseConnection(connection);
QueryDataSet dataSet = new QueryDataSet(databaseConnection);
if (null != tableNames && 0 < tableNames.length) {
int tableNamesLength = tableNames.length;
for (int i = 0; i < tableNamesLength; i++) {
dataSet.addTable(tableNames[i]);
}
}
Writer writer = new FileWriter(file);
XmlDataSetWriter w = new XmlDataSetWriter(writer);
w.write(dataSet);
writer.flush();
writer.close();
}
/**
* <pre>
* 导出数据库中的所有数据到指定文件
* 这个文件是XML格式的。
* 具体格式说明或其他格式参见http://www.dbunit.org/components.html
*
* 这个方法可以把上面生成的XML文件导入到数据库中,
* 如果是其他格式的文件只需要更换IDataSetProducer的实现类就可以了。
* 具体格式请参见APIDOC在这个方法里使用了事务控制,保证数据的一致性。
*
* </pre>
*
* @param file
* 一个标准的java.io.File
* @param connection
* 一个标准的java.sql.Connection
* @throws Exception
*/
public static void exportAllTables(File file, Connection connection) throws Exception {
IDatabaseConnection databaseConnection = new DatabaseConnection(connection);
IDataSet dataSet = databaseConnection.createDataSet();
Writer writer = new FileWriter(file);
XmlDataSetWriter w = new XmlDataSetWriter(writer);
w.write(dataSet);
writer.flush();
writer.close();
}
/**
* CsvDataSetWriter
*
* <pre>
* 导出数据库中的所有数据到指定文件
* 这个文件是XML格式的。
* 具体格式说明或其他格式参见http://www.dbunit.org/components.html
*
* 这个方法可以把上面生成的XML文件导入到数据库中,
* 如果是其他格式的文件只需要更换IDataSetProducer的实现类就可以了。
* 具体格式请参见APIDOC在这个方法里使用了事务控制,保证数据的一致性。
*
* </pre>
*
* @param file
* 一个标准的java.io.File
* @param connection
* 一个标准的java.sql.Connection
* @throws Exception
*/
public static void exportAllTablesToCsv(Connection connection, File file) throws Exception {
IDatabaseConnection databaseConnection = new DatabaseConnection(connection);
IDataSet dataSet = databaseConnection.createDataSet();
CsvDataSetWriter w = new CsvDataSetWriter(file);
w.write(dataSet);
}
/**
* 导入数据到数据库
*
* @param file
* 一个标准的java.io.File
* @param connection
* 一个标准的java.sql.Connection
*/
public static void importData(File file, Connection connection) throws DatabaseUnitException, IOException, SQLException {
IDataSetProducer dataSetProducer = new XmlProducer(FileHelper.createInputSource(file));
IDataSet dataSet = new CachedDataSet(dataSetProducer);
IDatabaseConnection databaseConnection = new DatabaseConnection(connection);
DatabaseOperation operation = DatabaseOperation.CLEAN_INSERT;
DatabaseOperation.TRANSACTION(operation);
operation.execute(databaseConnection, dataSet);
DatabaseOperation.CLOSE_CONNECTION(operation);
}
}
Maven工程文件
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.coderdream</groupId> <artifactId>dbunit-export-import</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>DBUnitSample</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.24</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency> <dependency> <groupId>org.dbunit</groupId> <artifactId>dbunit</artifactId> <version>2.4.8</version> </dependency> </dependencies> </project>
数据库配置属性文件
dbutil.properties
db.classname=com.mysql.jdbc.Driver
db.url=jdbc:mysql://127.0.0.1:3306/dbup?characterEncoding=UTF-8
db.username=root
db.password=1234
数据库脚本
dbup.sql
/*
Navicat MySQL Data Transfer
Source Server : localhost
Source Server Version : 50525
Source Host : localhost:3306
Source Database : dbup
Target Server Type : MYSQL
Target Server Version : 50525
File Encoding : 65001
Date: 2014-10-11 14:27:06
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `role`
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
`id` varchar(20) NOT NULL DEFAULT '',
`roleName` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES ('1', '管理员');
INSERT INTO `role` VALUES ('2', '普通用户');
-- ----------------------------
-- Table structure for `student`
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` varchar(20) NOT NULL DEFAULT '',
`name` varchar(20) DEFAULT NULL,
`sex` varchar(10) DEFAULT NULL,
`birthday` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', '2', '3', '4');
-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` varchar(20) NOT NULL DEFAULT '',
`name` varchar(20) DEFAULT NULL,
`role_id` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `ref_id` (`role_id`),
CONSTRAINT `ref_id` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', '张三', '1');
INSERT INTO `user` VALUES ('2', '李四', '2');
日志配置文件
log4j.properties
# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1
# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender
# A1 uses PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
运行结果
导出的xml文件backup.xml
<?xml version='1.0' encoding='UTF-8'?> <dataset> <table name="student"> <column>id</column> <column>name</column> <column>sex</column> <column>birthday</column> <row> <value>0001</value> <value>翁仔</value> <value>m</value> <value>1979-12-31</value> </row> <row> <value>0002</value> <value>王翠花</value> <value>f</value> <value>1982-08-09</value> </row> </table> </dataset>
参考文档
完整源代码