您的位置:首页 > 其它

SSH的一个BaseDao继承HibernateDaoSupport(二)

2013-05-07 10:24 375 查看
之前做过一个SSH中BaseDao的设计,当时没有做一些修改,里面的方法也有许多不完善的部分。

抽空整理了一下,没有很大改动,只是加入了自己的一部分想法和注释,不求尽善尽美,仍有很大的改动空间。

如果有那位朋友做了改动,可以分享下,让更多的人看到你的想法。

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
* T extends Serializable T其实就是一个占位符, 你也可以换成其它字母,但作为惯例 当我们需要一种类型时,我们都T来占位,表示Type ,
* 后面的extends Serializable 表示在实际应用过程中,替换T的类型必须实现Serializable接口. PK => Primary
* Key
*/
/**
* DAO 对实体提供了持久化操作和查询支持Transaction control of the save(), update() and delete()
* 对增删改操作的事务控制可以直接支持由spring容器管理的事务管理
* 或者他们可以添加到用户管理的spring事务管理的操作中.
* 这些方法都提供了如何配置事务所需类型的附加信息
* @author Administrator
* @param <T>T extends Serializable
* 		  T其实就是一个占位符, 你也可以换成其它字母,但作为惯例
* 		  当我们需要一种类型时,我们都T来占位,表示Type ,
*/
@SuppressWarnings("unchecked")
public class BaseDAO<T extends Serializable, PK extends Serializable> extends HibernateDaoSupport {
private static final Log log = LogFactory.getLog(BaseDAO.class);

/**
* 加入该类型变量的原因,
* 只是为了将每个子类所服务的实体确定一下.
*/
private Class<T> claz;

/**
* 无参数的构造方法,只是为了spring的实例化
*/
public BaseDAO() {

}

/**
* 这种构造方法规定了每个子类将所服务的实体类型传入
* 弥补了泛型使用中,无法在sql等语句中无法使用类型的bug\
* 同样的如果子类的dao在使用spring注入时,
* 必须使用无参数的构造方法,例:
* public class AbcDao extent BaseDao<..>{
* 	public AbcDao(){
* 		super(Abc.class);
* 	}
* }
* @param claz
*/
public BaseDAO(Class claz) {
this.claz = claz;
}

public Serializable save(T entity) {
log.debug("saving " + claz + " instance");

Serializable ret = 0;

try {
ret = getHibernateTemplate().save(entity);
log.debug("save successful");
} catch (RuntimeException re) {
log.error("save failed", re);
throw re;
}
return ret;
}

public T findById(PK id) {
log.debug("getting " + claz.getName() + " instance with id: " + id);
try {
T instance = (T) getHibernateTemplate()
.get(claz, id);
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}

public List<T> findByExample(T entity) {
log.debug("finding " + claz.getName() + " instance by example");
try {
List<T> results = getHibernateTemplate().findByExample(entity);
log.debug("find " + claz.getName() + " by example successful, result size: "
+ results.size());
return results;
} catch (RuntimeException re) {
log.error("find by example failed", re);
throw re;
}
}

public List<T> findByProperty(String propertyName, Object value) {
log.debug("finding " + claz.getName() + " instance with property: "
+ propertyName + ", value: " + value);
try {
String queryString = "from " + claz.getName() + " as model where model."
+ propertyName + "= ?";
return getHibernateTemplate().find(queryString, value);
} catch (RuntimeException re) {
log.error("find by property name failed", re);
throw re;
}
}

public void update(T entity) {
log.debug("start update");
getHibernateTemplate().update(entity);
log.debug("end update");
}

public List findAll() {
log.debug("finding all " + claz.getName() + " instances");
try {
String queryString = "from " + claz.getName();
return getHibernateTemplate().find(queryString);
} catch (RuntimeException re) {
log.error("find all failed", re);
throw re;
}
}

/****
* merge的作用是:新new一个对象,如果该对象设置了ID,则这个对象就当作游离态处理:
* 当ID在数据库中不能找到时,用update的话肯定会报异常,然而用merge的话,就会insert。
* 当ID在数据库中能找到的时候,update与merge的执行效果都是更新数据,发出update语句;
* 如果没有设置ID的话,则这个对象就当作瞬态处理:
* 用update的话,由于没有ID,所以会报异常,merge此时则会保存数据,根据ID生产策略生成一条数据;
* 用update是直接把实体和数据库同步,
* 而是要merge方法时 merge操作的是实体的代理对象,
* 所以我们用它时一定要把它放到事务中执行,
* 否则会报could not load an entity异常,
* 意思是在:this.getHibernateTemplate().merge(dc);
* 语句前面开启一个事务就OK
* @param detachedInstance
* @return
*/
public T merge(T entity) {
log.debug("merging " + claz.getName() + " instance");
try {
Transaction transaction = this.getSessionFactory().getCurrentSession().beginTransaction();
T result = (T) getHibernateTemplate().merge(entity);
transaction.commit();
log.debug("merge successful");
return result;
} catch (RuntimeException re) {
log.error("merge failed", re);
throw re;
}
}

/**
* 将传入的对象持久化并保存。
* 如果对象未保存(Transient状态),调用save方法保存。
* 如果对象已保存(Detached状态),调用update方法将对象与Session重新关联。
*/
public void attachDirty(T entity) {
log.debug("attaching dirty " + claz.getName() + " instance");
try {
getHibernateTemplate().saveOrUpdate(entity);
log.debug("attach successful");
} catch (RuntimeException re) {
log.error("attach failed", re);
throw re;
}
}

/**
* 将传入的对象状态设置为Transient状态
*/
public void attachClean(T entity) {
log.debug("attaching clean " + claz.getName() + " instance");
try {
getHibernateTemplate().lock(entity, LockMode.NONE);
log.debug("attach successful");
} catch (RuntimeException re) {
log.error("attach failed", re);
throw re;
}
}

public void update(final String hql, final Object[] params) {
// 使用回调接口完成操作
super.getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Query query = session.createQuery(hql);
System.out.println(hql);
for (int i = 0; i < params.length; i++) {
query.setParameter(i, params[i]);
}
query.executeUpdate();
return null;
}
});
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: