业务对象只应该关注业务逻辑,不应该关心数据存取的细节。数据访问对象必须实现特定的持久化策略(如,基于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);

    }

}
4. 参考
[2] 所使用的数据库表见 Java连接SqlServer2005MySQL5