数据访问对象模式.docx
《数据访问对象模式.docx》由会员分享,可在线阅读,更多相关《数据访问对象模式.docx(30页珍藏版)》请在冰点文库上搜索。
数据访问对象模式
php
/**
*数据访问对象(DataAccessObject)示例
*@create_date:
2010-01-04
*/
classBaseDAO
{
var$_db=null;
var$_table=null;
functionBaseDAO($config)
{
$this->_db=newMysqlDB();//这里的不能进行操作
}
/**
*获取处理
*
*@paramarray$filter //过滤条件
*@paramstring$field //获取字段
*@paramint$page //当前页
*@paramint$limit //页数
*/
functionfetch($filter=array(),$field="*",$page=1,$limit=null)
{
$this->_db->select($filed)->from($this->_table)->where($filter)->limit($page,$limit);
return$this->_db->execute();
}
functionupdate(){}
functiondelete(){}
functioninsert(){}
}
classMemberDAOextendsBaseDAO
{
var$_table="member";
}
$oMember=newMemberDAO();
$oMember->fetch();
/**
*常用到的地方:
*MVC中model层基类
*/
?
>
数据访问对象模式
数据访问对象模式描述了如何创建透明访问数据源的对象。
场景设计
设计一个BaseDao基类,实现数据库操作基本的一些query,insert,update方法
在实际使用的过程中,继承BaseDao,就可以直接调用基类的数据库操作方法
代码:
BaseDao数据库操作基类
php
//数据访问对象模式
//将数据库访问层脱离出来作为公用的访问接口,方便用户开放,是php中常用的一种设计模式
classBaseDao{
private$db;
publicfunction__construct($config){
$this->db=mysql_connect($config['user'],$config['pass'],$config['host']);
mysql_select_db($config['database'],$this->db);
}
publicfunctionquery($sql){
returnmysql_query($sql,$this->db);
}
}
代码:
UserDao用户数据表的数据操作,继承BaseDao
[php]viewplaincopyprint?
php
include("UserDao.php");
classUserDaoextendsBaseDao{
publicfunctionaddUser(){
$sql="INSERTINTOuser(username)VALUES('initphp')";
return$this->query($sql);
}
}
$UserDao=newUserDao;
$UserDao->addUser();
java数据访问对象模式---DAO模式
使用数据访问对象(DAO)模式来抽象和封装所有对数据源的访问。
DAO管理着与数据源的连接以便检索和存储数据。
DAO实现了用来操作数据源的访问机制。
数据源可以时RDBMS,LDAP,File等。
依赖于DAO的业务组件为其客户端使用DAO提供更简单的接口。
DAO完全向客户端隐藏了数据源实现细节。
由于当低层数据源实现变化时,DAO向客户端提供的接口不会变化,所有该模式允许DAO调整到不同的存储模式,而不会影响其客户端或者业务组件。
重要的是,DAO充当组件和数据源之间的适配器。
(按照这个理论,如果我们UPTEL系统使用了DAO模式,就可以无缝的从ORACLE迁移到任何一个RDBMS了。
梦想总是很完美的,且看看DAO模式如何实现)
1.结构,图1是表示DAO模式中各种关系的类图。
此主题相关图片如下:
2.参与者和职责
1)BusinessObject(业务对象)
代表数据客户端。
正是该对象需要访问数据源以获取和存储数据。
2)DataAccessObject(数据访问对象)
是该模式的主要对象。
DataAccessObject抽取该BusinessObject的低层数据访问实现,以保证对数据源的透明访问。
BusinessObject也可以把数据加载和存储操作委托给DataAccessObject。
3)DataSource(数据源)
代表数据源实现。
数据源可以是各RDBMSR数据库,OODBMS,XML文件等等。
4)valueObject(值对象)
代表用做数据携带着的值对象。
DataAccessObject可以使用值对象来把数据返回给客户端。
DataAccessObject也许会接受来自于客户端的数据,其中这些用于更新数据源的数据存放于值对象中来传递。
3.策略
1).自动DAO代码产生策略
因为每个BusinessObject对应于一个特殊的DAO,因此有可能建立BusinessObject,DAO和低层实现(比如RDBMS中的表)之间的关系(映射)。
一点这些关系(映射)已经建立,我们就可以编写与应用程序有馆的代码生成的简单工具了(什么?
自己写GP程序?
用ORM的附带工具自动生成不就完了,最多自己写几个Adapter,牛人就是不同,啥都要自己写...),其中的工具可以产生该应用程序需要的所有DAO代码。
如果DAO需求很复杂,我们可以采用第三方工具,其中这些工具提供对象到RDBMS数据库的关系映射(这里指的是前面提到的ORM工具,全称是ObjectRelationMapping,目前成熟的ORM工具有很多:
Hibernate,OJB,Torque,TopLink等等)。
这些工具通常包含GUI工具来把业务对象映射到持久性存储对象,并且因而定义中间DAO。
一旦这些映射完成,这些工具会自动地生成代码,并且也许会提供其他增值功能,比如结果缓冲、查询缓冲、与应用程序集成,以及与其他第三方产品(比如分布式缓冲)地继承,等等。
(增值服务:
Torque提供了结果缓冲,Hibernate提供了对Oracle数据库SQL指令的优化,OJB提供JDOAPI、OMDBAPI)
2).数据访问对象的工厂策略
通过调整抽象工厂和工厂方法模式,DAO模式可以达到很高的灵活度。
当低层存储不会随着实现变化而变化时,该策略可以使用工厂方法模式来实现该策略。
以产生应用程序需要的大量DAO。
图2是这种情况下的类图。
此主题相关图片如下:
当低层存储随着实现变化而变化时,该策略可以使用抽象工厂方法模式而实现。
图3是这种情况下的类图。
此主题相关图片如下:
5.结果
1).启用透明性
业务对象可以是使用数据源,而无须了解该数据源实现的具体细节。
访问是透明的,原因是实现被隐藏在DAO的内部。
2).启用更容易的迁移
DAO层使应用程序更加容易地迁移到一个不同的数据库实现。
业务对象不了解低层数据实现。
因而,该迁移只涉及对DAO层的变化。
更进一步说,如果使用工厂策略,则有可能为每一个低层存储实现提供一个具体工厂实现。
在这种情况下,迁移到不同的迁移实现意味着给应用程序提供一个新的工厂实现。
3).减少业务对象中代码复杂度
由于DAO管理所有的数据访问复杂性,它可以简化业务对象和其他使用DAO的客户端中的代码。
所有与实现有关的代码(比如sql语句)都被包含在DAO中,而不是包含在业务对象中。
这样做提高了代码的可读性,已经代码生产效率。
4).把所有的数据访问集中到一个独立的层。
因为所有的数据访问操作现在被委托给DAO,所有单独的数据访问层可以被看作把数据访问实现与应用程序中的其他代码相隔离的。
这种集中化使应用程序更容易地维护和管理。
5).不适用于容器管理的持久性
由于EJB容器用容器管理的持久性(CMP)来管理实体bean,该容器会自动地服务所有的持久性存储访问。
使用容器管理的实体bean的应用程序不需要DAO层,因为该应用程序服务器透明地提供该功能。
然而,当需要组合使用CMP和BMP时,DAO仍旧有用处。
6).添加其他层
DAO会在数据客户端和数据源之间创建其他的对象层,其中该数据源需要被设计和实现以便于权衡该模式的好处。
但是选择本方法也会带来额外的开销。
7).需要类层次设计
在使用工厂策略时,我们需要设计和实现具体工厂的层次,以及这些工厂产生的具体产品层次。
如果能够确保这种灵活性,则有必要考虑这种额外的工作。
这样做会增加设计的复杂性。
然而,在实现该工厂策略时,你可以首先考虑工厂方法模式,然后再根据需要过渡到抽象工厂。
1,什么是DAO?
数据访问对象(DAO)为数据库提供了一个抽象接口,使得开发人员无需了解数据库模式的详细信息就可以访问常见数据库操作——实际上,数据访问对象实现了应用程序的低级别的数据访问逻辑与高级别的业务逻辑的分离。
这种分离是非常重要的,因为它使得这两种重要的应用程序层可以彼此相对独立,从而使我们可以经常地对它们进行单独扩展。
使用DAO后,发生变化的商业逻辑可以使用相同的DAO接口,同时对逻辑的修改不会影响DAO客户端——只要该接口的实现是适当的。
DAO是集合,对象,方法和属性;它用对象集合来处理数据库,表,视图和索引等。
使用DAO编程,可以访问并操作数据库,管理数据库的对象和定义数据库的结构等。
DAO模型是设计关系数据库结构的对象类的集合。
它们提供了完成管理一个关系型数据库系统所需的全部操作的属性和方法,这其中包括创建数据库,定义表、字段和索引,建立表间的关系,定位和查询数据库等。
2,DAO设计模式:
图1显示了应用程序和数据源之间的关系:
图1.应用程序和数据源
在整个应用程序中使用数据访问对象(DAO)使我们可以将底层数据访问逻辑与业务逻辑分离开来。
我们构建了为每一个数据源提供GRUD(创建、读取、更新、删除)操作的DAO类。
在本文中,我将为您介绍构建更好的DAO类的DAO实现策略和技术。
更确切地说,我将讨论日志、异常处理和事务界定。
您将学到如何将这三者结合到自己的DAO类中。
本文假定您熟悉JDBCAPI、SQL和关系数据库编程。
我们将以对DAO设计模式和数据访问对象的概述开始。
DAO基础
DAO模式是标准J2EE设计模式之一。
开发人员用这种模式将底层数据访问操作与高层业务逻辑分离开。
一个典型的DAO实现有以下组件:
1.一个DAO工厂类
2.一个DAO接口
3.一个实现了DAO接口的具体类
4.数据传输对象(有时称为值对象)
5.具体的DAO类包含访问特定数据源的数据的逻辑。
dao包括5个重要部分
(1)数据库连接类
(2)vo类
(3)dao接口类
(4)dao实现类
(5)dao工厂类
(6)代理实现类
1.数据库连接类
主要功能是连接数据库,以及关闭数据库,通过数据库连接类,可大大的简便开发,在需要创建数据库时,只需创建该类的实例。
并调用其中的方法就可获得数据库连接和关闭数据库,不必再进行充分操作
2.vo类
vo类是一个包含属性和表中完全对应的类,并在该类中提供set和get方法来设置并获得改类中的属性。
一个vo类和一个数据库中的表相对应,也就是说有多少表就有多少vo类。
而实例化的vo对象代表一个表中的一行数据
3.DAO接口
接口中定义了用户的所有操作,如增、删、改、查。
不过因为是接口,所有仅仅只是定义。
需要子类来实现。
4.DAO实现类
DAO实现类实现了dao接口,并且实现了dao接口中定义的所有方法。
在dao实现中通过连接数据库进行数据库操作。
一个dao实现类对应一个表,如userDao对应user表,该类中定义对该表的所有操作
5.DAO工厂类
在没有dao工厂类的情况下,必须通过创建DAO实现类实例才能完成数据库操作。
对于后期修改非常不方便。
有时要修改所有dao实现类的方法。
使用dao工厂类可以很好的解决后期修改的问题,可以通过dao工厂类的一个静态方法来获得dao实现类的实例。
这时如果需要替换dao实现类,只需要修改该dao工厂类中的方法代码,而不必修改所有的数据库代码。
6.代理实现类:
主要负责数据库的打开和关闭。
并且调用真实实现类的操作。
--输入界面-->
<%@pagecontentType="text/html"pageEncoding="GBK"%>
<%request.setCharacterEncoding("GBK");//解决乱码问题%>
empno:
ename:
job:
hiredate:
sal:
--后台插入数据-->
<%@pageimport="info.haowei.Dao.factory.DAOFactory"%>
<%@pageimport="java.text.SimpleDateFormat"%>
<%@pageimport="info.haowei.Dao.vo.Emp"%>
<%@pagecontentType="text/html"pageEncoding="GBK"%>
<%request.setCharacterEncoding("GBK");//解决乱码问题%>
<%
Empemp=newEmp();
emp.setEmpno(Integer.parseInt(request.getParameter("empno")));
emp.setEname(request.getParameter("ename"));
emp.setJob(request.getParameter("job"));
emp.setHiredate((newSimpleDateFormat("yyyy-MM-dd")).parse(request.getParameter("hiredate")));
emp.setSal(Float.parseFloat(request.getParameter("sal")));
try{
if(DAOFactory.getIEmpDAOInstance().doCreate(emp)){
%>
添加成功!
!
<%
}else{
%>
添加失败!
!
!
<%
}
}catch(Exceptione){
e.printStackTrace();
}
%>
//vo类
packageinfo.haowei.Dao.vo;
importjava.util.Date;
publicclassEmp{
privateintempno;
privateStringename;
privateStringjob;
privateDatehiredate;
privatefloatsal;
publicintgetEmpno(){
returnempno;
}
publicvoidsetEmpno(intempno){
this.empno=empno;
}
publicStringgetEname(){
returnename;
}
publicvoidsetEname(Stringename){
this.ename=ename;
}
publicStringgetJob(){
returnjob;
}
publicvoidsetJob(Stringjob){
this.job=job;
}
publicDategetHiredate(){
returnhiredate;
}
publicvoidsetHiredate(Datehiredate){
this.hiredate=hiredate;
}
publicfloatgetSal(){
returnsal;
}
publicvoidsetSal(floatsal){
this.sal=sal;
}
}
//工厂类-----dao工厂类
packageinfo.haowei.Dao.factory;
importinfo.haowei.Dao.dao.IEmpDAO;
importinfo.haowei.Dao.dao.proxy.EmpDAOProxy;
publicclassDAOFactory{
publicstaticIEmpDAOgetIEmpDAOInstance(){
returnnewEmpDAOProxy();
}
}
//操作数据库的类
packageinfo.haowei.Dao.dbc;
importjava.sql.Connection;
importjava.sql.DriverManager;
importjava.sql.SQLException;
publicclassDatabaseConnection{
privatestaticfinalStringDBDRIVER="org.gjt.mm.mysql.Driver";
publicstaticfinalStringDBURL="jdbc:
mysql:
//localhost:
3306/zhw";
publicstaticfinalStringDBUSER="root";
publicstaticfinalStringDBPASS="root";
privateConnectionconn;
publicDatabaseConnection(){
try{
Class.forName(DBDRIVER);
this.conn=DriverManager.getConnection(DBURL,DBUSER,DBPASS);
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}catch(SQLExceptione){
e.printStackTrace();
}
}
publicConnectiongetConnection(){
returnthis.conn;
}
publicvoidclose(){
if(this.conn!
=null){
try{
this.conn.close();
}catch(SQLExceptione){
e.printStackTrace();
}
}
}
}
//代理类.相当于回调吧
packageinfo.haowei.Dao.dao.proxy;
importjava.util.List;
importinfo.haowei.Dao.dao.IEmpDAO;
importinfo.haowei.Dao.dao.impl.EmpDAOImpl;
importinfo.haowei.Dao.dbc.DatabaseConnection;
importinfo.haowei.Dao.vo.Emp;
//代理
publicclassEmpDAOProxyimplementsIEmpDAO{
privateDatabaseConnectiondbc=null;
privateIEmpDAOdao=null;
publicEmpDAOProxy(){
this.dbc=newDatabaseConnection();
this.dao=newEmpDAOImpl(this.dbc.getConnection());
}
publicbooleandoCreate(Empemp){
booleanflag=false;
try{
if(this.dao.findById(emp.getEmpno())==null){
flag=this.dao.doCreate(emp);
}
}catch(Exceptione){
}finally{
dbc.close();
}
returnflag;
}
publicListfindAll(Stringkeyword){
Listall=null;
try{
all=this.dao.findAll(keyword);
}catch(Exceptione){
}finally{
dbc.close();
}
returnall;
}
publicEmpfindById(intempno){
Empemp=n