JAVA 数据库测试框架DBUnit之Hibernate篇

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类,运行结果如下所示:




下面的五个测试方法全部通过。
(完,待续.................................................................)

我在一个内部论坛也写过的

 

你可能感兴趣的:(java,Hibernate,数据库,框架,exception,测试)