• 记录我开发鞋服行业供应链软件的历程<设计数据库层>


       

        上一章讲过数据库层(Dao层)具有如下的特点:

         1):整个系统只有一个DAO

         2):支持多种类型的事务控制(单表,多表,混合)

         3):查询支持Hibernate和原生SQL

        为什么我们会这么设计呢?这里引用一下sprigside2.0的实现:

       1:定义一个Dao接口 

      

     /**
       * 针对单个Entity对象的操作定义.不依赖于具体ORM实现方案.
       *
       * @author calvin
       */
       public interface EntityDao<T> {
    
       T get(Serializable id);
    
       List<T> getAll();
    
       void save(Object o);
    
       void remove(Object o);
    
       void removeById(Serializable id);
    
      /**
       * 获取Entity对象的主键名.
       */
       String getIdName(Class clazz);
      }   
    
    

       2: 定义一个基本的实现类
        

      /**
       * Hibernate Dao的泛型基类.
       * <p/>
       * 继承于Spring的<code>HibernateDaoSupport</code>,提供分页函数和若干便捷查询方法,并对返回值作了泛型类型转换.
       *
       * @author calvin
       * @author tin
       * @see HibernateDaoSupport
       * @see HibernateEntityDao
       */
       @SuppressWarnings("unchecked")
       public class HibernateGenericDao extends HibernateDaoSupport {
        ......
       }
    

        3:业务层中的每个对象都继承HibernateGenericDao 

      @SuppressWarnings("unchecked")
       public class OrderManager extends HibernateEntityDao<Order> {
         ......
       }  
    

         4:事务控制要配置到每个Manager 

    <!-- 支持 @Transactional 标记 -->
     <tx:annotation-driven/>
    
     <!-- 支持 @AspectJ 标记-->
     <aop:aspectj-autoproxy/>
    
     <!-- 以AspectJ方式 定义 AOP -->
     <aop:config proxy-target-class="true">
      <aop:advisor pointcut="execution(* org.springside.bookstore..*Manager.*(..))"
          advice-ref="txAdvice"/>
      <aop:advisor pointcut="execution(* org.springside.core.dao.*Dao.*(..))" advice-ref="txAdvice"/>
     </aop:config>
    
     <!-- 基本事务定义,使用transactionManager作事务管理,默认get*方法的事务为readonly,其余方法按默认设置.
        默认的设置请参考Spring文档事务一章. -->
     <tx:advice id="txAdvice">
      <tx:attributes>
       <tx:method name="get*" read-only="true"/>
       <tx:method name="find*" read-only="true"/>
       <tx:method name="*"/>
      </tx:attributes>
     </tx:advice> 
    

        

      这个可能是大众化的做法,但是我个人认为它只适用于一些简单的业务场合,如果做ERP,或者是我们现在做的鞋服行业,是很难满足业务需求的,打个比方,我们对单据中明细的一条操作,可能要引发5个到10个其它的操作,而这些操作,有的要执行批量脚本,有的只要执行一个存储过程,有的是删除一些数据,反正不确定的。下面简单讲讲我们的做法。 

     

         1:首先定义一个原子操作的接口,其中的pojo代表的不仅仅是po,也可能是一个存储过程名称,或者是一个脚本。。 

              

         public interface IOperator {
    	/**
    	 *处理
    	 * @param session
    	 * @throws HibernateException
    	 */
    	public void execute(Session session)  throws HibernateException;
        
    	/**
    	 * 获取一个原子操作对象
    	 * @return
    	 */
    	public Object getPojo();
         }
    

         2:定义一个抽象函数,实现IOperator 

           

         public abstract class AbstractOperator implements IOperator {
             Object pojo=null;// 处理对象      ……
          }   
    

        3:实现最基本的原子操作,比如增加保存一个hibernate对象,修改保存一个hibernate对象,删除pojo,执行一条脚本,以增加保存为例:    

       

     public class Add extends AbstractOperator {
    
     public Add(Object obj) {
      super(obj);
     }
    
     /**
      * 处理增加的pojo
      */
       public void execute(Session session) throws HibernateException {
         if (pojo != null) {
            session.save(pojo);
         }
    
       }
     } 
    

     4:定义一个原子操作集合类,继承AbstractOperator   

      public class Operators extends AbstractOperator {
     // 操作列表
     List<IOperator> objectList = new ArrayList<IOperator>();  
    
          ……  
    
       }  
    
    

     5:Dao定义一个集口,对原子操作集合类进行操作   

      

    public interface IDao {
    
     /**
      * 执行一组操作,这组操作包括增加,修改,删除,执行sql脚本,执行存储过程,清除cache等, 执行的先后顺序是在列表中增加的先后顺序
      */
     public abstract void execute(final IOperator os) throws DataAccessException;
     /**
      * 增加保存一个对象
      */
     public abstract Object addSave(final Object o) throws DataAccessException;
           /**
            * 修改保存一个对象
             * @param o
            * @throws DataAccessException
            */
     public abstract void updateSave(final Object o) throws DataAccessException;
     
           /**
     * 删除一个对象
     * @param o
     * @throws DataAccessException
     */
     public abstract void delete(final Object o) throws DataAccessException;
    .......
       } 
    

      6:Dao实现也是继承的spring 中的HibernateDaoSupport   

      7:事务控制参考springside的配置,只需要控制到Dao实现类就可以。   

       讲到这里,数据库层基本告一段落了,我个人体会是,数据库层讲难也难,讲易也易,但一定要根据业务需求来确定,适合业务才是最好的。           

  • 相关阅读:
    html5 本地存储
    javascript 中的 this 关键字详解
    重绘和回流
    javascript 的预解释机制
    zepto.js 实现原理解析
    python3.6新特性
    python面试终极准备
    科大讯飞语音合成api
    智能儿童玩具
    MySQL与MongoDB
  • 原文地址:https://www.cnblogs.com/mzhanker/p/2080129.html
Copyright © 2020-2023  润新知