每一个实体都应有一个对应的Dao,他封装了对这个实体的数据库操做。例java
实体Dao接口实现类spring
========================================================数据库
User--> UserDao--> UserDaoImplsession
Role--> RoleDao--> RoleDaoImpl框架
Department--> DepartmentDao--> DepartmentDaoImplide
Article--> ArticleDao--> ArticleDaoImplthis
...spa
BaseDao.java----把每一个dao都须要的方法放到这里,好让他们继承设计
public interface BaseDao<T> { void save(T entity); /** * 保存实体 * @param id */ void delete (Long id); /** * 删除实体 * @param entity */ void update(T entity); /** * 更新实体 * @param id * @return */ T getById(Long id); /** * 按id查询 * @return */ List<T> getByIds(Long[] id); /** * 按id查询 * @return */ List<T> findAll(); /** * 查询全部 */ }
UserDao.java----一些公用的方法继承BaseDao便可code
public interface UserDao extends BaseDao<User>{ //本身有的特殊方法写在本身这里面 }
RoleDao.java
public interface RoleDao extends BaseDao<Role>{ }
增删改查等共有方法都有了
//实现RoleDao,实现全部未实现的方法 public class RoleDaoImpl implements RoleDao{ public void save(Role entity) { } public void delete(Long id) { } public void update(Role entity) { } public Role getById(Long id) { return null; } public List<Role> getByIds(Long[] id) { return null; } public List<Role> findAll() { return null; } }
public class UserDaoImpl implements RoleDao{ public void save(Role entity) { } public void delete(Long id) { } public void update(Role entity) { } public Role getById(Long id) { return null; } public List<Role> getByIds(Long[] id) { return null; } public List<Role> findAll() { return null; } }
public class BaseDaoImpl<T> implements BaseDao<T> { public void save(T entity) { } public void delete(Long id) { } public void update(T entity) { } public T getById(Long id) { return null; } public List<T> getByIds(Long[] id) { return null; } public List<T> findAll() { return null; } }
public class RoleDaoImpl extends BaseDaoImpl<Role> implements RoleDao{ }
public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao{ }
能够看出这两个实现类的不少方法都重复了,咱们把它抽取出来,咱们写一个类它事先实现了里面的公共方法,让这两个实现类继承便可。
BaseDaoImpl里方法是有了,但里面尚未内容,接下来写该实现类里面的方法内容
@SuppressWarnings("unchecked") public abstract class BaseDaoImpl<T> implements BaseDao<T> { @Resource private SessionFactory sessionFactory;// 经过注入获得SessionFactory,要把它放到容器里才能注入,在具体的实现类上声明@Repository private Class<T> clazz; public BaseDaoImpl() { //使用反射技术获得T的真实类型 ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();//获取当前new类型的泛型的父类类型 this.clazz = (Class<T>) pt.getActualTypeArguments()[0];//获取第一个类型参数的真实类型,只有一个泛型参数,因此写0 System.out.println("clazz--->" + clazz); } /** * 获取当前可用的session对象,用protected修饰方便子类获得session */ protected Session getSession() { return sessionFactory.getCurrentSession(); } public void save(T entity) { // 不须要本身关事务了,spring框架已经帮咱们作了,咱们用它的事务管理 getSession().save(entity); } public void update(T entity) { getSession().update(entity); } public void delete(Long id) { Object obj = getById(id); if (obj != null) { getSession().delete(obj); } } public T getById(Long id) { return (T) getSession().get(clazz, id); } public List<T> getByIds(Long[] ids) { return getSession().createQuery(// "FROM User WHERE id=IN(:ids)")// .setParameter("", ids) .list(); } public List<T> findAll() { return getSession().createQuery(// "FROM " + clazz.getSimpleName())// .list(); } }
说明:
4, 实体的Dao接口要继承BaseDao接口。
5, Dao的实现类要继承DaoImplBase类。
6, 也能够不继承指定的接口或类,这样就要本身写相应的方法。
7, T getById(Long id)与List<T> getByIdList(Long[] idList)不要合并为List getById(Long... ids),由于获取一个对象时也是返回List,不方便。
获取 BaseDao的类型参数T的Class
问题:
1, 有了DaoBase与DaoImplBase,还要用UserDao、RoleDao吗?
答:要用。由于UserDao或RoleDao中的方法能够分为有公有的方法与特有的方法两部分。公有的方法是经过继承BaseDao获得的,特有的方法要写在本身里面(BaseDao中是没有的)。
2, UserDaoImpl已经继承了BaseDaoImpl,就不实现UserDao能够吗?
答:不能够。不然UserDao userDao = new UserDaoImpl(); 就不成立。
使用反射获取类型参数的真实类型的代码以下:
public DaoBaseImpl () { Type type = this.getClass().getGenericSuperclass(); ParameterizedType pt = (ParameterizedType) type; this.clazz = (Class<T>) pt.getActualTypeArguments()[0]; } |
说明:
1, 使用Session时,不要本身建立,也不要管理事务,直接调用getSession()便可。
2, 暂时不实现getSession()方法,在后面的事务管理中实现:
protected Session getSession(){
throw new UnsupportedOperationException();
}