博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
通用Hibernate-Dao
阅读量:5167 次
发布时间:2019-06-13

本文共 11528 字,大约阅读时间需要 38 分钟。

在做管理系统时。通常基于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
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
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 
* 泛型,指实体类 type * @param
* 泛型,指实体类主键的数据类型,如Integer,Long */ public interface GenericDao
{ /** * 保存指定实体类 * * @param entityobj * 实体类 */ public void save(T entity); /** * 删除指定实体 * * @param entityobj * 实体类 */ public void delete(T entity); /** * * 删除实体 * @param entityClass 实体类名 * @param id 实体的ID */ public void deleteById(Class
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); /** * 模糊查询指定条件对象集合
* 用法:可以实例化一个空的T对象,需要查询某个字段,就set该字段的条件然后调用本方法
* 缺点:目前测试貌似只能支持String的模糊查询,虽然有办法重写,但没必要,其他用HQL
* * @param entity * 条件实体 * @return 结合 */ public List
findByExample(T entity); /** * 获取所有实体集合 * * @param entityClass * 实体 * @return 集合 */ public List
findAll(Class
entityClass); public List
findAll(Class
entityClass,String hql,Object[] params,int start, int limit); /** * 查找指定PK实体类对象 * * @param entityClass * 实体Class * @param id * 实体PK * @return 实体对象 */ public T findById(Class
entityClass, PK id); /** * * 按HQL条件查询列表 * @param hql 查询语句,支持连接查询和多条件查询 * @param params 参数数组,代替hql中的"?"号 * @return 结果集List */ public List
findByHql(String hql,Object[] params); /** * 查找指定属性的实体集合 * * @param entityClass * 实体 * @param propertyName * 属性名 * @param value * 条件 * @return 实体集合 */ public List
findByProperty(Class
entityClass, String propertyName,Object value); /** * 查询指定HQL语句的分页数据集合 * * @param hsql * HQL语句 * @param start * 开始记录号 * @param limit * 最大记录号 * @return 分页数据集合 * @throws Exception * 抛出异常 */ public List
findByPage(Class
entityClass,int start,int limit) ; /** * 获得总记录数 */ public T getTotalCount(Class
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了。  * 其实,这样做是相当于配置文件方式的代码:  * 
*
*
* * @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
extends MyHibernateDaoSupport implements GenericDao
{ 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
findAll(Class entityClass) { return super.getHibernateTemplate().loadAll(entityClass); } public List
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
findByExample(T entity) { return super.getHibernateTemplate().findByExample(entity); } public List
findByHql(String hql, Object[] params) { Query query = super.getSession().createQuery(hql); if(null!= params && params.length>0){ for(int i = 0; i
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
findByPage(Class
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

至此 泛型就告一个段落。 
接下来日子就好过了。 
我们不是有user  news   等等一系列的curd管理。 
以User为例子; 
定义一个user的接口, 
UserDao.Java 

package com.oa.dao;    import com.oa.User;    public interface UserDao extends GenericDao
{ 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
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层的代码可以复用,少了不少。 
对于大型管理系统,效果更明显。 

转载于:https://www.cnblogs.com/dandan1224/p/6109271.html

你可能感兴趣的文章
C#里如何遍历枚举所有的项
查看>>
如何在键盘出现时滚动表格,以适应输入框的显示
查看>>
超级强大的鼠标手势工具
查看>>
常用Dockerfile举例
查看>>
jquery的ajax用法
查看>>
设计模式-策略模式(Strategy)
查看>>
django orm 数据查询详解
查看>>
JarvisOJ Basic 熟悉的声音
查看>>
C# list导出Excel(二)
查看>>
CAS 单点登录模块学习
查看>>
跟着辛星用PHP的反射机制来实现插件
查看>>
Android应用开发-网络编程①
查看>>
input中的name,value以及label中的for
查看>>
静态库制作-混编(工程是oc为基础)
查看>>
jQuery 显示加载更多
查看>>
代理模式
查看>>
Confluence 6 系统运行信息中的 JVM 内存使用情况
查看>>
Confluence 6 升级以后
查看>>
用JS实现版面拖拽效果
查看>>
二丶CSS
查看>>