在做管理系统时。通常基于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);
}
}
持久化层完毕。
接下来的是事务层
先创建一个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&¶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);
}
//其他的方法。。。。
}
Ok。。到现在我们就利用泛型dao来设计就完毕了
两者相对比,发现dao层的代码可以复用,少了不少。
对于大型管理系统,效果更明显。
Junit Test方法我这里就不提供了。
参考:
rongxh7
吼吼。谢谢!
欢迎大家提出意见,但是拒绝人身攻击。
分享到:
相关推荐
而泛型DAO(Data Access Object)则是基于Hibernate进一步抽象出来的一个设计模式,用于提供更通用的数据操作方法。本文档主要探讨了如何在Spring+Hibernate环境中创建和使用泛型DAO。 首先,我们来看一下泛型DAO...
Struts2、Hibernate、Spring整合的泛型DAO (本人评价: 代码开发效率提高30% 代码出错率减少70%) 对于大多数开发人员,系统中的每个 DAO 编写几乎相同的代码到目前为止已经成为一种习惯。虽然所有人都将这种重复...
1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1....
* DAO设计模式:泛型可以用于DAO设计模式中,例如BaseHibernateEntityDao等。 * 工具类:泛型可以用于工具类中,例如工具类的静态方法可以使用泛型。 五、结论 泛型是Java编程语言中的一种重要特性,它可以提高...
2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip...
C# 工具类 泛型转JSON 使用 Newtonsoft.Json 转换JSON
3.java实例化泛型类.zip3.java实例化泛型类.zip3.java实例化泛型类.zip3.java实例化泛型类.zip3.java实例化泛型类.zip3.java实例化泛型类.zip3.java实例化泛型类.zip3.java实例化泛型类.zip3.java实例化泛型类.zip3....
Struts2、Hibernate、Spring整合的泛型DAO (本人评价: 代码开发效率提高30% 代码出错率减少70%) 对于大多数开发人员,系统中的每个 DAO 编写几乎相同的代码到目前为止已经成为一种习惯。虽然所有人都将这种重复...
文章详细阐述了泛型DAO模式的设计方法,包括在实现方法中直接定义泛型,或者在类和接口上定义泛型。泛型DAO模式通过抽象化设计,增强了程序的复用性和简化了编程语言,同时在程序运行结束后进行类型检查,避免了运行...
C++设计新思维:泛型编程与设计模式之应用.pdf 带目录书签
4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip...
在Java Web开发中,数据访问对象(DAO)模式是一种常用的设计模式,用于隔离应用程序与数据库之间的交互。DAO类处理所有数据库操作,使得业务逻辑层可以专注于处理核心业务,而不必关心底层的数据存取细节。而泛型...
在现代软件开发中,特别是基于Java的企业级应用开发中,DAO(Data Access Object)层的设计扮演着至关重要的角色。它作为业务逻辑层与数据持久层之间的桥梁,承担着数据存取的核心职责。本文将深入探讨一种在SSH...
基于泛型的通用Dao接口和Hibernate的实现 基于泛型的通用Dao接口是指使用泛型来实现数据访问对象(DAO)的接口,主要是在使用 Hibernate 或 JPA 时使用。泛型可以使得DAO接口更灵活、更通用。 泛型Dao接口的优点:...
标题中的“基于Hibernate+Spring 泛型GenericDao”的工程源码指的是一个整合了Spring框架和Hibernate ORM技术的项目,其中使用了泛型设计模式来实现数据访问对象(DAO)。这个项目可能旨在提供一种通用、可复用且...
本篇文章将深入探讨一个使用Spring注解和Hibernate实现的泛型DAO设计,以提高代码的复用性和可维护性。 首先,`HibernateBaseDao.java`是基础的Hibernate DAO类,它提供了对Hibernate操作的基本封装。这个类通常会...
Delphi泛型动态数组的扩展.2.mht
Delphi泛型动态数组的扩展.1.mht
【泛型DAO】是一种在Java开发中常见的设计模式,它利用了Java泛型特性来提高代码的可重用性和类型安全性。在Java中,DAO(Data Access Object)模式是用来封装对数据库的操作,将业务逻辑与数据访问逻辑分离,使得...