構建HibernateUtil測試Entity層代碼

網站後端一般從下往上有Entity層(對應DB table) —> Dao層(對應DB table增刪改查各種操作)—> Service層(業務邏輯層,調用dao層和DB打交道) —> Controller層(對應各種http api,調用service)。

前後端分離開發的話,後端必須做到充分的自測,才能保證前後端聯調時不出大問題。如果Dao層使用JPA的話,其實不需要測試,除非用錯了。那麼,針對entity層和service/controller層,後端開發時怎麼自測一直是個問題縈繞在我心頭。

目前這個問題的一半找到了答案,可以使用Hibernate Session對entity類進行測試。如果entity類的字段定義或者註解不合理的話,增刪改查操作會報錯,那麼上層的service/controller也就會出錯。所以entity層的測試其實十分必要。在測試過程中,將hibernate配置成打印sql語句,並且在實際unit test的catch子句裏打印stack trace十分實用,能快速定位問題。

步驟總結如下,供日後參考:

  1. 首先在src/main/resource下增加配置文件hibernate.cfg.xml,配置數據庫driver,dialect,數據庫連接url,用戶名,密碼等等,記得把需要測試的entity類配置到mapping節點裏,class=“完整包名.entity類名”

有時候爲了省事兒,也可以不配置這個文件,直接在HibernaterUtil類裏,創建SessionFactory實例時把各項配置塞進去。下一步代碼裏會有示例。

<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://dburl/auto</property>
        <property name="hibernate.connection.username">DB用戶名</property>
        <property name="hibernate.connection.password">DB密碼</property>
        <property name="hibernate.connection.pool_size">1</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="hbm2ddl.auto">update</property>
        <mapping class="com.ssophie.xxxentiry"/>
        <mapping class="com.ssophie.oooentity"/>
    </session-factory>
</hibernate-configuration>
  1. HibernateUtil.class
    如果走hibernate.cfg.xml的話,代碼異常簡單,一句話的事兒:sessionFactory = new Configuration().configure().buildSessionFactory();
    不走hibernate.cfg.xml的話呢,就把每個配置項塞進去:
Configuration configuration = new Configuration().configure().buildSessionFactory();
				.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect")
			    .setProperty("hibernate.connection.driver_class", "com.mysql.cj.jdbc.Driver")
			    .setProperty("hibernate.connection.url", "DBUrl...").setProperty("hibernate.connection.username","oooo")
			    .setProperty("hibernate.connection.password", "xxxx");
		ServiceRegistry serviceRegistry
        = new StandardServiceRegistryBuilder()
            .applySettings(configuration.getProperties()).build(); configuration.addAnnotatedClass(entity_xxx.class).addAnnotatedClass(entity_ooo.class);
    sessionFactory = configuration
            .buildSessionFactory(serviceRegistry);

完整的HibernateUtil類代碼如下,創建SessionFactory實例之後,使用sessionFactory.openSession()就可以拿到一個session.

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

import com.ssc.ssgx.web.entities.xxx;
import com.ssc.ssgx.web.entities.ooo;

public class HibernateUtil {
	private static SessionFactory sessionFactory = null;

	static {
		try{
			loadSessionFactory();
		}catch(Exception e){
			System.err.println("Exception while initializing hibernate util.. ");
			e.printStackTrace();
		}
	}
	public static void loadSessionFactory(){
		sessionFactory = new Configuration().configure().buildSessionFactory();
		/**
		Configuration configuration = new Configuration().configure().buildSessionFactory();
				.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect")
			    .setProperty("hibernate.connection.driver_class", "com.mysql.cj.jdbc.Driver")
			    .setProperty("hibernate.connection.url", "DBUrl...").setProperty("hibernate.connection.username","oooo")
			    .setProperty("hibernate.connection.password", "xxxx");
		ServiceRegistry serviceRegistry
        = new StandardServiceRegistryBuilder()
            .applySettings(configuration.getProperties()).build(); configuration.addAnnotatedClass(entity_xxx.class).addAnnotatedClass(entity_ooo.class);
    sessionFactory = configuration
            .buildSessionFactory(serviceRegistry);**/
	}

public static Session getSession() throws HibernateException {

		Session retSession=null;
	    	try {
	    		retSession = sessionFactory.openSession();
	    	}catch(Throwable t){
			System.err.println("Exception while getting session.. ");
			t.printStackTrace();
	    	}
	    	if(retSession == null) {
	    		System.err.println("session is discovered null");
	    	}
	    	return retSession;
    }
}
  1. 測試類裏,在BeforeClass裏獲取session,然後執行各個test單元,最後在AfterClass裏關閉session即可。如果是進行刪除修改測試的話,記得tansaction要commit…
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.ssc.ssgx.web.entities.CaseInfo;

public class CaseInfoTest {
	
	private static Session session;
	
	@BeforeClass
	public static void getSession(){
		session = HibernateUtil.getSession();
	}
	
	@Test
	public void TestAddCase() {
		Transaction transaction = null;
		try {
			transaction = session.beginTransaction();
			CaseInfo caseInfo = new CaseInfo();
			caseInfo.setCaseDesc("xxx");
			caseInfo.setCaseId("xxx");
			session.save(caseInfo);
			transaction.commit();
		} catch (Exception exception) {
System.out.println(exception.getMessage());
			transaction.rollback();
		}
	}
	
	@Test
	public void deleteCase(){
		Transaction transaction = null;
		try {
			transaction = session.beginTransaction();
			CaseInfo c = session.get(CaseInfo.class, Long.valueOf(6l));
			session.delete(c);
			transaction.commit();
		} catch (Exception exception) {
		System.out.println(exception.getMessage());
			transaction.rollback();
		}
	}
	
	@AfterClass
	public static void closeSession(){
		if(session != null)
			session.close();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章