首先说明,这个东西最开始是我从网上找到的,但是不记得在那里找到的了。只是觉得非常有用,所以就根据我的需要做了修改,放在了这里,当作一个备忘录吧。
这个是接口:
/**
* @author Fred
* Jun 25, 2007 5:52:47 PM
*/
public interface BaseDao<T>{
/**
* 根据对象ID来查询对象。
* @param id 对象ID。
* @return 如果找到对应的对象,则返回该对象。如果不能找到,则返回null。
*/
public T findById(Long id);
/**
* 查询所有的指定对象。
*/
public List listAll();
/**
* 查询,并指定起始的纪录和最大的查询结果集大小以及需要排序的属性和排序的方向。
* @param startPos 起始纪录的序号。
* @param amount 最大的查询结果集大小。
* @param conditions 一个以属性名为key,以属性值为value的Map
* @param sortableProperty 需要排序的属性。
* @param desc 排序的方向。
* @return 结果集。
*/
public List listAndSort(int startPos, int amount, Map conditions, String sortableProperty, boolean asc);
/**
* 统计当前的总纪录数.
*/
public Long countTotalAmount();
/**
* 持久化指定的对象。
* @param entity 将要持久化的对象。
* @return 持久化以后的对象。
*/
public T save(T entity);
/**
* 在数据库中删除指定的对象。该对象必须具有对象ID。
* @param entity 将要被删除的对象。
*/
public void delete(T entity);
/**
* 更新给定的对象。
* @param entity 含有将要被更新内容的对象。
* @return 更新后的对象。
*/
public T update(T entity);
/**
* 获取标志是否被删除的标志字段。如果是直接删除,返回 null
*/
public String getDeleteToken();
}
然后是其实现类:
/**
* 范型化的BaseDao的实现,作为其他实际被Service层调用的Dao实现的基类。
* @author Fred
* Jun 25, 2007 5:56:38 PM
*/
public class BaseDaoImpl extends HibernateDaoSupport implements BaseDao {
private Class persistentClass;
protected static final String DEFAULT_INDEIRECTLY_DELETE_TOKEN = "disused";
/**
* @return the persistentClass
*/
public Class getPersistentClass() {
return this.persistentClass;
}
/**
* 默认构造函数,用于获取范型T的带有类型化信息的Class对象
*/
@SuppressWarnings("unchecked")
public BaseDaoImpl() {
this.persistentClass = (Class) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
@SuppressWarnings("unchecked")
public T findById(Long id) {
return (T) this.getHibernateTemplate().get(this.getPersistentClass(), id);
}
public List listAll() {
return this.findByCriteria();
}
@Override
public List listAndSort(int startPos, int amount, Map conditions, String sortableProperty,
boolean asc) {
return this.listAndSort(this.getPersistentClass(), startPos, amount, conditions, sortableProperty, asc, false);
}
@Override
public Long countTotalAmount() {
StringBuilder hql = new StringBuilder()
.append("select count(obj.id) from ")
.append(BaseDaoImpl.this.getPersistentClass().getSimpleName())
.append(" obj ");
if (BaseDaoImpl.this.getDeleteToken() != null) {
hql.append("where obj.")
.append(BaseDaoImpl.this.getDeleteToken())
.append(" = false");
}
final String hqlString = hql.toString();
return (Long) this.getHibernateTemplate().execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Query query = session.createQuery(hqlString.toString());
return query.uniqueResult();
}
});
}
public T save(T entity) {
this.getHibernateTemplate().saveOrUpdate(entity);
return entity;
}
public T update(T entity) {
this.getHibernateTemplate().update(entity);
return entity;
}
public void delete(T entity) {
this.getHibernateTemplate().delete(entity);
}
@SuppressWarnings("unchecked")
protected List findByCriteria(Criterion... criterion) {
DetachedCriteria detachedCrit = DetachedCriteria
.forClass(getPersistentClass());
for (Criterion c : criterion) {
detachedCrit.add(c);
}
return getHibernateTemplate().findByCriteria(detachedCrit);
}
/**
* 查询,并指定起始的纪录和最大的查询结果集大小以及需要排序的属性和排序的方向。
* @param clazz 要被查询的对象对应的Class。
* @param startPos 起始纪录的序号。
* @param amount 最大的查询结果集大小。
* @param conditions 一个以属性名为key,以属性值为value的Map
* @param sortableProperty 需要排序的属性。
* @param desc 排序的方向。
* @return 结果集。
*/
@SuppressWarnings("unchecked")
protected List listAndSort(Class clazz, final int startPos, final int amount,
final Map conditions, String sortableProperty, boolean asc, boolean getDisused) {
boolean hasCondition = false;
StringBuilder hql = new StringBuilder().append("from ").append(clazz.getSimpleName()).append(" obj ");
//是否查询被删掉的
if (this.getDeleteToken() != null) {
hasCondition = true;
hql.append("where obj.")
.append(this.getDeleteToken())
.append(" ");
if (getDisused) {
hql.append("is true ");
} else {
hql.append("is false ");
}
}
//设置查询条件
boolean needsAnd = false;
if (!conditions.isEmpty()) {
if (!hasCondition) {
hql.append("where ");
} else {
needsAnd = true;
}
}
for (String property : conditions.keySet()) {
if (needsAnd) {
hql.append("and ");
}
hql.append("obj.").append(property).append(" = :").append(property).append(" ");
}
//排序
hql.append("order by ").append(" obj.").append(sortableProperty).append(" ");
if (asc) {
hql.append("asc");
} else {
hql.append("desc");
}
//分页
final String hqlString = hql.toString();
return (List) this.getHibernateTemplate().execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Query query = session.createQuery(hqlString);
query.setFirstResult(startPos);
query.setMaxResults(amount);
//给查询条件赋值
for (String property : conditions.keySet()) {
query.setParameter(property, conditions.get(property));
}
return query.list();
}
});
}
@Override
public String getDeleteToken() {
return null;
}
}
最后,你的实际使用的Dao就可以继承这个基本的Dao实现,只需要添加在实际中需要的特定方法就可以了,对在基本的Dao实现中提供的方法可以直接使用,而且不用考虑类型问题。比如:
我有一个UserDao,是作对用户对象的操作的:
接口如下:
/**
* @author Fred
* Jun 26, 2007 12:16:47 AM
*/
public interface UserDao extends BaseDao {
/**
* 根据用户ID查找用户
*/
public User find(String userId);
}
实现类如下:
/**
* @author Fred
* Jun 26, 2007 12:20:49 AM
*/
public class UserDaoImpl extends BaseDaoImpl implements UserDao {
@SuppressWarnings("unchecked")
public User find(final String userId) {
return (User) this.getHibernateTemplate().execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
String hql = "from User user where user.userId = :userId";
Query query = session.createQuery(hql);
query.setString("userId", userId);
return query.uniqueResult();
}
});
}
@Override
public String getDeleteToken() {
return "expired";
}
}
我们的这个UserDaoImpl没有提供对
public User findById(Long id);
这样的方法的实现,但是通过
public class UserDaoImpl extends BaseDaoImpl implements UserDao {
......
}