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

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介:
业务对象只应该关注业务逻辑,不应该关心数据存取的细节。数据访问对象必须实现特定的持久化策略(如,基于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,如需转载请自行联系原作者
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
4月前
|
存储 消息中间件 人工智能
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
152 11
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
|
6月前
|
JavaScript 前端开发 开发者
讲述Vue框架中用于对象响应式变化的Object.defineProperty函数。
综上所述,Vue.js通过 `Object.defineProperty()`提供了强大的响应式能力,使得状态管理变得简洁高效。这种能力是Vue.js受到广大开发者青睐的重要原因之一。尽管Vue 3.x使用Proxy替代了该方法,但对于Vue 2.x及其之前版本,`Object.defineProperty()`是理解Vue.js内部工作机制不可或缺的一部分。
233 27
|
12月前
|
安全 Java
Object取值转java对象
通过本文的介绍,我们了解了几种将 `Object`类型转换为Java对象的方法,包括强制类型转换、使用 `instanceof`检查类型和泛型方法等。此外,还探讨了在集合、反射和序列化等常见场景中的应用。掌握这些方法和技巧,有助于编写更健壮和类型安全的Java代码。
683 17
|
10月前
|
前端开发 数据处理
对象数据的读取,看这一篇就够了!Object.keys()、Object.values()和Object.entries()用法详解;如何获取对象原型链上的属性
Object.keys()、Object.values()和Object.entries()都是利于对象操作的便捷方法,能有效提升数据处理的效率。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
ES6中map对象的使用,确实比Object好使哈
ES6中Map对象的使用优势,包括任意类型作为键、直接获取大小、增删查改操作等。Map的键可以是函数、对象、NaN等,支持forEach循环和for...of循环。
191 1
ES6中map对象的使用,确实比Object好使哈
|
Python
通过 type 和 object 之间的关联,进一步分析类型对象
通过 type 和 object 之间的关联,进一步分析类型对象
281 3
|
JavaScript 前端开发 大数据
在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改
在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改
251 0
|
10月前
|
安全 IDE Java
重学Java基础篇—Java Object类常用方法深度解析
Java中,Object类作为所有类的超类,提供了多个核心方法以支持对象的基本行为。其中,`toString()`用于对象的字符串表示,重写时应包含关键信息;`equals()`与`hashCode()`需成对重写,确保对象等价判断的一致性;`getClass()`用于运行时类型识别;`clone()`实现对象复制,需区分浅拷贝与深拷贝;`wait()/notify()`支持线程协作。此外,`finalize()`已过时,建议使用更安全的资源管理方式。合理运用这些方法,并遵循最佳实践,可提升代码质量与健壮性。
311 1
|
10月前
|
Java
课时78:Object类的基本概念
Object类的主要特点是可以解决参数的统一问题,使用object类可以接受所有的数据类型。 1. Object类简介 2. 观察Object类接收所有子类对象 3. 使用Object类接收数组
204 0
|
JSON Java Apache
Java基础-常用API-Object类
继承是面向对象编程的重要特性,允许从已有类派生新类。Java采用单继承机制,默认所有类继承自Object类。Object类提供了多个常用方法,如`clone()`用于复制对象,`equals()`判断对象是否相等,`hashCode()`计算哈希码,`toString()`返回对象的字符串表示,`wait()`、`notify()`和`notifyAll()`用于线程同步,`finalize()`在对象被垃圾回收时调用。掌握这些方法有助于更好地理解和使用Java中的对象行为。
172 8