1. 设计说明
在我们的电子相册系统中,主要的两个对象就是:相片(photo)、用户(user)。所以我们就针对这两个对象来进行设计。而这两个对象都涉及到了对其进行:添加、删除、更新、查找。所以我们可以把共有的方法封装到一个方法。由于我们的编程提倡是用接口思想,所以最好是设计个接口,然后用实现类来实现。例如,我们设计个BaseDao的接口,这个接口中包含了所在共用的方法名,然后用BaseDaoImpl的类实现BasseDao的方法。这样共用的方法就设计好了。接下来就是根据具体的对象来调用了。如,我们对User进行DAO的操作,那么我们就会设计个UserDao来继承接口BaseDao,然后用UserDaoImpl来继承BaseDaoImpl类,这样实现的类也就设计好了。
2. Dao实例图
3. 代码实现
1) 公用接口BaseDao,这里就包含了所有的对象操作的公共部分。这里包含了发下几个方面:根据ID加载实体、保存实体、更新实体、删除实体、删除实体、根据ID删除实体、获取所有实体、获取实体总数。值我们去注意的就是,这里我们用了泛型的设计,因为它是公共的方法,所以我们也不清楚是什么对象调用了这个接口。
public interface BaseDao<T>
{
/**
* 根据ID加载实体
* @param entityClazz
* @param id
* @return
*/
T get(Class<T> entityClazz, Serializable id);
/**
* 保存实体
* @param entity
* @return
*/
Serializable save(T entity);
/**
* 更新实体
* @param entity
*/
void update(T entity);
/**
* 删除实体
* @param entity
*/
void delete(T entity);
/**
* 根据ID删除实体
* @param entity
* @param id
*/
void delete(Class<T> entity, Serializable id);
/**
* 获取所有实体
* @param entityClazz
* @return
*/
List<T> findAll(Class<T> entityClazz);
/**
* 获取实体总数
* @param entityClazz
* @return
*/
long findCount(Class<T> entityClazz);
}
2) 编写好了接,那么接下来我们要做的事情就是要实现这些接口的方法。
public class BaseDaoImpl<T> implements BaseDao<T>
{
//DAO组件进行持久操作底层依赖的SessionFactory组件
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory()
{
return this.sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
@SuppressWarnings("unchecked")
@Override
public T get(Class<T> entityClazz, Serializable id)
{
return (T)getSessionFactory().getCurrentSession().get(entityClazz, id);
}
@Override
public Serializable save(T entity)
{
return getSessionFactory().getCurrentSession().save(entity);
}
@Override
public void update(T entity)
{
getSessionFactory().getCurrentSession().update(entity);
}
@Override
public void delete(T entity)
{
getSessionFactory().getCurrentSession().delete(entity);
}
@Override
public void delete(Class<T> entity, Serializable id)
{
delete(get(entity, id));
}
@Override
public List<T> findAll(Class<T> entityClazz)
{
return find("select en from " + entityClazz.getSimpleName() + " en");
}
@Override
public long findCount(Class<T> entityClazz)
{
List list = find("select count(*) from " + entityClazz.getSimpleName());
if (list != null && list.size() == 1)
{
return (Long) list.get(0);
}
return 0;
}
/**
* 根据HQL语句查询实体
* @param hql
* @return
*/
@SuppressWarnings("unchecked")
protected List<T> find(String hql)
{
return (List<T>)getSessionFactory().getCurrentSession().createQuery(hql).list();
}
/**
* 根据带占位符参数HQL语句查实体
* @param hql
* @param params
* @return
*/
@SuppressWarnings({ "unchecked", "unused" })
protected List<T> find(String hql, Object...params)
{
Query query = getSessionFactory().getCurrentSession().createQuery(hql);
for (int i=0, len = params.length; i < len; i++)
{
query.setParameter(i + "", params[i]);
}
return (List<T>)query.list();
}
/**
* 分页查询
* @param hql
* @param pageNo
* @param pageSize
* @return
*/
@SuppressWarnings("unchecked")
protected List<T> findByPage(String hql, int pageNo, int pageSize)
{
return getSessionFactory().getCurrentSession().createQuery(hql)
.setFirstResult((pageNo - 1) * pageSize)
.setMaxResults(pageSize)
.list();
}
/**
* 分页查询,多个参数
* @param hql
* @param pageNo
* @param pageSize
* @param params
* @return
*/
@SuppressWarnings("unchecked")
protected List<T> findByPage(String hql, int pageNo, int pageSize, Object...params)
{
Query query = getSessionFactory().getCurrentSession().createQuery(hql);
for (int i = 0, len = params.length; i < len; i++)
{
query.setParameter(i + "", params[i]);
}
return query.setFirstResult((pageNo - 1) * pageSize)
.setMaxResults(pageSize)
.list();
}
}
3) 现在我们设计个用户的接口——UserDao,这个接口只要继承BaseDao就可以了,同时,如果有自己的独有的方法,那么就再进行添加。
public interface UserDao extends BaseDao<User>
{
/**
* 根据用户名查找的用户
* @param name 需要查找的用户的用户名
* @return 查找到的用户
*/
User findByName(String name);
}
4) 一样的,我们也要对这个接口进行实现。注意的是,这个接口不仅要实现UserDao的方法,同时还要继承接口BaseDaoImpl。
public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao
{
@Override
public User findByName(String name)
{
List<User> users = find("select u from User u where u.name = ?0", name);
if (users != null && users.size() == 1)
{
return users.get(0);
}
return null;
}
}
5) 对于相片的Dao实现与用户的实现是一样的,所以这里就不给出了。读者可以见源码。