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

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:
业务对象只应该关注业务逻辑,不应该关心数据存取的细节。数据访问对象必须实现特定的持久化策略(如,基于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,如需转载请自行联系原作者
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
设计模式 Java 测试技术
软件测试/测试开发/全日制|Page Object模式:为什么它是Web自动化测试的必备工具
软件测试/测试开发/全日制|Page Object模式:为什么它是Web自动化测试的必备工具
53 0
|
14天前
|
JavaScript
js 字符串String转对象Object
该代码示例展示了如何将一个以逗号分隔的字符串(`'1.2,2,3,4,5'`)转换为对象数组。通过使用`split(',')`分割字符串并`map(parseFloat)`处理每个元素,将字符串转换成浮点数数组,最终得到一个对象数组,其类型为`object`。
|
1月前
|
存储 设计模式 Python
Python中的类(Class)和对象(Object)
Python中的类(Class)和对象(Object)
29 0
|
1月前
|
存储 JavaScript
JS中Map对象与object的区别
JS中Map对象与object的区别
|
2月前
|
Java 流计算
在Flink实时任务中,POJO(Plain Old Java Object)对象的模式演进可能会引起不兼容的问题
【2月更文挑战第6天】在Flink实时任务中,POJO(Plain Old Java Object)对象的模式演进可能会引起不兼容的问题
21 3
|
3月前
|
JavaScript 前端开发 测试技术
Proxy vs Object.defineProperty:哪种对象拦截机制更适合你?
Proxy vs Object.defineProperty:哪种对象拦截机制更适合你?
|
3月前
|
存储 JavaScript 前端开发
【JavaScript】<面向对象Object>函数方法&对象创建&原型对象&作用域解析
【1月更文挑战第17天】【JavaScript】<面向对象Object>函数方法&对象创建&原型对象&作用域解析
|
3月前
|
JavaScript 前端开发
如何巧妙使用`Object.keys`方法将`JS`的一个对象的特定的值赋值给另外一个对象
如何巧妙使用`Object.keys`方法将`JS`的一个对象的特定的值赋值给另外一个对象
17 0
|
4月前
|
Docker Python 容器
generator object APIClient read from socket locals对象操作
generator object APIClient read from socket locals对象操作
24 1
|
5月前
|
Java
java判断Object对象是否为空demo
java判断Object对象是否为空demo