在做管理系统时。通常基于Facade模式的系统持久化层要写许多Dao。这些dao里面的方法又是重复的,那么有没有什么好的方法来统一利用一个公共的Dao。
答案是可以的。这里我们接触到JDK5.0里面的一个新特性:泛型。
关于泛型的含义我这里就不再解释了。
下面我们以一个对用户管理和新闻管理的来示范。
首先是2个POJO。我这里只列出User POJO。
(基于注释的Pojo)
如果按照常规的Facade模式来设计,我们的思路是:
先创建一个UserDao的接口。
然后实现这个接口:UserDaoImpl
持久化层完毕。
接下来的是事务层
先创建一个UserService的接口。
然后实现这个接口:UserServiceImpl。
在UserServiceImpl里引用UserDao来实现业务逻辑。
按照上面的模式:新闻管理也这么写一遍。
重复的工作使得我们觉得好烦。
这个时候是泛型出场的时候了。
基于Facade的设计模式,dao和service还是要的。 这里我们就要设计一个公共的Dao.. 我们称之为:GenericDao
看到,我们不再是具体的User , News
。。而是用 T 来取代实体。
因为我这个是基于 注解的,所以附上MyHibernateDaoSupport的代码。
到现在位置genericdao的接口有了,也就是我们要做什么。。现在就是实现它,就是怎么做。
GenericDaoImpl 代码:
至此 泛型就告一个段落。
接下来日子就好过了。
我们不是有user news 等等一系列的curd管理。
以User为例子;
定义一个user的接口,
UserDao.Java
持久化层就是这么多了。
下面进入业务逻辑层,依然是先定义一个接口。
接下来是实现
Ok。。到现在我们就利用泛型dao来设计就完毕了
两者相对比,发现dao层的代码可以复用,少了不少。
对于大型管理系统,效果更明显。
Junit Test方法我这里就不提供了。
参考: rongxh7
吼吼。谢谢!
欢迎大家提出意见,但是拒绝人身攻击。
答案是可以的。这里我们接触到JDK5.0里面的一个新特性:泛型。
关于泛型的含义我这里就不再解释了。
下面我们以一个对用户管理和新闻管理的来示范。
首先是2个POJO。我这里只列出User POJO。
(基于注释的Pojo)
- package com.oa;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.GenerationType;
- import javax.persistence.Id;
- import javax.persistence.Table;
- @Entity
- @Table(name = "tb_user")
- public class User {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private int id;
- @Column(name = "username", length = 15)
- private String username;
- @Column(name = "password", length = 15)
- private String password;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- }
先创建一个UserDao的接口。
- package com.oa.dao;
- import java.util.List;
- import com.oa.User;
- public interface UserDao {
- public void save(User user);
- public void delete(int id);
- public void update(User user);
- public List<User> query();
- public User get(int id);
- }
- package com.oa.dao.impl;
- import java.util.List;
- import org.springframework.context.annotation.Scope;
- import org.springframework.stereotype.Repository;
- import com.oa.User;
- import com.oa.dao.MyHibernateDaoSupport;
- import com.oa.dao.UserDao;
- /**
- * 从Spring 2.0开始,引入了@Repository注解,
- * 用它来标记充当储存库(又称 Data Access Object或DAO)角色或典型的类
- */
- /**
- * Spring 2.5引入了更多典型化注解(stereotype annotations): @Component、@Service和 @Controller。
- * @Component是所有受Spring管理组件的通用形式; 而@Repository、@Service和 @Controller则是@Component的细化,
- * 用来表示更具体的用例(例如,分别对应了持久化层、 服务层 和 表现层)。
- */
- //@Scope("singlton")
- @Repository("userDao")//声明此类为数据持久层的类
- public class UserDaoImpl extends MyHibernateDaoSupport implements UserDao {
- public void delete(int id) {
- super.getHibernateTemplate().delete(
- super.getHibernateTemplate().load(User.class, id));
- }
- public User get(int id) {
- return (User) super.getHibernateTemplate().get("from User", id);
- }
- @SuppressWarnings("unchecked")
- public List<User> query() {
- return super.getHibernateTemplate().find("from User");
- }
- public void save(User user) {
- super.getHibernateTemplate().save(user);
- }
- public void update(User user) {
- super.getHibernateTemplate().update(user);
- }
- }
接下来的是事务层
先创建一个UserService的接口。
- package com.oa.service;
- import com.oa.User;
- public interface UserService {
- public void save(User user);
- public void update(User user);
- }
在UserServiceImpl里引用UserDao来实现业务逻辑。
- package com.oa.service.impl;
- import com.oa.User;
- import com.oa.service.UserService;
- import com.oa.dao.UserDao;
- import java.util.List;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- /**
- * 声明此类为业务逻辑层的类
- * 默认bean名称生成器会返回小写开头的非限定(non-qualified)类名
- * @Service
- * userServiceImpl
- */
- @Service("userService")
- public class UserServiceImpl implements UserService {
- /**
- * @Autowired
- *
- * @Autowired 注解可以用于"传统的"setter 方法,如下例:
- * public void setUserDao(UserDAO userDao)
- {
- this.userDao = userDao;
- }
- */
- /**
- * @Resource有一个'name'属性,缺省时,Spring 将这个值解释为要注射的 bean 的名字。
- * @Resource(name="userDao")
- */
- @Autowired // or @Resource(name="userDao")
- private UserDao userDao;
- public void save(User user) {
- userDao.save(user);
- }
- public void update(User user) {
- userDao.update(user);
- }
- }
重复的工作使得我们觉得好烦。
这个时候是泛型出场的时候了。
基于Facade的设计模式,dao和service还是要的。 这里我们就要设计一个公共的Dao.. 我们称之为:GenericDao
- package com.oa.dao;
- import java.io.Serializable;
- import java.util.*;
- /**
- * *
- *
- * @param <T>
- * 泛型,指实体类 type
- * @param <PK>
- * 泛型,指实体类主键的数据类型,如Integer,Long
- */
- public interface GenericDao<T, PK> {
- /**
- * 保存指定实体类
- *
- * @param entityobj
- * 实体类
- */
- public void save(T entity);
- /**
- * 删除指定实体
- *
- * @param entityobj
- * 实体类
- */
- public void delete(T entity);
- /** *
- * 删除实体
- * @param entityClass 实体类名
- * @param id 实体的ID
- */
- public void deleteById(Class<T> entityClass,PK id);
- /**
- * 更新或保存指定实体
- *
- * @param entity 实体类
- */
- public void saveorupdate(T entity);
- /** *
- * 更新实体
- * 可用于添加、修改、删除操作
- * @param hql 更新的HQL语句
- * @param params 参数,可有项目或多项目,代替Hql中的"?"号
- */
- public void update(final String hql,final Object[] params);
- /**
- * 模糊查询指定条件对象集合 <br>
- * 用法:可以实例化一个空的T对象,需要查询某个字段,就set该字段的条件然后调用本方法<br>
- * 缺点:目前测试貌似只能支持String的模糊查询,虽然有办法重写,但没必要,其他用HQL<br>
- *
- * @param entity
- * 条件实体
- * @return 结合
- */
- public List<T> findByExample(T entity);
- /**
- * 获取所有实体集合
- *
- * @param entityClass
- * 实体
- * @return 集合
- */
- public List<T> findAll(Class<T> entityClass);
- public List<T> findAll(Class<T> entityClass,String hql,Object[] params,int start, int limit);
- /**
- * 查找指定PK实体类对象
- *
- * @param entityClass
- * 实体Class
- * @param id
- * 实体PK
- * @return 实体对象
- */
- public T findById(Class<T> entityClass, PK id);
- /** *
- * 按HQL条件查询列表
- * @param hql 查询语句,支持连接查询和多条件查询
- * @param params 参数数组,代替hql中的"?"号
- * @return 结果集List
- */
- public List<T> findByHql(String hql,Object[] params);
- /**
- * 查找指定属性的实体集合
- *
- * @param entityClass
- * 实体
- * @param propertyName
- * 属性名
- * @param value
- * 条件
- * @return 实体集合
- */
- public List<T> findByProperty(Class<T> entityClass, String propertyName,Object value);
- /**
- * 查询指定HQL语句的分页数据集合
- *
- * @param hsql
- * HQL语句
- * @param start
- * 开始记录号
- * @param limit
- * 最大记录号
- * @return 分页数据集合
- * @throws Exception
- * 抛出异常
- */
- public List<T> findByPage(Class<T> entityClass,int start,int limit) ;
- /**
- * 获得总记录数
- */
- public T getTotalCount(Class<T> entityClass);
- public T getPageCount(String hql,Object[] params);
- }
。。而是用 T 来取代实体。
因为我这个是基于 注解的,所以附上MyHibernateDaoSupport的代码。
- package com.oa.dao;
- import javax.annotation.Resource;
- import org.hibernate.SessionFactory;
- import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
- /**
- * 我们之所以要改写
- * HibernateDaoSupport,是因我为,我们要为DAO层的类注入SessionFactory这个属性。
- * 以后,我们开发的DAO类,就可以直接重用这个MyHibernateDaoSupport了。
- * 其实,这样做是相当于配置文件方式的代码:
- * <bean id="userDao" class="com.oa.dao.UserDaoImpl">
- * <property
- * name="sessionFactory" ref="sessionFactory"/>
- * </bean>
- *
- * @author Administrator
- *
- */
- public class MyHibernateDaoSupport extends HibernateDaoSupport {
- @Resource(name="sessionFactory") //为父类HibernateDaoSupport注入sessionFactory的值
- public void setSuperSessionFactory(SessionFactory sessionFactory){
- super.setSessionFactory(sessionFactory);
- }
- }
GenericDaoImpl 代码:
- package com.oa.dao.impl;
- import java.io.Serializable;
- import java.util.List;
- import org.hibernate.Query;
- import org.springframework.stereotype.Repository;
- import com.oa.dao.GenericDao;
- import com.oa.dao.MyHibernateDaoSupport;
- @SuppressWarnings("unchecked")
- @Repository("genericDao") //声明此类为数据持久层的类
- public class GenericDaoImpl<T, PK extends Serializable> extends
- MyHibernateDaoSupport implements GenericDao<T, PK> {
- public void delete(T entity) {
- super.getHibernateTemplate().delete(entity);
- }
- public void deleteById(Class entityClass, PK id) {
- super.getHibernateTemplate().delete(findById(entityClass, id));
- }
- public void save(T entity) {
- super.getHibernateTemplate().save(entity);
- }
- public void saveorupdate(T entity) {
- super.getHibernateTemplate().saveOrUpdate(entity);
- }
- public void update(String hql, Object[] params) {
- Query query = super.getSession().createQuery(hql);
- for(int i=0; i<params.length; i++){
- query.setParameter(i, params[i]);
- }
- query.executeUpdate();
- }
- public List<T> findAll(Class entityClass) {
- return super.getHibernateTemplate().loadAll(entityClass);
- }
- public List<T> findAll(Class entityClass, String hql, Object[] params,int start, int limit) {
- Query query = super.getSession().createQuery(hql);
- if(params!=null&¶ms.length>0){
- for(int i = 0;i<params.length;i++){
- query.setParameter(i, params[i]);
- }
- }
- if(start!=0&&limit!=0){
- query.setFirstResult(start).setMaxResults(limit);
- }
- return query.list();
- }
- public List<T> findByExample(T entity) {
- return super.getHibernateTemplate().findByExample(entity);
- }
- public List<T> findByHql(String hql, Object[] params) {
- Query query = super.getSession().createQuery(hql);
- if(null!= params && params.length>0){
- for(int i = 0; i<params.length;i++){
- query.setParameter(i, params[i]);
- }
- }
- return query.list();
- }
- public T findById(Class entityClass, PK id) {
- return (T)super.getHibernateTemplate().get(entityClass, id);
- }
- public List<T> findByProperty(Class entityClass, String propertyName,Object value) {
- String queryString = "from "+entityClass.getName()+ " as model where model." + propertyName + "=?";
- return super.getHibernateTemplate().find(queryString, value);
- }
- //分页使用
- public List<T> findByPage(Class<T> entityClass,int start,int limit) {
- Query query=super.getSession().createQuery("select o from "+entityClass.getName()+" o");
- query.setFirstResult(start).setMaxResults(limit);
- return query.list();
- }
- public T getTotalCount(Class entityClass) {
- return (T)super.getSession().createQuery("select count(o) from "+entityClass.getName()+" o").uniqueResult();
- }
- public T getPageCount(String hql, Object[] params) {
- Query query = super.getSession().createQuery(hql);
- if(null!= params && params.length>0){
- for(int i = 0; i<params.length;i++){
- query.setParameter(i, params[i]);
- }
- }
- return (T)query.list();
- }
- }
接下来日子就好过了。
我们不是有user news 等等一系列的curd管理。
以User为例子;
定义一个user的接口,
UserDao.Java
- package com.oa.dao;
- import com.oa.User;
- public interface UserDao extends GenericDao<User, Integer> {
- public int login(User user);
- //其他的方法的
- }
- 然后就是实现它 UserDaoImpl
- package com.oa.dao.impl;
- import com.oa.User;
- import com.oa.dao.UserDao;
- public class UserDaoImpl extends GenericDaoImpl<User, Integer> implements UserDao {
- public int login(User user){
- //登陆判断的方法
- return XX;
- };
- //其他的方法的实现
- }
下面进入业务逻辑层,依然是先定义一个接口。
- package com.oa.service;
- import com.oa.User;
- public interface UserService {
- public void save(User user);
- public void update(User user);
- public int login(User user);
- //其他的方法
- }
- package com.oa.service.impl;
- import com.oa.User;
- import com.oa.dao. UserDao;
- import com.oa.service.TestUserService;
- public class UserService implements UserService {
- private UserDao UserDao;
- public void save(User user) {
- UserDao.save(user);
- }
- public void updasaveorupdatete(User user) {
- UserDao.saveorupdate(user);
- }
- public int login(User user) {
- return UserDao.login(user);
- }
- //其他的方法。。。。
- }
两者相对比,发现dao层的代码可以复用,少了不少。
对于大型管理系统,效果更明显。
Junit Test方法我这里就不提供了。
参考: rongxh7
吼吼。谢谢!
欢迎大家提出意见,但是拒绝人身攻击。