DAO-数据访问对象(Data Access Object) 模式

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介:
业务对象只应该关注业务逻辑,不应该关心数据存取的细节。数据访问对象必须实现特定的持久化策略(如,基于JDBC或Hibernate的持久化逻辑),  这样就抽出来了 DAO 层,作为数据源层,而之上的 Domain Model 层与之通讯而已,如果将那些实现了数据访问操作的所有细节都放入高层 Domain model( 领域模型 ) 的话,系统的结构一定层次上来说就变得有些混乱。低级别的数据访问逻辑与高级别的业务逻辑分离,用一个 DAO 接口隐藏持久化操作的细节,这样使用的最终目的就是让业务对象无需知道底层的持久化技术知识,这是标准  j2ee  设计模式之一。
 
1.        DAO 模式使用环境
具体类图如下。
参与者和职责
1)       BusinessObject( 业务对象 )
代表数据客户端。正是该对象需要访问数据源以获取和存储数据。
2)       DataAccessObject( 数据访问对象 )
是该模式的主要对象。 DataAccessObject 抽取该 BusinessObject 的低层数据访问实现,以保证对数据源的透明访问。 BusinessObject 也可以把数据加载和存储操作委托给 DataAccessObject
3)       DataSource( 数据源 )
代表数据源实现。数据源可以是各 RDBMSR 数据库, OODBMS,XML 文件等等。
4)       ValueObject( 值对象 )
代表用做数据携带着的值对象。 DataAccessObject 可以使用值对象来把数据返回给客户端。
DataAccessObject 也许会接受来自于客户端的数据,其中这些用于更新数据源的数据存放于值对象中来传递。
 
2.  数据访问对象的工厂策略
通过调整抽象工厂和工厂方法模式, DAO 模式可以达到很高的灵活度。具体类图如下。
DAO 层使应用程序更加容易地迁移到一个不同的数据库实现。业务对象不了解低层数据实现。因而,该迁移只涉及对 DAO 层的变化。更进一步说,如果使用工厂策略,则有可能为每一个低层存储实现提供一个具体工厂实现。在这种情况下,迁移到不同的迁移实现意味着给应用程序提供一个新的工厂实现。
同时,抽象 DAO 工厂可以指定需要创建的实例 DAO ,并交由不同的具体 DAO 工厂去创建。
 
3.DAO 代码实例(工程代码见附件)
一个典型的 DAO 组成: DAO 工厂类, DAO 接口,实现 DAO 接口的具体类 ( 每个  DAO  实例负责一个主要域对象或实体 ) VO Value Object )。
VO Student 类,将所有关于持久化的操作归入 StudentDAO 类中。
Student.java
public   class  Student {
     private  String  id ;
     private  String  name ;
     private  String  cardId ;
     private   int   age ;
 
     getter/setter() 。。。
}
StudentDAO.java
public   interface  StudentDAO {
     public   boolean  insertStudent(Student student);
     public   boolean  deleteStudent( int  id);
     public  Student findStudent( int  id);
}
抽象 DAO 工厂 DAOFactory 指定了可能的具体 DAO 工厂,并指定需要创建的具体 DAO
DAOFactory.java
public   abstract   class  DAOFactory {
     // List of DAO types supported by the factory
     public   static   final   int   SQLSERVER  = 1;
     public   static   final   int   MYSQL  = 2;
     // There will be a method for each DAO that can be
     // created. The concrete factories will have to
     // implement these methods.
     public   abstract  StudentDAO getStudentDAO();
 
     public   static  DAOFactory getDAOFactory( int  whichFactory) {
        switch  (whichFactory) {
        case   SQLSERVER :
            return   new  SqlServerDAOFactory();
        case   MYSQL :
            return   new  MySqlDAOFactory();
        default :
            return   null ;
       }
    }
}
这里提供两个具体 DAO 工厂, SqlServerDAOFactory MySqlDAOFactory 。提供它们来得到具体的 DAO 实现。
SqlServerDAOFactory.java
public   class  SqlServerDAOFactory  extends  DAOFactory{
     public   static   final  String  DRIVER  =  "com.microsoft.sqlserver.jdbc.SQLServerDriver" ;
     public   static   final  String  DBURL  =  "jdbc:sqlserver://localhost:1025; DatabaseName=tmp" ;
     private   static  String  userName  =  "sa" ;
     private   static  String  userPwd  =  "root" ;
 
     public   static  Connection createConnection() {
       Connection dbConn =  null ;
        try  {
           Class.forName( DRIVER );
           dbConn = DriverManager.getConnection( DBURL userName userPwd );
        catch  (ClassNotFoundException e) {
           e.printStackTrace();
        catch  (SQLException e) {
           e.printStackTrace();
       }
        return  dbConn;
    }
 
     public  StudentDAO getStudentDAO() {
        return   new  SqlServerStudentDAO(createConnection());
    }
 
     。。。。。。
}
MySqlDAOFactory.java
这里提供一个缺省的 StudentDAO 实现 StudentDAODefaultImpl 它依据特定的 Connection ,来实现数据库相关操作。
StudentDAODefaultImpl.java
public   abstract   class  StudentDAODefaultImpl  implements  StudentDAO {
     private  Connection  dbConn ;
 
     public  StudentDAODefaultImpl(Connection dbConn) {
        this . dbConn  = dbConn;
    }
 
     public   boolean  deleteStudent( int  id) {
       Statement stmt;
        try  {
           stmt =  dbConn .createStatement();
           String sql =  "DELETE FROM student_table WHERE id = '"  + id +  "'" ;
            int  delete = stmt.executeUpdate(sql);
            if  (delete == 1)
               return   true ;
        catch  (SQLException e) {
           e.printStackTrace();
       }
        return   false ;
    }
 
     public  Student findStudent( int  id) { 。。。 }
     public   boolean  insertStudent(Student stu) { 。。。 }
}
两个特定的 DAO 类分别从两个具体 DAO 工厂, SqlServerDAOFactory MySqlDAOFactory 中得到连接对象。
SqlServerStudentDAO.java
public   class  SqlServerStudentDAO  extends  StudentDAODefaultImpl {
     private  Connection  dbConn  =  SqlServer DAOFactory.createConnection();
   
     public  SqlServerStudentDAO(Connection dbConn) {
        super (dbConn);
    }
 
     public  Connection getDbConn() {
        return   dbConn ;
    }
}
MySqlStudentDAO.java
测试类 Test.java
public   class  Test {
     public   static   void  main(String[] args) {
       Student student =  new  Student( "1" "zj" "0901" , 27);
       DAOFactory mysqlDAOFactory = DAOFactory.getDAOFactory(DAOFactory. MYSQL );
       StudentDAO studentDAO = mysqlDAOFactory.getStudentDAO();
       studentDAO.insertStudent(student);
    }
}
本文转自zhangjunhd51CTO博客,原文链接:http://blog.51cto.com/zhangjunhd/127856,如需转载请自行联系原作者
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
ES6中map对象的使用,确实比Object好使哈
ES6中Map对象的使用优势,包括任意类型作为键、直接获取大小、增删查改操作等。Map的键可以是函数、对象、NaN等,支持forEach循环和for...of循环。
30 1
ES6中map对象的使用,确实比Object好使哈
|
1月前
|
Python
通过 type 和 object 之间的关联,进一步分析类型对象
通过 type 和 object 之间的关联,进一步分析类型对象
53 3
|
23天前
|
JavaScript 前端开发 大数据
在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改
在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改
13 0
|
3月前
|
数据安全/隐私保护
作用域通信对象:session用户在登录时通过`void setAttribute(String name,Object value)`方法设置用户名和密码。点击登录按钮后,跳转到另外一个页面显示用户
该博客文章通过示例演示了如何使用session对象的`setAttribute`和`getAttribute`方法在不同页面间传递和显示用户的用户名和密码信息,并说明了如何设置会话的有效期。
作用域通信对象:session用户在登录时通过`void setAttribute(String name,Object value)`方法设置用户名和密码。点击登录按钮后,跳转到另外一个页面显示用户
|
3月前
|
SQL 存储 数据库
|
3月前
|
存储 关系型数据库 MySQL
|
3月前
【Azure Developer】使用PowerShell Where-Object方法过滤多维ArrayList时候,遇见的诡异问题 -- 当查找结果只有一个对象时,返回结果修改了对象结构,把多维变为一维
【Azure Developer】使用PowerShell Where-Object方法过滤多维ArrayList时候,遇见的诡异问题 -- 当查找结果只有一个对象时,返回结果修改了对象结构,把多维变为一维
网易:所有的对象最终都会继承自 Object.prototype ? ——原型链(二)详细讲解!
网易:所有的对象最终都会继承自 Object.prototype ? ——原型链(二)详细讲解!
|
3天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
28 4
|
1月前
|
Java
Java Object 类详解
在 Java 中,`Object` 类是所有类的根类,每个 Java 类都直接或间接继承自 `Object`。作为所有类的超类,`Object` 定义了若干基本方法,如 `equals`、`hashCode`、`toString` 等,这些方法在所有对象中均可使用。通过重写这些方法,可以实现基于内容的比较、生成有意义的字符串表示以及确保哈希码的一致性。此外,`Object` 还提供了 `clone`、`getClass`、`notify`、`notifyAll` 和 `wait` 等方法,支持对象克隆、反射机制及线程同步。理解和重写这些方法有助于提升 Java 代码的可读性和可维护性。