传统的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重写
分享到:
相关推荐
#### 5.1 Spring 持久层入门 ##### 5.1.1 Spring 的 DAO 支持 Spring DAO的核心理念是通过抽象出一系列接口来解耦具体的数据库实现细节。这些接口通常包含基本的数据操作方法,例如:`insert`、`find`、`update`和...
### Spring 快速入门知识点详解 #### Spring框架简介与优势 Spring框架是一个开源的轻量级Java应用框架,旨在简化企业级应用的开发过程。它提供了全面的解决方案,包括依赖注入(Dependency Injection, DI)、面向...
在Spring入门阶段,首先要理解的是依赖注入(DI)。DI是一种设计模式,它允许我们解耦组件,让它们之间通过接口而非具体的实现进行交互。Spring通过容器管理对象的生命周期和依赖关系,我们只需要配置好bean的定义,...
本文将深入探讨Spring DAO框架的入门知识,包括其基本概念、主要功能、如何配置以及实际应用。 **1. Spring DAO概述** Spring DAO框架是Spring对传统DAO设计模式的实现,它提供了统一的异常处理、事务管理和数据源...
### Spring快速入门教程知识点解析 #### 一、Spring框架概览与优势 Spring框架是一个开源的轻量级Java EE框架,旨在简化企业级应用的开发。它提供了全面的解决方案,包括控制反转(Inversion of Control,IoC)、...
数据访问层(DAO或Repository)与数据持久化进行交互。此外,Spring还提供了事务管理、安全性控制等企业级服务。 要实现快速开发Springweb应用,开发者需要掌握Spring框架的IOC容器配置和使用,AOP的相关知识,以及...
Spring的DAO(Data Access Object)抽象层使得数据库访问更加简单,减少了对JDBC的直接操作。 Spring还提供了大量其他功能,如Spring Boot用于快速构建独立的应用程序,Spring Cloud为微服务架构提供了一套完整的...
### Spring框架入门到熟练 #### 一、Spring框架概述 Spring框架是一款开源的企业级应用框架,旨在解决企业级应用开发中的复杂性问题。它最初由Rod Johnson创建,并于2004年发布了第一个版本。Spring框架的核心优势...
Spring框架是中国Java开发领域中最广泛使用的轻量级框架之一,它以其依赖注入...这份"spring入门介绍PPT"将是你深入理解Spring的宝贵资源,通过它,你可以逐步掌握Spring的核心理念和技术,开启你的Spring开发之旅。
### Spring入门教程知识点详解 #### 一、理论知识 ##### 1. 依赖注入与控制反转 - **依赖注入**(Dependency Injection, DI):在应用程序的运行期间,由外部容器(例如Spring容器)动态地将一个对象所依赖的其他...
在 Spring MVC 中,模型通常由 Java 对象(Beans)组成,这些对象通过 DAO(数据访问对象)与数据库交互。 2. **视图(View)**:负责呈现数据。Spring MVC 支持多种视图技术,如 JSP、FreeMarker 或 Thymeleaf,...
本入门Demo将帮助初学者快速理解并掌握 Spring MVC 的基本概念和使用方法。 首先,Spring MVC 提供了控制器(Controller)的概念,它负责接收来自客户端的请求,处理业务逻辑,并将结果传递给视图(View)。在 ...
### Spring 快速入门教程知识点解析 #### 一、项目背景与目标 - **项目名称**:“MyUsers”——一个简单的Web应用,用于演示如何利用Struts作为前端框架、Spring作为中间层、Hibernate作为后端数据库操作层进行开发...