Spring的DAO入门

 

 传统的DAO模式

<!--[if !vml]--><!--[endif]-->
Figure 1. Application structure, before and after DAO

设计一个接口

IEmployeeDAO.java

import java.util.Map;

public interface IEmployeeDAO {
  //SQL String that will be executed
  public String FIND_BY_SAL_RNG = "SELECT EMP_NO, EMP_NAME, "
  + "SALARY FROM EMP WHERE SALARY >= ? AND SALARY <= ?";

  //Returns the list of employees who fall into the given salary
  //range. The input parameter is the immutable map object
  //obtained from the HttpServletRequest. This is an early
  //refactoring based on "Introduce Parameter Object"

  public List findBySalaryRange(Map salaryMap);
}

实现这个接口

IEmployeeDAO.java

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import com.bea.dev2dev.to.EmployeeTO;

public class EmployeeDAOImpl implements IEmployeeDAO{

  public List findBySalaryRange(Map salaryMap)
  {
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    List empList = new ArrayList();
    //Transfer Object for inter-tier data transfer
    EmployeeTO tempEmpTO = null;
    try{
    //DBUtil - helper classes that retrieve connection from pool
      conn = DBUtil.getConnection();
      pstmt = conn.prepareStatement(FIND_BY_SAL_RNG);
      pstmt.setDouble(1, Double.valueOf( (String)
          salaryMap.get("MIN_SALARY") );
      pstmt.setDouble(2, Double.valueOf( (String)
          salaryMap.get("MIN_SALARY") );
      rs = pstmt.executeQuery();
      int tmpEmpNo = 0;
      String tmpEmpName = "";
      double tmpSalary = 0.0D;
      while (rs.next()){
        tmpEmpNo = rs.getInt("EMP_NO");
        tmpEmpName = rs.getString("EMP_NAME");
        tmpSalary = rs.getDouble("SALARY");
        tempEmpTO = new EmployeeTO(tmpEmpNo,
              tmpEmpName,
              tmpSalary);
        empList.add(tempEmpTO);  
      }//end while
    }//end try
    catch (SQLException sqle){
      throw new DBException(sqle);
    }//end catch
    finally{
      try{
        if (rs != null){
          rs.close();
        }
      }
      catch (SQLException sqle){
        throw new DBException(sqle);
      }
      try{
        if (pstmt != null){
          pstmt.close();
        }       
      }
      catch (SQLException sqle){
        throw new DBException(sqle);
      }
      try{
        if (conn != null){
          conn.close();
        }       
      }
      catch (SQLException sqle){
        throw new DBException(sqle);
      }
    }//end of finally block
    return empList;
  }//end method findBySalaryRange
}

 

以上说明了DAO几个关键点:

  • They encapsulate all interactions with the JDBC API. If an O/R mapping solution like Kodo or Hibernate were being used, the DAO classes can wrap the proprietary APIs of these products.
  • They wrap the retrieved data in a JDBC API-neutral transfer object and returns it to the business tier for further processing.
  • They are stateless in nature. Their sole aim is to access and change persistent data for the business objects.
  • They trap any errors (for example, database is unavailable, wrong SQL syntax) reported in the process by the underlying JDBC API or database as SQLException. The DAO objects notify the business objects of such errors again by a JDBC-neutral, custom build runtime exception class DBException.
  • They release database resources like Connection and PreparedStatement objects back to the pool and relinquish memory held by ResultSet cursors after they have been used.

 

Therefore, the DAO layer provides a consistent data access API for the business tier abstracting the low level data access API.

生成DAO Factory

DAOFactory.java

public class DAOFactory {
  private static DAOFactory daoFac;

  static{
    daoFac = new DAOFactory();
  }

  private DAOFactory(){}

  public DAOFactory getInstance(){
    return daoFac;
  }

  public IEmployeeDAO getEmployeeDAO(){
    return new EmployeeDAOImpl();
  }
}

business组件结合

EmployeeBusinessServiceImpl .java

public class EmployeeBusinessServiceImpl implements
                                       IEmployeeBusinessService {

  public List getEmployeesWithinSalaryRange(Map salaryMap){

    IEmployeeDAO empDAO = DAOFactory.getInstance()
                                    .getEmployeeDAO();
    List empList = empDAO.findBySalaryRange(salaryMap);
    return empList;
  }
}

 

问题:

The DAO design pattern is not devoid of shortcomings:

  • Code Repetition: As evident from the EmployeeDAOImpl listing, code repetition (shown in bold above) is a major problem with JDBC-based, traditional database access. Writing boilerplate code over and over is a clear violation of the basic OO principle of code reuse. This has obvious side effects in terms of project cost, timelines, and effort.
  • Coupling: The DAO code is very tightly coupled with the JDBC interfaces and core collections. This is evident from the number of import statements per DAO class.
  • Resource Leakage: Following the design of the EmployeeDAOImpl class, all DAO methods must relinquish control of acquired database resources like connection, statements, and result sets. This is a risky proposition because a novice programmer can very easily skip those bits. As a result, resources would run out and bring the system to a halt.
  • Error Handling: JDBC drivers report all error situations by raising the SQLException. SQLException is a checked exception, therefore developers are forced to handle it—even though it isn't possible to recover from the majority of these exceptions, which results in cluttering the code. Moreover, the error code and message obtained from the SQLException object are database vendor-specific, so it's not possible to write portable DAO error messaging code.
  • Fragile Code: The setting of the bind variables for the statement object, and the retrieval of the data using the result set getter methods are two frequently used tasks in JDBC-based DAO. If the number of columns in the SQL where clause is changed, or the column positions are altered, the code has to go through the rigorous cycle of change, test, and redeployment.

进入Spring DAO


Figure 2. Major components of the Spring JDBC framework

JdbcTemplate 是最重要的 类,使用它能避免很过 错误,它主要做了以下工作:

Retrieves connections from the datasource. Prepares appropriate statement object. Executes SQL CRUD operations. Iterates over result sets and populates the results in standard collection objects. Handles SQLException exceptions and translates them to a more error-specific exception hierarchy.

用Spring DAO重写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值