HibernateUtils 与第三方边界

        

       花了一下午重构了下数据库交互层的代码,减少了piles of code ,  称起来应该有几克重吧? 还想到了一个模板方法模式,进一步减少了一大堆的getSession 和 closeSession. 感觉还不错。错漏或考虑不周之处,还恳请指出。

        

package com.ccnu.salary.utils;



import java.util.ArrayList;

import java.util.List;



import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;



/**

 * 提供 数据库交互的可复用代码

 *

 */



public class HibernateUtils {

	

	private static SessionFactory factory;   

	

	private HibernateUtils() {}

	

	static {

		Configuration cfg = new Configuration().configure();

		factory = cfg.buildSessionFactory();

	}

	

	public static SessionFactory getSessionFactory() {

		return factory;

	}

	

	public static Session getSession() {

		return factory.openSession();

	}

	

	public static void closeSession(Session session) {

		if (session != null) {

			if (session.isOpen()) {

				session.close();

			}

		}

	}

	

	public interface ActionInSession {

		Object doSomething(Session session);

	}

	

	public static Object templatedExec(ActionInSession ais)

	{

		Session session = null;

		try{

			session = getSession();

			session.beginTransaction();

			Object obj = ais.doSomething(session);

			session.getTransaction().commit();

			return obj;

		} catch (Exception e) {

			e.printStackTrace();

			session.getTransaction().rollback();

		} finally {

			HibernateUtils.closeSession(session);

		}

		return null;

	}

	

	public static void save(final Object obj){

		templatedExec(new ActionInSession() {



			@Override

			public Object doSomething(Session session) {

				session.save(obj);

				return null;

			}

			

		});

	}

	

	

	public static void deleteById(final Class c, final long id)

	{

		templatedExec(new ActionInSession() {



			@Override

			public Object doSomething(Session session) {

				Object obj = session.load(c, id);

				session.delete(obj);

				return null;

			}

			

		});

	}

	

	public static void delete(final Object obj)

	{

		templatedExec(new ActionInSession() {



			@Override

			public Object doSomething(Session session) {

				session.delete(obj);

				return null;	

			}

			

		});

	}

	

	public static Object findById(final Class c, final long id)

	{

		return templatedExec(new ActionInSession(){



			@Override

			public Object doSomething(Session session) {

				return session.get(c, id);

			}

			

		});

	}

	

	public static Object findByCondition(final String hql, final String param1, final String param2)

	{

		return templatedExec(new ActionInSession() {



			@Override

			public Object doSomething(Session session) {

				return session.createQuery(hql)

						.setParameter(0, param1)

						.setParameter(1, param2)

						.uniqueResult();

			}

			

		}) ;

	}

	

	

	public static List findAll(final String hql)

	{

		return (List) templatedExec(new ActionInSession() {



			@Override

			public Object doSomething(Session session) {

				return session.createQuery(hql).list();	

			}

			

		}) ;	

	}

	

}

 

 

        在《代码整洁之道》中谈到, 当引入第三方框架或代码时,要谨慎地控制其作用的范围及影响,而不是简单地无所顾忌地使用其带来的便利。换句话说,要将第三方代码局限在一个范围内,当需要换用框架时,不至于影响系统整体,这就是所谓的第三方边界。HibernateUtils 就是这样一个第三方边界, 将 Hibernate 框架的影响范围限制在一个类中, 需要改动的时候,只需要改动少量的地方即可。当然,这里主要起演示性的作用,在大型项目中,可能需要采用更精细的手段来实现真正稳固可靠的第三方边界。


        后记:  实际上, Spring HibernateTemplate 已经做了此工作,而且比本文做的更可靠,  多了解一些开源组件、库, 对于避免做重复工作是非常有益的。 当然, 使用自己编写的组件最大的优势是简单,灵活, 不必为了一个轮胎去借一辆汽车。



 

你可能感兴趣的:(Hibernate)