基于泛型DAO的Facade设计模式.

在做管理系统时。通常基于Facade模式的系统持久化层要写许多Dao。这些dao里面的方法又是重复的,那么有没有什么好的方法来统一利用一个公共的Dao。

答案是可以的。这里我们接触到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;
}

}


如果按照常规的Facade模式来设计,我们的思路是:
先创建一个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);

}



然后实现这个接口:UserDaoImpl

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);

}

}



[size=small][color=red]持久化层完毕。


接下来的是事务层[/color][/size]


先创建一个UserService的接口。



package com.oa.service;

import com.oa.User;

public interface UserService {

public void save(User user);

public void update(User user);

}


然后实现这个接口:UserServiceImpl。
在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);

}



看到,我们不再是具体的User , News
。。而是用 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);
}


}



到现在位置genericdao的接口有了,也就是我们要做什么。。现在就是实现它,就是怎么做。
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&&params.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);

}

//其他的方法。。。。

}



Ok。。到现在我们就利用泛型dao来设计就完毕了

两者相对比,发现dao层的代码可以复用,少了不少。

对于大型管理系统,效果更明显。


Junit Test方法我这里就不提供了。

参考:[url=http://www.blogjava.net/rongxh7/]rongxh7[/url]
吼吼。谢谢!

欢迎大家提出意见,但是拒绝人身攻击。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值