`
Dev|il
  • 浏览: 121822 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

自己写的一个Hibernate CURD的封装

阅读更多
自己在dome一个小项目的时候,突发奇想,利用单例和工厂加上泛型的知识封装Po的CURD操作,直接上代码,文笔不好,呵呵,还请大家指教

接口规范,定义CURD操作
package edu.sasu.DAO;

import java.util.List;


/**
 * 所有实体类遵循的接口
 * @author Administrator
 *
 * @param <T>
 * @param <ID>
 */
public interface BaseDao<T> {

	/**
	 * 保存实体
	 * @param entity 实体类
	 */
	public boolean save(T entity);
	
	/**
	 * 删除实体
	 * @param entity 实体类
	 */
	public boolean delete(T entity);
	
	/**
	 * 根据实体ID删除实体
	 * @param entity 实体类
	 */
	public boolean deleteById(T entity);
	
	/**
	 * 跟新实体
	 * @param entity 实体类
	 */
	//public boolean update(T entity);
	public boolean update(T entity, Object OID);
	/**
	 * 根据实体d,查询单个实体
	 * @param entity 实体类 
	 * @return
	 */
	//public T findById(T entity);
	public T findById(T entity, Object entityID);
	/**
	 * 累出所有实体集合
	 * @param entityClass 实体类
	 * @return 实体类List
	 */
	public  List<T> findAll(String hql);
	
	public List<T> findAll(T entity);
	
	/**
	 * 保存和跟新方法
	 */
	public boolean saveOrUpdate(T entity);
}



实现BaseDao接口,实现其中的方法
package edu.sasu.DAOImpl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import edu.sasu.DAO.BaseDao;
import edu.sasu.Util.DBUtil;
/**
 * 封装的基类操作
 * @author Administrator
 *
 * @param <T>
 */
public class BaseDAOImpl<T>  implements BaseDao<T>{
	public synchronized boolean delete(T entity) {
		// TODO Auto-generated method stub
		return false;
	}
    /**
     * 删除某条数据
     */
	public synchronized boolean deleteById(T entity) {
		Session session = DBUtil.getDBUtil().getSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			session.delete(entity);
			tx.commit();
		} catch (HibernateException e) {
			if(tx != null){
				tx.rollback();
			}
			return false;
		}
		return true;
	}

	public synchronized List<T> findAll(T entity) {
		// TODO Auto-generated method stub
		return null;
	}
    /**
     * 查找单个数据
     */
	public synchronized T findById(T entity, Object entityID) {
		Session session = DBUtil.getDBUtil().getSession();
		Transaction tx = null;
		T temp;
		try {
			tx = session.beginTransaction();
			temp = (T) session.get(entity.getClass(),(Serializable) entityID);
			tx.commit();
		} catch (HibernateException e) {
			if(tx != null){
				tx.rollback();
			}
			throw e;
		}finally{
			
		}
		return temp;
	}
    /**
     * 保存数据
     */
	public synchronized boolean save(T entity) {
		Session session = DBUtil.getDBUtil().getSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			//session.persist(entity);
			session.save(entity);
			tx.commit();
		} catch (HibernateException e) {
			if(tx != null){
				tx.rollback();
			}
			//return false;
			e.printStackTrace();
		}
		return true;
	}
    /**
     * 跟新数据
     */
	public synchronized boolean update(T entity, Object OID) {
		Session session = DBUtil.getDBUtil().getSession();
		Transaction tx = null;
		
		try {
			tx = session.beginTransaction();	
			T temp = (T) session.get(entity.getClass(), (Serializable) OID);
			session.merge(entity); //如果update要抛异常
			tx.commit();
		} catch (HibernateException e) {
			if(tx != null){
				tx.rollback();
			}
			//return false;
			e.printStackTrace();
		}
		return true;
	}
    /**
     * 查找符合hql的所有数据
     */
	public synchronized List<T> findAll(String hql) {
		Session session = DBUtil.getDBUtil().getSession();
		Transaction tx = null;
		List<T> list = new ArrayList<T>();
		try {
			tx = session.beginTransaction();
			list = session.createQuery(hql).list();
			session.flush();
			tx.commit();
		} catch (HibernateException e) {
			if(tx != null){
				tx.rollback();
			}
			e.printStackTrace();
		}
		return list;
	}
	
	/**
	 * 保存和跟新方法
	 */
	public synchronized boolean saveOrUpdate(T entity) {
		Session session = DBUtil.getDBUtil().getSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			session.saveOrUpdate(entity);
			tx.commit();
		} catch (HibernateException e) {
			if(tx != null){
				tx.rollback();
			}
			//return false;
			e.printStackTrace();
		}
		return true;
	}
}


基础工厂采用单例实现获取实例操作对象
package edu.sasu.factory;

import edu.sasu.DAO.BaseDao;
import edu.sasu.DAOImpl.BaseDAOImpl;
/**
 * 基础工厂
 * @author Administrator
 *
 * @param <T>
 */
public class BaseFactory<T> {
	
	private static BaseFactory baseFactory; //单一实例
	private BaseDao<T> Instance;
	private BaseFactory(){
		Instance = new BaseDAOImpl<T>();	
	}
	
	public BaseDao<T> getInstance(){ //不要把factory的new放在构造函数里面,不然会出现递归错误
		return Instance;
	}
	
	public static BaseFactory getFactory(){
		if(baseFactory == null){
			baseFactory = new BaseFactory();
		}
		return baseFactory;
	}
}

以上定义baseDAO接口,baeDAOIMpl是接口的实现,baseFactory是工厂,对baseDAOimp实例化,
在类中调用为: User(一个PoJo类)
User entity= new User();
BaseFactory<User> factory = BaseFactory.getFactory();
执行保存操作: factory.getInstance().save(entity);  entity User的实例对象
执行保存操作,请大家评点下此种写法有什么不好的地方,本人能力有限,觉得还可以,请大牛指教
分享到:
评论
35 楼 leelege 2011-03-11  
让一切GenericDao都去死吧
34 楼 liuxuejin 2011-03-11  
不用泛型的飘过,个人觉得没有什么必要,因为增删查的代码(简单的)完全可以用sql拼接实现,复杂的查询sql  泛型又不能解决!所以我没有使用!
33 楼 java113096 2011-03-11  
finallygo 写道
icanfly 写道
ricoyu 写道
你为什么要在你的每个方法上做同步控制呢?它们有访问共享资源吗?
+1

+1

+1

32 楼 jiluo093 2011-03-11  
http://jiluo093.iteye.com/blog/953388
31 楼 piao_bo_yi 2011-03-11  
Dev|il 写道
yin_bp 写道
Dev|il 写道
dnstfengtao 写道
finallygo 写道
icanfly 写道
ricoyu 写道
你为什么要在你的每个方法上做同步控制呢?它们有访问共享资源吗?
+1

+1

+1


每个方法加个线程同步的原因是工厂模式是用单例实现的,只存在一个实例对象,如果两个地方同时对这个方法调用,就会存在操作失败,呵呵,写的很差,惭愧


系统的性能都会被你这些synchronized耗尽的,杯具了。

synchronized很耗资源吗?能具体说下吗?呵呵,不理解这个词的含义,只知道他是线程同步的


Lock, access, unlock.
30 楼 yehengxy 2011-03-11  
lsf_demo 写道
superobin 写道
现在惯用的方法是在spring做个切面,把整个事务用切面管理,dao完全不搭理事务的问题。
例如 一个service调用多个dao方法,那么切面应该切在service方法的前后,在进入service方法之前由transcationmanager声明事务(现成的,配置好就是自动的了),进入dao时从dbutil中获取的应该是绑定在sessionholder中的session,进而保证了多个dao方法用的是相同的session从而保证事务;而在service方法结束时,也由transcationmanager将事务提交。(发现异常回滚)


貌似是这么回事。之前翻的是jdbc那部分的源码,hibernate的也看过一点,应该是一样的,就是一个hold的是connection一个hold的是session.另外,可能要注意处理session关闭的问题,看看是否需要用dbutil去关闭session

+1

学到了
29 楼 Aaronlong31 2011-03-11  
楼主的这个和springside里的DAO基类很像,建议你去看看,那里还有对ibatis的封装。
28 楼 jiluo093 2011-03-11  
问一个问题啊,我在用tomcat6+ssh+jotm测试jta时,如果两个数据源都是基于MySQL的就可以,如果一个是MySQL,一个是SqlServer,就不能回滚,请问哪位遇到过吗????
27 楼 lsf_demo 2011-03-11  
superobin 写道
现在惯用的方法是在spring做个切面,把整个事务用切面管理,dao完全不搭理事务的问题。
例如 一个service调用多个dao方法,那么切面应该切在service方法的前后,在进入service方法之前由transcationmanager声明事务(现成的,配置好就是自动的了),进入dao时从dbutil中获取的应该是绑定在sessionholder中的session,进而保证了多个dao方法用的是相同的session从而保证事务;而在service方法结束时,也由transcationmanager将事务提交。(发现异常回滚)


貌似是这么回事。之前翻的是jdbc那部分的源码,hibernate的也看过一点,应该是一样的,就是一个hold的是connection一个hold的是session.另外,可能要注意处理session关闭的问题,看看是否需要用dbutil去关闭session

+1
26 楼 frankiegao123 2011-03-11  
你的代码中没有任何共享资源,都是局部变量。局部变量都在自己的线程栈中,不会被其他线程所看到,因此也没有数据被多个线程共享的问题,所以就不需要同步了,呵呵。
25 楼 huangfoxAgain 2011-03-10  
最重要的一点,不应该将事务处理放到dao里面,放到service层!
24 楼 Dev|il 2011-03-10  
java_xiaoyi 写道
ricoyu 写道
你为什么要在你的每个方法上做同步控制呢?它们有访问共享资源吗?

犀利。。。。

犀利和解啊?能说下原因吗?呵呵
23 楼 Dev|il 2011-03-10  
chionloay 写道
这个只是都是数据库的一些基本操作,如果有很很实体,那么就避免了很多重复的类似代码,还是可以的,如果需要多操作,可以对业务逻辑接口进行扩展,CRUD可以放到基类里面

嗯,是好好法子,让这个类为基类,其他操作继承此类,但线程同步问题怎么解决啊,求解,synchronized很耗资源,呵呵
22 楼 Dev|il 2011-03-10  
whaosoft 写道
icanfly 写道
ricoyu 写道
你为什么要在你的每个方法上做同步控制呢?它们有访问共享资源吗?

+1

也许lz只是提供给学生看的例子而已

呵呵,我就是学生,才大二,想学习下企业的做法,大哥能指点下吗?
21 楼 Dev|il 2011-03-10  
yin_bp 写道
Dev|il 写道
dnstfengtao 写道
finallygo 写道
icanfly 写道
ricoyu 写道
你为什么要在你的每个方法上做同步控制呢?它们有访问共享资源吗?
+1

+1

+1


每个方法加个线程同步的原因是工厂模式是用单例实现的,只存在一个实例对象,如果两个地方同时对这个方法调用,就会存在操作失败,呵呵,写的很差,惭愧


系统的性能都会被你这些synchronized耗尽的,杯具了。

synchronized很耗资源吗?能具体说下吗?呵呵,不理解这个词的含义,只知道他是线程同步的
20 楼 Dev|il 2011-03-10  
程序新手 写道
呵呵 写的不错了,继续努力 ,加油~

呵呵,谢谢
19 楼 chionloay 2011-03-10  
这个只是都是数据库的一些基本操作,如果有很很实体,那么就避免了很多重复的类似代码,还是可以的,如果需要多操作,可以对业务逻辑接口进行扩展,CRUD可以放到基类里面
18 楼 whaosoft 2011-03-10  
icanfly 写道
ricoyu 写道
你为什么要在你的每个方法上做同步控制呢?它们有访问共享资源吗?

+1

也许lz只是提供给学生看的例子而已
17 楼 程序新手 2011-03-10  
呵呵 写的不错了,继续努力 ,加油~
16 楼 yin_bp 2011-03-10  
Dev|il 写道
dnstfengtao 写道
finallygo 写道
icanfly 写道
ricoyu 写道
你为什么要在你的每个方法上做同步控制呢?它们有访问共享资源吗?
+1

+1

+1


每个方法加个线程同步的原因是工厂模式是用单例实现的,只存在一个实例对象,如果两个地方同时对这个方法调用,就会存在操作失败,呵呵,写的很差,惭愧


系统的性能都会被你这些synchronized耗尽的,杯具了。

相关推荐

Global site tag (gtag.js) - Google Analytics