概述:在科技每天都在变化的今天,你无法预料到今后你的程序是否面临更新持久层的存储问题。如果你还是小公司,利用JDBC+Access开发了一套留言板,在1,2年之后,你发现你的留言板很火,你打算把它转变为论坛模式,这样你的现有的数据库可能会有效率瓶颈上的问题,你想升级成MS-SQLServer或者oracle, 又或者转变为DB2。或者你发现留言板人气是在很差,但是还不能不有这个功能,你想把这个数据库留给别的程序使用,而利用xml文件来作存储。以上的情况一旦发生,你就要面临一个超级难度的问题, 你的程序里面有关数据库连接的部分,就要全部重写。不同的数据库建立连接的方式不同,具体的查询语句上,比如Stored Procedure可能还不一样。如果面临这样的处境,想必你要去跳楼了。DAO(Data – Access –Object)就是帮你解决这个难题的。顾名思义,数据访问对象,就是用一个对象去访问数据库吧?对!基本上来说,就是这样。利用一个相同的对象,去访问。
可是一个对象怎么会能访问不同的数据库呢?别忘了,我们用的是java语言,其中你在学习javaSE的时候,一定看到过这样一个单词 – Polymorphism。对,就是他,多态!
想起来了吗?当你学习inherit(继承,派生), extends, implements这些的时候…重写(overlord),重载.可以利用多态,调用一个对象的相同的方法,可以实现哦。
应用:我们使用DAO的时候,一般都会利用工厂模式来产生DAOBase,由这个来派生对于每一个不同的数据局接口的访问方式。
优点:正如上图所示范的那样,把不同的数据库类型,可以制造相应的DAO工厂,利用工厂产生出来对于这个数据的自己专用DAO接口,然后应用程序用来访问数据的部分,就只需要实现这个接口就可以了。这样不必担心真正的持久层到底是什么东西,关系型数据库,XML或者甚至可能是文本文件。我们所作的,都是使用相同的程序代码,而真正去访问数据库,建立连接,全部都是DAO工厂根DAO接口里面的问题了。随便你换成什么数据库,程序代码只需要实现对应的DAO接口,本身不用更改任何代码。
缺点:对于每一种数据库,都要建立对应的工厂,然后子类派生具体的建立连接方式,对于小程序来说,不如直接使用JDBC来的方便,会增加开发的复杂度。
举例:
利用DAO模式我们客户端的代码很可能看起来是这样的。
// 取得DAO工厂的抽象类
DAOFactory xmlFactory = DAOFactory.getDAOFactory(DAOFactory.XML);
// 利用工厂得到具体的类
CustomerDAO custDAO = xmlFactory.getCustomerDAO();
// insert 操作
int newCustNo = custDAO.insertDB(...);
// select 操作,这里我们利用Transfer Object来返回一个查询的结果(类似EJB entity Bean)
Customer customer = custDAO.selectDB(...);
// 修改得到对象的属性
customer.setCustomerName(...);
customer.setGender(...);
// 同样,利用Transfer Object 来执行 update 更新数据库
custDAO.updateDB(customer);
// delete a customer object
custDAO.deleteDB(customer);
...
-----------------------------------------------------
// 对于各种数据库类型总体抽象出来的工厂抽象类
public abstract class DAOFactory {
// 列出来支持的数据库类型
public static final int MS_SQL = 1;
public static final int RACLE = 2;
...
// 利用统一的 getDAOFactory方法,来取得不同的DAO对象,因为你不知道具体应用中是什么数据库,所以可以利用java的多态,再定义方法的时候返回DAOFactory,这个是所有可能返回结果的super class,也就是说,每一个可能的返回结果,要继承或者间接的实现 DAOFactory 这个超类。
public static DAOFactory getDAOFactory(int databaseType) {
switch (whichFactory) {
case MS_SQL:
return new SqlserverDAOFactory();
case ORACLE :
return new OracleDAOFactory();
...
default :
return null;
}
}
// 这里边是具体需要利用到的对象,可以暂且理解为表,一个DAO
对应持久数据层里面的 table
public abstract CustomerDAO getCustomerDAO();
public abstract OrderDAO getOrderDAO();
...
}
----------------------------------------------------------
// 这些是 CustomerDAO 需要进行对数据库操作的方式 ,比如 insert, delete, select, update
public interface CustomerDAO {
public int insertDB(...);
public boolean deleteDB(...);
public Customer selectDB(...);
public boolean updateDB(...);
...
}
-----------------------------------------------------------
// 具体的SQLServer是这样实现 DAO Factory
import java.sql.*;
…
public class SqlserverDAOFactory extends DAOFactory {
public static final String DRIVER =" xxx.xxx.xxxdriver ";
public static final String DBURL = ” … ip:port … ;
// method to create connections
public static Connection createConnection() {
// 这里利用JDBC或者连接池取得Connection 对象,连到数据库 注意exception的处理
}
public CustomerDAO getCustomerDAO() {
// 返回对应于这个sqlServer数据库的具体DAO对象,因为这个也是多态的调用,所以sqlServerCustomerDAO 是要继承于 CustomerDAO的,原理跟 DAOFactory一样
return new SqlServerCustomerDAO();
}
public OrderDAO getOrderDAO() {
//
return new SqlServerOrderDAO();
}
...
}
------------------------------------------------------------
import java.sql.*;
public class SqlServerCustomerDAO implements CustomerDAO {
public SqlServerCustomerDAO() {
// initialization
}
public int insertDB(...) {
// 执行具体的插入到SQLServer的insert代码
// 返回插入成功的customer id ,要是失败,返回-1
}
public boolean deleteDB(...) {
// 执行 SQLServer的删除语句
// 返回成功或者失败 true false
}
public Customer selectDB(...) {
// Implement find a customer here using supplied
}
public boolean updateDB(...) {
// implement update record here using data
}
...
}
----------------------------------------------------
上面介绍了transfer object ,不再废话了
public class Customer implements java.io.Serializable {
// member variables
int CustomerId;
String customerName;
String gender;
...
// getter and setter methods...
...
}
考试:以前版本的考试里面有,310-083已经没有了。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/225526/viewspace-448868/ ,如需转载,请注明出处,否则将追究法律责任。