1.准备数据库,这里我使用MYSQL数据库,创建表格 student,如下所示:
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `student`
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` char(4) NOT NULL,
`name` char(50) DEFAULT NULL,
`sex` char(1) DEFAULT NULL,
`birthday` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.在上面的表中插入如下数据:
INSERT INTO`student` VALUES ('0011', 'haha', 'f', '1984-11-2');
INSERT INTO `student` VALUES ('0044', 'lulu', 'f', '1984-11-2');
INSERT INTO `student` VALUES ('0066', 'jie', 'm', '1984-11-2');
INSERT INTO `student` VALUES ('0077', 'minggxu9', 'm', '1984-11-2');
3.准备好数据库以后,然后配置Hibernate,以及DBUnit的支持。我这里还没有用Maven进行管理,只是将它们下载下来,并导入至CLASSPATH中而已。
Hibernate的下载地址为:
http://sourceforge.net/projects/hibernate/files/hibernate3/3.1.2/hibernate-3.1.2.zip/download
DBUnit的下载地址为:
http://sourceforge.net/projects/dbunit/files/
4.编写一个Hibernate例子。这里使用上面提拱的student表做以下两个操作:
1)查询所有学生
2)添加一个学生
实现步骤如下所示:
4.1 书写hibernate.cfg.xml文件,将它保存至src/main/resources源文件夹下面,它的内容如下所示:
<?xml version='1.0'encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/HibernateConfiguration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<!-- JDBC驱动程序 -->
<propertyname="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- JDBCURL -->
<propertyname="connection.url"> jdbc:mysql://localhost:3306/atdDB?useUnicode=true&characterEncoding=UTF8</property>
<!-- 数据库用户名 -->
<propertyname="connection.username">root</property>
<!-- 数据库密码 -->
<propertyname="connection.password">123456</property>
<!-- sql的方言,不同db的sql略有不同 方言区分大小写-->
<propertyname="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 后台显示sql语句,主要是调试用 -->
<propertyname="show_sql">true</property>
<!-- 映射文件 -->
<mapping resource="Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
注意: 上面的红色高亮显示,表示是要引入一个student.hbm.xml自定义映射文件,它的细节如4.3所示。
4.2 编写POJO类(Student .java),也即JAVABEAN,相当于DDD中的CTO数据传输对象。
package po;
public class Student {
private String id;
private String name;
private String sex;
private String birthday;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name =name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex =sex;
}
public String getBirthday() {
returnbirthday;
}
public void setBirthday(String birthday){
this.birthday= birthday;
}
}
4.3 编写映射文件Stuend.hbm.xml,之前的例子中使用的是JPA方式--泛型注入的方式,我这里写了个映射文件,可以看到Hibernate的数据库表格中的映射情况,如下所示:
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="po.Student"table="student">
<idname="id" type="string" unsaved-value="null">
<generator class="assigned" />
</id>
<propertyname="name" type="string"not-null="true"/>
<propertyname="sex" type="string"not-null="true"/>
<propertyname="birthday" />
</class>
</hibernate-mapping>
注意:这个映射文件表示它与po层的JAVABEAN(Student.java)配合一起使用的。它们之间的字段和属性一一对应,
<generator class="assigned" />表示的是id为主键的。
4.3书写测试测子--HibernateTest.java,就是上面的两个操作(查询全部和插入功能):
packagecom.db.oper;
import java.util.List;
import java.util.ListIterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import po.Student;
public class HibernateTest {
private static Log log =LogFactory.getLog(HibernateTest.class);
public void find() {
SessionFactory sessionFactory;
try {
sessionFactory = newConfiguration().configure()
.buildSessionFactory();
Session session = sessionFactory.openSession();
List students = (List)session.createQuery("from Student").list();
//也可以使用原生态的SQL,我这里写了一个类SQL语句
注:也可以使用原生态的SQL,我这里写了一个类SQL语句 ,而插入操作也比较简单,即将student对象持久化到session中即可。而这个session是单例模式,只允许同一个时间出现一个。
5.使用DBUnit持久化测试框架
dbunit的原理是:它会把数据库表里的数据和一个xml文件里表示的数据关联起来。也就是说数据库表里的数据可以导出到一个对应的xml里,同时也可以将一个xml里的数据导入到数据库表里。是相互转换的。
数据库表里的数据<===>xml文件
5.1 一个简单的测试例子。TestApp.java的内容如下所示:
package com.db.oper;
import java.io.FileOutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.database.QueryDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
public class TestApp {
public static void main(String[] args) throwsException {
Class.forName("com.mysql.jdbc.Driver");
Connectionconn = DriverManager
.getConnection(
"jdbc:mysql://localhost:3306/atdDB?useUnicode=true&characterEncoding=UTF8",
"root","123456");
IDatabaseConnection connection = new DatabaseConnection(conn);
QueryDataSetdataSet = new QueryDataSet(connection);
// 将整个person表里的数据导出到 xml文件里
dataSet.addTable("student");
// 将users表里符合条件的数据导出到xml文件里
// 导出到student.xml文件里
FlatXmlDataSet.write(dataSet, new FileOutputStream("student.xml"));
}
}
导出的student.xml文件的内容如下所示:
<?xml version='1.0'encoding='UTF-8'?>
<dataset>
<student id="0001" name="mingg"sex="m" birthday="2011-11-06"/>
<student id="0002" name="jie"sex="f" birthday="2010-10-01"/>
<student id="004" name="dsad"sex="f" birthday="2011-12-14"/>
<student id="0088" name="wangdo"sex="m" birthday="2008-12-16"/>
</dataset>
里面的内容同数据库表中的内容是一一对应的。如果我会想测试查询中的数据是否同数据库中的内容一致,我们只要对比这个XML文件即可,不用再去查看数据库表和表中的内容了。
下面我们做一个测试类,里面包括表,表结构,以及表中内容的测试。它的内容如下所示:
package com.db.test;
import java.io.File;
import java.io.FileInputStream;
import org.dbunit.Assertion;
import org.dbunit.DBTestCase;
import org.dbunit.PropertiesBasedJdbcDatabaseTester;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.SortedTable;
import org.dbunit.dataset.filter.DefaultColumnFilter;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.operation.DatabaseOperation;
public class SimpleTest extends DBTestCase {
public SimpleTest()
{
// super();
System.setProperty(
PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS,
"com.mysql.jdbc.Driver");
System.setProperty(
PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL,
"jdbc:mysql://localhost:3306/atdDB?useUnicode=true&characterEncoding=UTF8");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME,
"root");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD,
"123456");
}
/**
* 给定数据集
*/
@Override
protected IDataSet getDataSet() throwsException {
System.out.println("init...");
return newFlatXmlDataSet(new FileInputStream("student.xml"));
}
public void test1() throws Exception{
IDataSetdbDataSet = getConnection().createDataSet();
ITabledbTable = dbDataSet.getTable("student");
IDataSetxmlDataSet = new FlatXmlDataSet(new FileInputStream("student.xml"));
ITablexmlTable = xmlDataSet.getTable("student");
Assertion.assertEquals(xmlTable, dbTable);
}
/**
* 表结构和student.xml结构不一致
*/
public void test2() throws Exception{
IDataSetdbDataSet = getConnection().createDataSet();
ITabledbTable = dbDataSet.getTable("student");
IDataSetxmlDataSet = new FlatXmlDataSet(new FileInputStream("student.xml"));
ITablexmlTable = xmlDataSet.getTable("student");
dbTable = DefaultColumnFilter.includedColumnsTable(dbTable,xmlDataSet.getTableMetaData("student").getColumns());
Assertion.assertEquals(xmlTable, dbTable);
}
/**
* 只比较name
*/
public void test3() throws Exception{
IDataSetdbDataSet = getConnection().createDataSet();
ITabledbTable = dbDataSet.getTable("student");
IDataSetxmlDataSet = new FlatXmlDataSet(new FileInputStream("student.xml"));
ITablexmlTable = xmlDataSet.getTable("student");
dbTable =DefaultColumnFilter.excludedColumnsTable(dbTable, newString[]{"id","name"});
xmlTable =DefaultColumnFilter.excludedColumnsTable(dbTable, newString[]{"name"});
Assertion.assertEquals(xmlTable, dbTable);
}
/**
* 表里数据和student.xml里的数据的顺序不一致
*/
public void test4() throws Exception{
IDataSetdbDataSet = getConnection().createDataSet();
ITabledbTable = dbDataSet.getTable("student");
IDataSet xmlDataSet= new FlatXmlDataSet(new FileInputStream("student.xml"));
ITablexmlTable = xmlDataSet.getTable("student");
SortedTabledbSortedTable = new SortedTable(dbTable,new String[]{"id"});
//按数据库里表结构字段类型来进行排序,如果是int则按int排序,不是依照字符串的形式排序
dbSortedTable.setUseComparable(true);
SortedTablexmlSortedTable = new SortedTable(xmlTable,new String[]{"id"});
//按数据库里表结构字段类型来进行排序,如果是int则按int排序,不是依照字符串的形式排序
xmlSortedTable.setUseComparable(true);
Assertion.assertEquals(xmlSortedTable, dbSortedTable);
}
/**
* 对student表插入一条记录做测试
* @throws Exception
*/
// public void test5() throws Exception{
//
//
// db.save(users);
//
// IDataSetdataSet = getConnection().createDataSet();
// ITableactualTable = dataSet.getTable("users");
//
// IDataSet dataSet2 = newFlatXmlDataSet(new File("expected.xml"));
// ITableexpectedTable = dataSet2.getTable("users");
//
// Assertion.assertEquals(expectedTable,actualTable);
// }
/**
* 在把xml里的数据导入到db里之前,需要对数据库里的表的数据做的操作。
*/
protected DatabaseOperationgetSetUpOperation() throws Exception
{
System.out.println("setup...");
return DatabaseOperation.CLEAN_INSERT;
}
/**
* 测试执行完以后,需要对数据库里的表里的数据做的操作
*/
protected DatabaseOperation getTearDownOperation() throwsException
{
System.out.println("teardown...");
return DatabaseOperation.DELETE_ALL;
}
}
特别注意注释掉的部分,下面我重写一下:
HibernateTest.java部分:
public voidinsert(Student student){
SessionFactory sessionFactory;
try {
sessionFactory = new Configuration().configure()
.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(student);
tx.commit();
session.close();
sessionFactory.close();
System.out.println("插入数据OK!请在MySQL查看结果!");
}catch (HibernateException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
SimpleTest.java重写部分:
/**
* 对Users表插入一条记录做测试
* @throws Exception
*/
public void test5() throws Exception{
Studentstudent = new Student();
student.setBirthday("1988-11-02");
student.setId("1111");
student.setName("hong");
student.setSex("f");
HibernateTest ht = new HibernateTest();
ht.insert(student);
IDataSetdataSet = getConnection().createDataSet();
ITableactualTable = dataSet.getTable("student");
IDataSet dataSet2 = newFlatXmlDataSet(new File("expected.xml"));
ITableexpectedTable = dataSet2.getTable("student");
Assertion.assertEquals(expectedTable,actualTable);
}
而expected.xml部分如下所示:
<?xmlversion='1.0' encoding='UTF-8'?>
<dataset>
<student id="0001" name="mingg"sex="m" birthday="2011-11-06"/>
<student id="0002" name="jie"sex="f" birthday="2010-10-01"/>
<student id="004" name="dsad"sex="f" birthday="2011-12-14"/>
<student id="0088" name="wangdo"sex="m" birthday="2008-12-16"/>
<student id="1111" name="hong"sex="f" birthday="1988-11-02"/>
</dataset>
右键点击SimpleTest.java类,运行结果如下所示:
下面的五个测试方法全部通过。
(完,待续.................................................................)
我在一个内部论坛也写过的