面向应用的持久层

 

1.1

持久化:通过持久化过程,将内存中的数据保存到数据库(或)其他媒介)以备日后只用,是为持久化。

持久层:专注于数据持久化的一个相对独立的领域。

 

所谓持久层,我们不妨从回答下面几个问题来尝试理解:

1.如果表示层发生变化,需要从JSP迁移到Java WebStartClient,我们的数据持久层代码是否需要重新编译。

2.如果业务逻辑层发生变化,那么数据化持久话代码是否需要重新编译。

3.如果底层数据持久化机制发生了改变,比如更换数据库,那么,系统的非持久化部分代码,包括表示层,业务逻辑层是否重新编译。

 

1.2

耦合:事物之间的相互关系。

解耦合:采用一些手段降低关联的紧密程度。

解耦合设计:应用层解耦合应用逻辑和数据逻辑分离;资源层解耦合逻辑结构和物理结构的相分离。

解耦思想的自然演进和持久层的解耦合:以网上商店购物结算的处理过程为例

<此处读者以人类历史的发展过程来整理作者的演绎过程,并对其示例代码略作整合,并忽略了异常处理>

原始社会原始个体独立生产自己所需:

业务逻辑和数据访问代码混杂,一个过程负责完成所有工作。

public BigDecimal calcAmount(String customerID, BigDecimal amount) throws Exception {

      connection conn = null;

      Statement statement = null;

     

       class.forName("Oracle.jdbc.driver.OracleDriver");

       conn = DriverManager.getConnection(

                                                 "JDBC:oracle:thin:@dbserver:1521:forum",

                                                   "MyUserName", "MyPasswor");

       PreparedStatement stmt_customer = conn.prepareStatement("select level from customer where id = ?");

       stmt_customer.setString(1, customerID);

       ResultSet rset_customer = stmt_customer.executeQuery();

       if(rset_customer.next())

       {

             int customerLevel = rset_customer.getInt(1);

             PreparedStatement stmt_promotion = conn.prepareStatement(

                                              "select ration from promotion where cust_level = ?");

             stmt_promotion.setInt(1, customerLevel);

             ResultSet rset_promotion = stmt_promotion.executeQuery();

             Double ratio = 1;

             if(rset_promotion.next())

             { 

                 ratio = rset_promotion.getDouble(1);

              }

            

              amount = amount.multi(new BigDecimal(ratio));

              PreparedStatement stmt_updateCustomer = conn.prepareStatement(

                           "update custiomer set sum_amount = sum_amount + ? where id = ?");

              stmt_updateCustomer.setDouble(1, amount.doubleValue());

              stmt_updateCustomer.setString(2, customerID);

              stmt_updateCustomer.executeUpdate()

              stmt_updateCustomer.close();

 

              rset_promotion.close():

              stmt_promotion.close():

      }

 

       rset_customer.close();

       stmt_customer.cloase();

 

       return amount;

  }

       

奴隶社会个体专注自己的生产,并用产出与他人交换,简单的独立和合作:

将一些变化的,和影响性能的操作进行简单的封装,比如将用户信息通过配置文件实现,用一个对象负责数据库连接池的管理,以提高性能。

从配置文件读取数据库连接的配置片段:

……

Class.forname(config.getValue(“JDBC_DRIVER”);

Conn = DriverManager.getConnection(config.getValue(“DB_URL”), config.getValue(“DB_USER”), config.getValue(“DB_PASSWORD”));

……

 

连接池管理类:

 

Public class DBHelper{

  Public static Connection getConnection() {

  //从连接池获取数据库连接

  }

Public static releaseConnection(Connection conn) {

   //将使用完的连接返回到连接池

}

}

 

 

Public class MyDBPersistence {

   ……

   Connection conn = null;

try {

   conn = DBHelper.getConnection();

……

) finally  {

    DBHelper.releaseConnection(conn);

}

……

}

 

封建社会专业作坊的出现使得生产力大大提高:

引入DAOData Access Object)模式(DAO实际上是Data Accessor模式和Active Domain Object模式的组合),实现

业务逻辑层的分离

数据访问底层实现的分离

资源管理和调度的分离(数据访问层的分离,使得资源的管理和缓存机制可以更好的得以应用,从而提高性能)

数据抽象(对底层数据封装-对象Bean 使得业务逻辑可以访问更有意义的属性名称,而不是数据表的字段)。

 

业务逻辑层代码:

public BigDecimal calcAmount(String customerID, BigDecimal amount) {

 

          //根据客户ID获得客户记录

         Customer customer = CustomerDAO.getCustomer(customerID);

 

          //根据客户等级获得打折规则

          Promotion promotion = PromotionDAO.getPromotion(customer.getLevel());

 

          //累计客户总消费额,并保存结果

          customer.setSumAmount(customer.getSumAmount().add(amount));

          customerDAO.save(customer);

 

           return amount.getmultiply(promotion.getRation());

}

 

实体对象<Active Domain Object>

普通的实体bean(代码省略)。

 

数据访问层代码<Data Accessor>:

 

public class customerDAO {

 

public static Customer getCustomer(String ID) {

Connection conn;

ResultSet rset_customer = null;

PreparedStatement stmt_customer = null;

conn = DBHelper.getConnection();

 

……

……

……

Customer customer = new Customer():

Customer.setID(rset_customer.getInt(1);

……

 

 

DBHelper.releaseConnection(conn);

 

return customer

 

}

 

Public static void save(Customer customer) {

 

//同上

 

}

}

 

资本主义社会面对复杂的环境,更加规模化和专业化:

对于一个产品而言,面临着复杂多变的应用环境,如采用不同的数据库,我们引进Factory模式和Proxy模式来实现对不同数据库的访问机制,以更好的体现开闭原则对扩展开放,对变化封装。

 

public interface CustomerDAO {

       public Customer getCustomer(String custID);

public void save (Customer customer);

}

 

public class CustomerDAOImp_MySQL implements CustomerDAO {

 

}

 

public class CustomerDAOImp_Oracle implement CustomerDAO {

}

 

public class DAOFactory {

 

       private static HashMap daomap = null;

       

       public static Object getDAO(Class daoInterface) ;

              Initial();

              Object dao = daoMap.get(interface);

 

              if( null == dao)

              {

                      //报错

               }

               return dao;

         }

        

          public static synchronized void initial() {

                   if(null == daomap) {

                          daoMap = DAOConfig.load(); //根据配置文件加载DAO实现

           }

}

 

 

public BigDecimal calcAmount(String customerID, BigDecimal amount) {

           CustomerDAO customerDAO = (Customer)DAOFactory.getDAO(CustomerDAO.calss);

          

          //根据客户ID获得客户记录

         Customer customer = CustomerDAO.getCustomer(customerID);

 

          //根据客户等级获得打折规则

          Promotion promotion = PromotionDAO.getPromotion(customer.getLevel());

 

          //累计客户总消费额,并保存结果

          customer.setSumAmount(customer.getSumAmount().add(amount));

          customerDAO.save(customer);

 

           return amount.getmultiply(promotion.getRation());

}

 

 

calcAmount中似乎又夹杂了一点数据库操作的代码,当然事情不可能十全十美,总归是要有所取舍。不过我们继续用proxy模式对其进行重构优化。

 

public class CustomerProxy {

        public static Customer getCustomer(String customerID) {

              CustomerDAO custDAO = (CustomerDAO)DAOFactory.getDAO(CustomerDAO.class);

              return custDAO.getCustomer(customerID);

        }

 

 

        public static void save(Customer customer) {

               ……

        }

}

 

PromotionProxy类此。

 

再看看我们calcAmount:

 

public BigDecimal calcAmount(String customerID, BigDecimal amount) {

                     

          //根据客户ID获得客户记录

         Customer customer = CustomerProxy.getCustomer(customerID);

 

          //根据客户等级获得打折规则

          Promotion promotion = PromotionProxy.getPromotion(customer.getLevel());

 

          //累计客户总消费额,并保存结果

          customer.setSumAmount(customer.getSumAmount().add(amount));

          customerDAO.save(customer);

 

           return amount.getmultiply(promotion.getRation());

}

 

 

 

一个简单的例子,让我们了解到了数据持久层的概念和重要性,同时也体会到了一些重要的思想和技术方法的应用--分层设计,解耦合,开闭原则,设计模式。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值