struts2+hibernate+spring配置管理(三)——DAO层(二)

接上篇所说,如果懂得这个思想,其实很简单了,况且有spring的HibernateDaoSupport坐阵,你的代码会更精简,会更优化。话不多说,贴上代码先看一下吧:

java 代码
  1. /**  
  2.  * 负责为单个Entity对象提供CRUD操作的Hibernate DAO基类. 

     子类只要在类定义时指定所管理Entity的Class,

     
  3.  * 即拥有对单个Entity对象的CRUD操作.  
  4.  *   
  5.  *   
  6.  */  
  7. @SuppressWarnings("unchecked")   
  8. abstract public class HibernateBaseDao  extends HibernateDaoSupport {   
  9.   
  10.     protected Class  entityClass;// DAO所管理的Entity类型.   
  11.   
  12.     /**  
  13.      * 在构造函数中将泛型T.class赋给entityClass.  
  14.      */  
  15.     public HibernateBaseDao() {   
  16.         entityClass = GenericsUtils.getSuperClassGenricType(getClass());   
  17.     }   
  18.   
  19.     /**  
  20.      * 取得entityClass.JDK1.4不支持泛型的子类可以抛开Class  entityClass,重载此函数达到相同效果。  
  21.      */  
  22.     protected Class  getEntityClass() {   
  23.         return entityClass;   
  24.     }   
  25.   
  26.     /**  
  27.      * 根据ID获取对象.  
  28.      *   
  29.      * @see HibernateGenericDao#getId(Class,Object)  
  30.      */  
  31.     public T load(Serializable id) {   
  32.         return (T) getHibernateTemplate().load(getEntityClass(), id);   
  33.     }   
  34.   
  35.     /**  
  36.      * 根据ID获取对象,使用hinbernate get().  
  37.      *   
  38.      * @see HibernateGenericDao#getId(Class,Object)  
  39.      */  
  40.     public T get(Serializable id) {   
  41.         return (T) getHibernateTemplate().get(getEntityClass(), id);   
  42.     }   
  43.   
  44.     /**  
  45.      * 获取全部对象  
  46.      *   
  47.      * @see HibernateGenericDao#getAll(Class)  
  48.      */  
  49.     public List  getAll() {   
  50.         return getHibernateTemplate().loadAll(getEntityClass());   
  51.     }   
  52.   
  53.     /**  
  54.      * 获取全部对象,带排序参数.  
  55.      *   
  56.      */  
  57.     public List  getAll(String orderBy, boolean isAsc) {   
  58.         Assert.hasText(orderBy);   
  59.         if (isAsc)   
  60.             return getHibernateTemplate().findByCriteria(   
  61.                     DetachedCriteria.forClass(getEntityClass()).addOrder(   
  62.                             Order.asc(orderBy)));   
  63.         else  
  64.             return getHibernateTemplate().findByCriteria(   
  65.                     DetachedCriteria.forClass(getEntityClass()).addOrder(   
  66.                             Order.desc(orderBy)));   
  67.     }   
  68.   
  69.     /**  
  70.      * 保存对象.  
  71.      */  
  72.     public Serializable save(Object o) {   
  73.         return getHibernateTemplate().save(o);   
  74.     }   
  75.   
  76.     /**  
  77.      * 更新对象  
  78.      *   
  79.      * @param o  
  80.      */  
  81.     public void update(Object o) {   
  82.         getHibernateTemplate().update(o);   
  83.     }   
  84.   
  85.     /**  
  86.      * 保存或更新对象  
  87.      *   
  88.      * @param o  
  89.      */  
  90.     public void saveOrUpdate(Object o) {   
  91.         getHibernateTemplate().saveOrUpdate(o);   
  92.     }   
  93.   
  94.     /**  
  95.      * 删除对象.  
  96.      */  
  97.     public void remove(Object o) {   
  98.         getHibernateTemplate().delete(o);   
  99.     }   
  100.   
  101.     /**  
  102.      * 根据ID移除对象.  
  103.      *   
  104.      * @see HibernateGenericDao#removeById(Class,Serializable)  
  105.      */  
  106.     public void removeById(Serializable id) {   
  107.         remove(load(id));   
  108.     }   
  109.   
  110.     public void flush() {   
  111.         getHibernateTemplate().flush();   
  112.     }   
  113.   
  114.     public void clear() {   
  115.         getHibernateTemplate().clear();   
  116.     }   
  117.   
  118.     /**  
  119.      * 创建Query对象.  
  120.      * 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.  
  121.      * 留意可以连续设置,如下:  
  122.      *   
  123.      * @param values  
  124.      *            可变参数.  
  125.      */  
  126.     public Query createQuery(String hql, Object... values) {   
  127.         Assert.hasText(hql);   
  128.         Query query = getSession().createQuery(hql);   
  129.         for (int i = 0; i < values.length; i++) {   
  130.             query.setParameter(i, values[i]);   
  131.         }   
  132.         return query;   
  133.     }   
  134.   
  135.     /**  
  136.      * 取得Entity的Criteria.  
  137.      *   
  138.      */  
  139.     public Criteria createCriteria() {   
  140.         return getSession().createCriteria(getEntityClass());   
  141.     }   
  142.   
  143.     /**  
  144.      * 取得Entity的Criteria.  
  145.      *   
  146.      */  
  147.     public Criteria createCriteria(Criterion... criterions) {   
  148.         Criteria criteria = createCriteria();   
  149.         for (Criterion c : criterions) {   
  150.             criteria.add(c);   
  151.         }   
  152.         return criteria;   
  153.     }   
  154.   
  155.     /**  
  156.      * 取得Entity的Criteria,带排序参数.  
  157.      *   
  158.      */  
  159.     public Criteria createCriteria(String orderBy, boolean isAsc,   
  160.             Criterion... criterions) {   
  161.         Assert.hasText(orderBy);   
  162.   
  163.         Criteria criteria = createCriteria(criterions);   
  164.   
  165.         if (isAsc)   
  166.             criteria.addOrder(Order.asc(orderBy));   
  167.         else  
  168.             criteria.addOrder(Order.desc(orderBy));   
  169.   
  170.         return criteria;   
  171.     }   
  172.   
  173.     /**  
  174.      * 根据hql查询,直接使用HibernateTemplate的find函数.  
  175.      *   
  176.      * @param values  
  177.      *            可变参数,见{@link #createQuery(String,Object...)}  
  178.      */  
  179.     public List find(String hql, Object... values) {   
  180.         Assert.hasText(hql);   
  181.         return getHibernateTemplate().find(hql, values);   
  182.     }   
  183.   
  184.     /**  
  185.      * 根据属性名和属性值查询对象.  
  186.      *   
  187.      * @return 符合条件的对象列表  
  188.      */  
  189.     public List  findBy(String propertyName, Object value) {   
  190.         Assert.hasText(propertyName);   
  191.         return createCriteria(Restrictions.eq(propertyName, value)).list();   
  192.     }   
  193.   
  194.     /**  
  195.      * 根据属性名和属性值查询对象,带排序参数.  
  196.      */  
  197.     public List  findBy(Class  entityClass, String propertyName,   
  198.             Object value, String orderBy, boolean isAsc) {   
  199.         Assert.hasText(propertyName);   
  200.         Assert.hasText(orderBy);   
  201.         return createCriteria(orderBy, isAsc,   
  202.                 Restrictions.eq(propertyName, value)).list();   
  203.     }   
  204.   
  205.     /**  
  206.      * 根据属性名和属性值查询对象,带排序参数.  
  207.      *   
  208.      * @return 符合条件的对象列表  
  209.      */  
  210.     public List  findBy(String propertyName, Object value, String orderBy,   
  211.             boolean isAsc) {   
  212.         return findBy(getEntityClass(), propertyName, value, orderBy, isAsc);   
  213.     }   
  214.   
  215.     /**  
  216.      * 根据属性名和属性值查询单个对象.  
  217.      *   
  218.      * @return 符合条件的唯一对象 or null  
  219.      */  
  220.     public T findUniqueBy(String propertyName, Object value) {   
  221.         Assert.hasText(propertyName);   
  222.         return (T) createCriteria(Restrictions.eq(propertyName, value))   
  223.                 .uniqueResult();   
  224.     }   
  225.   
  226.     /**  
  227.      * 分页查询函数,使用hql.  
  228.      *   
  229.      * @param pageNo  
  230.      *            页号,从1开始.  
  231.      */  
  232.     public Page  pagedQuery(String hql, int pageNo, int pageSize,   
  233.             Object... values) {   
  234.         Assert.hasText(hql);   
  235.         Assert.isTrue(pageNo >= 1"pageNo should start from 1");   
  236.         // Count查询   
  237.         String countQueryString = " select count (*) "  
  238.                 + removeSelect(removeOrders(hql));   
  239.         List countlist = getHibernateTemplate().find(countQueryString, values);   
  240.         long totalCount = (Long) countlist.get(0);   
  241.   
  242.         if (totalCount < 1)   
  243.             return new Page();   
  244.         // 实际查询返回分页对象   
  245.         int startIndex = Page.getStartOfPage(pageNo, pageSize);   
  246.         Query query = createQuery(hql, values);   
  247.         List  list = query.setFirstResult(startIndex).setMaxResults(pageSize)   
  248.                 .list();   
  249.   
  250.         return new Page (startIndex, totalCount, pageSize, list);   
  251.     }   
  252.   
  253.     /**  
  254.      * 分页查询函数,使用已设好查询条件与排序的Criteria.  
  255.      *   
  256.      * @param pageNo  
  257.      *            页号,从1开始.  
  258.      * @return 含总记录数和当前页数据的Page对象.  
  259.      */  
  260.     public Page  pagedQuery(Criteria criteria, int pageNo, int pageSize) {   
  261.         Assert.notNull(criteria);   
  262.         Assert.isTrue(pageNo >= 1"pageNo should start from 1");   
  263.         CriteriaImpl impl = (CriteriaImpl) criteria;   
  264.   
  265.         // 先把Projection和OrderBy条件取出来,清空两者来执行Count操作   
  266.         Projection projection = impl.getProjection();   
  267.         List  orderEntries;   
  268.         try {   
  269.             orderEntries = (List) BeanUtils.forceGetProperty(impl,   
  270.                     "orderEntries");   
  271.             BeanUtils.forceSetProperty(impl, "orderEntries"new ArrayList());   
  272.         } catch (Exception e) {   
  273.             throw new InternalError(" Runtime Exception impossibility throw ");   
  274.         }   
  275.   
  276.         // 执行查询   
  277.         int totalCount = (Integer) criteria.setProjection(   
  278.                 Projections.rowCount()).uniqueResult();   
  279.   
  280.         // 将之前的Projection和OrderBy条件重新设回去   
  281.         criteria.setProjection(projection);   
  282.         if (projection == null) {   
  283.             criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);   
  284.         }   
  285.   
  286.         try {   
  287.             BeanUtils.forceSetProperty(impl, "orderEntries", orderEntries);   
  288.         } catch (Exception e) {   
  289.             throw new InternalError(" Runtime Exception impossibility throw ");   
  290.         }   
  291.   
  292.         // 返回分页对象   
  293.         if (totalCount < 1)   
  294.             return new Page();   
  295.   
  296.         int startIndex = Page.getStartOfPage(pageNo, pageSize);   
  297.         List  list = criteria.setFirstResult(startIndex).setMaxResults(   
  298.                 pageSize).list();   
  299.         return new Page (startIndex, totalCount, pageSize, list);   
  300.     }   
  301.   
  302.     /**  
  303.      * 分页查询函数,根据entityClass和查询条件参数创建默认的Criteria.  
  304.      *   
  305.      * @param pageNo  
  306.      *            页号,从1开始.  
  307.      * @return 含总记录数和当前页数据的Page对象.  
  308.      */  
  309.     public Page  pagedQuery(int pageNo, int pageSize, Criterion... criterions) {   
  310.         Criteria criteria = createCriteria(criterions);   
  311.         return pagedQuery(criteria, pageNo, pageSize);   
  312.     }   
  313.   
  314.     /**  
  315.      * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的Criteria.  
  316.      *   
  317.      * @param pageNo  
  318.      *            页号,从1开始.  
  319.      * @return 含总记录数和当前页数据的Page对象.  
  320.      */  
  321.     public Page  pagedQuery(int pageNo, int pageSize, String orderBy,   
  322.             boolean isAsc, Criterion... criterions) {   
  323.         Criteria criteria = createCriteria(orderBy, isAsc, criterions);   
  324.         return pagedQuery(criteria, pageNo, pageSize);   
  325.     }   
  326.   
  327.     /**  
  328.      * 判断对象某些属性的值在数据库中是否唯一.  
  329.      *   
  330.      * @param uniquePropertyNames  
  331.      *            在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"  
  332.      */  
  333.     public boolean isUnique(Object entity, String uniquePropertyNames) {   
  334.         Assert.hasText(uniquePropertyNames);   
  335.         Criteria criteria = createCriteria().setProjection(   
  336.                 Projections.rowCount());   
  337.         String[] nameList = uniquePropertyNames.split(",");   
  338.         try {   
  339.             // 循环加入唯一列   
  340.             for (String name : nameList) {   
  341.                 criteria.add(Restrictions.eq(name, PropertyUtils.getProperty(   
  342.                         entity, name)));   
  343.             }   
  344.   
  345.             // 以下代码为了如果是update的情况,排除entity自身.   
  346.   
  347.             String idName = getIdName(getEntityClass());   
  348.   
  349.             // 取得entity的主键值   
  350.             Serializable id = getId(entity);   
  351.   
  352.             // 如果id!=null,说明对象已存在,该操作为update,加入排除自身的判断   
  353.             if (id != null)   
  354.                 criteria.add(Restrictions.not(Restrictions.eq(idName, id)));   
  355.         } catch (Exception e) {   
  356.             ReflectionUtils.handleReflectionException(e);   
  357.         }   
  358.         return (Integer) criteria.uniqueResult() == 0;   
  359.     }   
  360.   
  361.     /**  
  362.      * 取得对象的主键值,辅助函数.  
  363.      */  
  364.     public Serializable getId(Object entity) throws NoSuchMethodException,   
  365.             IllegalAccessException, InvocationTargetException {   
  366.         Assert.notNull(entity);   
  367.         Assert.notNull(getEntityClass());   
  368.         return (Serializable) PropertyUtils.getProperty(entity,   
  369.                 getIdName(getEntityClass()));   
  370.     }   
  371.   
  372.     /**  
  373.      * 取得对象的主键名,辅助函数.  
  374.      */  
  375.     public String getIdName(Class clazz) {   
  376.         Assert.notNull(clazz);   
  377.         ClassMetadata meta = getSessionFactory().getClassMetadata(clazz);   
  378.         Assert.notNull(meta, "Class " + clazz   
  379.                 + " not define in hibernate session factory.");   
  380.         String idName = meta.getIdentifierPropertyName();   
  381.         Assert.hasText(idName, clazz.getSimpleName()   
  382.                 + " has no identifier property define.");   
  383.         return idName;   
  384.     }   
  385.   
  386.     /**  
  387.      * 去除hql的select 子句,未考虑union的情况,用于pagedQuery.  
  388.      *   
  389.      * @see #pagedQuery(String,int,int,Object[])  
  390.      */  
  391.     private static String removeSelect(String hql) {   
  392.         Assert.hasText(hql);   
  393.         int beginPos = hql.toLowerCase().indexOf("from");   
  394.         Assert.isTrue(beginPos != -1" hql : " + hql   
  395.                 + " must has a keyword 'from'");   
  396.         return hql.substring(beginPos);   
  397.     }   
  398.   
  399.     /**  
  400.      * 去除hql的orderby 子句,用于pagedQuery.  
  401.      *   
  402.      * @see #pagedQuery(String,int,int,Object[])  
  403.      */  
  404.     private static String removeOrders(String hql) {   
  405.         Assert.hasText(hql);   
  406.         Pattern p = Pattern.compile("order//s*by[//w|//W|//s|//S]*",   
  407.                 Pattern.CASE_INSENSITIVE);   
  408.         Matcher m = p.matcher(hql);   
  409.         StringBuffer sb = new StringBuffer();   
  410.         while (m.find()) {   
  411.             m.appendReplacement(sb, "");   
  412.         }   
  413.         m.appendTail(sb);   
  414.         return sb.toString();   
  415.     }   
  416.   
  417.     /**  
  418.      * 根据页码和每页的长度返回对象集合  
  419.      *   
  420.      * @param pageNo  
  421.      *            页码  
  422.      * @param pageSize  
  423.      *            每页的长度  
  424.      * @return  
  425.      */  
  426.     public List  getObjects(int pageNo, int pageSize) {   
  427.         Criteria criteria = this.createCriteria();   
  428.         return this.pagedQuery(criteria, pageNo, pageSize).getResult();   
  429.     }   
  430. }   

有了这个DAO后,你再让其它的实体DAO继承这个BASEDAO,比如:

java 代码
  1. public class ProductDAO extends HibernateBaseDao {   
  2.     //public void otherMethod(){...}   
  3. }  

就大功告成,所谓的OO,就让泛型帮你完成,烦人的对象转换就此终结。

有兴趣的朋友可以参考springside的源码,它更详细。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值