构建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();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章