数据访问对象模式_第1页
数据访问对象模式_第2页
数据访问对象模式_第3页
数据访问对象模式_第4页
数据访问对象模式_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、_db = new MysqlDB(); / 这里的不能进行操作/* 获取处理* * param array $filter / 过滤条件* param string $field / 获取字段* param int $page / 当前页* param int $limit / 页数*/function fetch($filter = array(),$field = *,$page = 1,$limit = null)$this-_db-select($filed)-from($this-_table)-where($filter)-limit($page,$limit);return $

2、this-_db-execute();function update()function delete()function insert()class MemberDAO extends BaseDAOvar $_table = member;$oMember = new MemberDAO();$oMember-fetch();/* 常用到的地方:* MVC中model层基类*/?数据访问对象模式数据访问对象模式描述了如何创建透明访问数据源的对象。场景设计设计一个BaseDao基类,实现数据库操作基本的一些query,insert,update方法在实际使用的过程中,继承BaseDao,就可

3、以直接调用基类的数据库操作方法代码:BaseDao 数据库操作基类db = mysql_connect($configuser, $configpass, $confighost); mysql_select_db($configdatabase, $this-db); public function query($sql) return mysql_query($sql, $this-db); 代码:UserDao 用户数据表的数据操作,继承BaseDaophpview plaincopyprint?query($sql); $UserDao = new UserDao; $UserDao-

4、addUser(); java数据访问对象模式-DAO模式使用数据访问对象(DAO)模式来抽象和封装所有对数据源的访问。DAO管理着与数据源的连接以便检索和存储数据。DAO实现了用来操作数据源的访问机制。数据源可以时RDBMS,LDAP,File等。依赖于DAO的业务组件为其客户端使用DAO提供更简单的接口。DAO完全向客户端隐藏了数据源实现细节。由于当低层数据源实现变化时,DAO向客户端提供的接口不会变化,所有该模式允许DAO调整到不同的存储模式,而不会影响其客户端或者业务组件。重要的是,DAO充当组件和数据源之间的适配器。(按照这个理论,如果我们UPTEL系统使用了DAO模式,就可以无缝的

5、从ORACLE迁移到任何一个RDBMS了。梦想总是很完美的,且看看DAO模式如何实现)1.结构,图1是表示DAO模式中各种关系的类图。此主题相关图片如下:2.参与者和职责1)BusinessObject(业务对象)代表数据客户端。正是该对象需要访问数据源以获取和存储数据。2)DataAccessObject(数据访问对象)是该模式的主要对象。DataAccessObject抽取该BusinessObject的低层数据访问实现,以保证对数据源的透明访问。BusinessObject也可以把数据加载和存储操作委托给DataAccessObject。3)DataSource(数据源)代表数据源实现。

6、数据源可以是各RDBMSR数据库,OODBMS,XML文件等等。4)valueObject(值对象)代表用做数据携带着的值对象。DataAccessObject可以使用值对象来把数据返回给客户端。DataAccessObject也许会接受来自于客户端的数据,其中这些用于更新数据源的数据存放于值对象中来传递。3.策略1).自动DAO代码产生策略 因为每个BusinessObject对应于一个特殊的DAO,因此有可能建立BusinessObject,DAO和低层实现(比如RDBMS中的表)之间的关系(映射)。一点这些关系(映射)已经建立,我们就可以编写与应用程序有馆的代码生成的简单工具了(什么?自

7、己写GP程序?用ORM的附带工 具自动生成不就完了,最多自己写几个Adapter,牛人就是不同,啥都要自己写.),其中的工具可以产生该应用程序需要的所有DAO代码。 如果DAO需求很复杂,我们可以采用第三方工具,其中这些工具提供对象到RDBMS数据库的关系映射(这里指的是前面提到的ORM工具,全称是 Object Relation Mapping,目前成熟的ORM工具有很多:Hibernate,OJB,Torque,TopLink等等)。这些工具通常包含GUI工具来把业务对象映射到持久性存储对象,并且因而定义中间DAO。一旦这些映射完成,这些工具会自动地生成代码,并且也许会提供其他增值功能,比

8、如结果缓冲、查询缓冲、与应用程序集成,以及与其他第三方产品(比如分布式缓冲)地继承,等等。(增值服务:Torque提供了结果缓冲,Hibernate提供了对Oracle数据库SQL指令的优化,OJB提供JDO API、OMDB API)2).数据访问对象的工厂策略通过调整抽象工厂和工厂方法模式,DAO模式可以达到很高的灵活度。当低层存储不会随着实现变化而变化时,该策略可以使用工厂方法模式来实现该策略。以产生应用程序需要的大量DAO。图2是这种情况下的类图。此主题相关图片如下:当低层存储随着实现变化而变化时,该策略可以使用抽象工厂方法模式而实现。图3是这种情况下的类图。此主题相关图片如下:5.结

9、果1).启用透明性业务对象可以是使用数据源,而无须了解该数据源实现的具体细节。访问是透明的,原因是实现被隐藏在DAO的内部。2).启用更容易的迁移 DAO层使应用程序更加容易地迁移到一个不同的数据库实现。业务对象不了解低层数据实现。因而,该迁移只涉及对DAO层的变化。更进一步说,如果使用工厂策略,则有可能为每一个低层存储实现提供一个具体工厂实现。在这种情况下,迁移到不同的迁移实现意味着给应用程序提供一个新的工厂实现。3).减少业务对象中代码复杂度由于DAO管理所有的数据访问复杂性,它可以简化业务对象和其他使用DAO的客户端中的代码。所有与实现有关的代码(比如sql语句)都被包含在DAO中,而不

10、是包含在业务对象中。这样做提高了代码的可读性,已经代码生产效率。4).把所有的数据访问集中到一个独立的层。因为所有的数据访问操作现在被委托给DAO,所有单独的数据访问层可以被看作把数据访问实现与应用程序中的其他代码相隔离的。这种集中化使应用程序更容易地维护和管理。5).不适用于容器管理的持久性由于EJB容器用容器管理的持久性(CMP)来管理实体bean,该容器会自动地服务所有的持久性存储访问。使用容器管理的实体bean的应用程序不需要DAO层,因为该应用程序服务器透明地提供该功能。然而,当需要组合使用CMP和BMP时,DAO仍旧有用处。6).添加其他层DAO会在数据客户端和数据源之间创建其他的

11、对象层,其中该数据源需要被设计和实现以便于权衡该模式的好处。但是选择本方法也会带来额外的开销。7).需要类层次设计在使用工厂策略时,我们需要设计和实现具体工厂的层次,以及这些工厂产生的具体产品层次。如果能够确保这种灵活性,则有必要考虑这种额外的工作。这样做会增加设计的复杂性。然而,在实现该工厂策略时,你可以首先考虑工厂方法模式,然后再根据需要过渡到抽象工厂。1,什么是DAO? 数据访问对象(DAO)为数据库提供了一个抽象接口,使得开发人员无需了解数据库模式的详细信息就可以访问常见数据库操作实际上,数据访问对象实现了应用程序的低级别的数据访问逻辑与高级别的业务逻辑的分离。这种分离是非常重要的,因

12、为它使得这两种重要的应用程序层可以彼此相对独立,从而使我们可以经常地对它们进行单独扩展。使用DAO后,发生变化的商业逻辑可以使用相同的DAO接口,同时对逻辑的修改不会影响DAO客户端只要该接口的实现是适当的。 DAO是集合,对象,方法和属性;它用对象集合来处理数据库,表,视图和索引等。使用DAO编程,可以访问并操作数据库,管理数据库的对象和定义数据库的结构等。 DAO模型是设计关系数据库结构的对象类的集合。它们提供了完成管理一个关系型数据库系统所需的全部操作的属性和方法,这其中包括创建数据库,定义表、字段和索引,建立表间的关系,定位和查询数据库等。2,DAO 设计模式:图 1 显示了应用程序和

13、数据源之间的关系:图 1. 应用程序和数据源 在整个应用程序中使用数据访问对象(DAO)使我们可以将底层数据访问逻辑与业务逻辑分离开来。我们构建了为每一个数据源提供 GRUD (创建、读取、更新、删除)操作的 DAO 类。在本文中,我将为您介绍构建更好的 DAO 类的 DAO 实现策略和技术。更确切地说,我将讨论日志、异常处理和事务界定。您将学到如何将这三者结合到自己的 DAO 类中。本文假定您熟悉 JDBC API、SQL 和关系数据库编程。我们将以对 DAO 设计模式和数据访问对象的概述开始。DAO基础DAO 模式是标准 J2EE 设计模式之一。开发人员用这种模式将底层数据访问操作与高层业

14、务逻辑分离开。一个典型的 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类是一个包含属性和表中完全对应的

15、类,并在该类中提供set和get方法来设置并获得改类中的属性。一个vo类和一个数据库中的表相对应,也就是说有多少表就有多少vo类。而实例化的vo对象代表一个表中的一行数据3. DAO接口接口中定义了用户的所有操作,如增、删、改、查。不过因为是接口,所有仅仅只是定义。需要子类来实现。4. DAO实现类DAO实现类实现了dao接口,并且实现了dao接口中定义的所有方法。在dao实现中通过连接数据库进行数据库操作。一个dao实现类对应一个表,如userDao对应user表,该类中定义对该表的所有操作5. DAO工厂类在没有dao工厂类的情况下,必须通过创建DAO实现类实例才能完成数据库操作。对于后期

16、修改非常不方便。有时要修改所有dao实现类的方法。使用dao工厂类可以很好的解决后期修改的问题,可以通过dao工厂类的一个静态方法来获得dao实现类的实例。这时如果需要替换dao实现类,只需要修改该dao工厂类中的方法代码,而不必修改所有的数据库代码。6.代理实现类:主要负责数据库的打开和关闭。并且调用真实实现类的操作。 empno: ename: job: hiredate: sal: 添加成功! 添加失败! /vo类package info.haowei.Dao.vo;import java.util.Date;public class Emp private int empno; pri

17、vate String ename; private String job; private Date hiredate; private float sal; public int getEmpno() return empno; public void setEmpno(int empno) this.empno = empno; public String getEname() return ename; public void setEname(String ename) this.ename = ename; public String getJob() return job; pu

18、blic void setJob(String job) this.job = job; public Date getHiredate() return hiredate; public void setHiredate(Date hiredate) this.hiredate = hiredate; public float getSal() return sal; public void setSal(float sal) this.sal = sal; /工厂类-dao工厂类package info.haowei.Dao.factory;import info.haowei.Dao.d

19、ao.IEmpDAO;import info.haowei.Dxy.EmpDAOProxy;public class DAOFactory public static IEmpDAO getIEmpDAOInstance() return new EmpDAOProxy(); /操作数据库的类package info.haowei.Dao.dbc;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;public class DatabaseConnecti

20、on private static final String DBDRIVER = org.gjt.mm.mysql.Driver; public static final String DBURL = jdbc:mysql:/localhost:3306/zhw; public static final String DBUSER = root; public static final String DBPASS = root; private Connection conn; public DatabaseConnection() try Class.forName(DBDRIVER);

21、this.conn = DriverManager.getConnection(DBURL, DBUSER, DBPASS); catch (ClassNotFoundException e) e.printStackTrace(); catch (SQLException e) e.printStackTrace(); public Connection getConnection() return this.conn; public void close() if (this.conn != null) try this.conn.close(); catch (SQLException

22、e) e.printStackTrace(); /代理类.相当于回调吧package info.haowei.Dxy;import java.util.List;import info.haowei.Dao.dao.IEmpDAO;import info.haowei.Dao.dao.impl.EmpDAOImpl;import info.haowei.Dao.dbc.DatabaseConnection;import info.haowei.Dao.vo.Emp;/代理public class EmpDAOProxy implements IEmpDAO private

23、DatabaseConnection dbc = null; private IEmpDAO dao = null; public EmpDAOProxy() this.dbc = new DatabaseConnection(); this.dao = new EmpDAOImpl(this.dbc.getConnection(); public boolean doCreate(Emp emp) boolean flag = false; try if(this.dao.findById(emp.getEmpno()=null) flag = this.dao.doCreate(emp);

24、 catch (Exception e) finally dbc.close(); return flag; public List findAll(String keyword) Listall = null; try all = this.dao.findAll(keyword); catch (Exception e) finally dbc.close(); return all; public Emp findById(int empno) Emp emp = null; try emp = this.dao.findById(empno); catch (Exception e)

25、finally dbc.close(); return emp; /接口实现类,具体操作封装类-dao实现类package info.haowei.Dao.dao.impl;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;import javax.swing.text.html.HTMLDocument.HTMLRe

26、ader.PreAction;import info.haowei.Dao.dao.IEmpDAO;import info.haowei.Dao.vo.Emp;public class EmpDAOImpl implements IEmpDAO private Connection conn = null; private PreparedStatement pstmt = null; public EmpDAOImpl(Connection conn) this.conn = conn; public boolean doCreate(Emp emp) boolean flag = fals

27、e; String sql = Insert into emp (empno,ename,job,hiredate,sal)Values(?,?,?,?,?); try this.pstmt = this.conn.prepareStatement(sql); this.pstmt.setInt(1,emp.getEmpno(); this.pstmt.setString(2, emp.getEname(); this.pstmt.setString(3, emp.getJob(); this.pstmt.setDate(4, new java.sql.Date(emp.getHiredate

28、().getTime(); this.pstmt.setFloat(5, emp.getSal(); if(this.pstmt.executeUpdate()0)/如果存在更新 flag = true; this.pstmt.close(); catch (SQLException e) e.printStackTrace(); return flag; public List findAll(String keyword) Listall = new ArrayList(); String sql = select empno,ename,job,hiredate,sal from emp

29、 where ename like ? or job like ?; try this.pstmt = this.conn.prepareStatement(sql); this.pstmt.setString(1,%+keyword+%); this.pstmt.setString(2,%+keyword+%); ResultSet rs = this.pstmt.executeQuery(); Emp emp = null; while(rs.next() emp = new Emp(); emp.setEmpno(rs.getInt(1); emp.setEname(rs.getStri

30、ng(2); emp.setJob(rs.getString(3); emp.setHiredate(rs.getDate(4); emp.setSal(rs.getFloat(5); all.add(emp); this.pstmt.close(); catch (SQLException e) e.printStackTrace(); return all; public Emp findById(int empno) Emp emp = null; String sql = select empno,ename,job,hiredate,sal from emp where empno=

31、?; try this.pstmt = this.conn.prepareStatement(sql); this.pstmt.setInt(1, empno); ResultSet rs = this.pstmt.executeQuery(); if(rs.next() emp = new Emp(); emp.setEmpno(rs.getInt(1); emp.setEname(rs.getString(2); emp.setJob(rs.getString(3); emp.setHiredate(rs.getDate(4); emp.setSal(rs.getFloat(5); thi

32、s.pstmt.close(); catch (SQLException e) e.printStackTrace(); return emp; /操作接口-dao接口类package info.haowei.Dao.dao;import java.util.List;import info.haowei.Dao.vo.Emp;public interface IEmpDAO public boolean doCreate(Emp emp); public ListfindAll(String keyword); public Emp findById(int empno);/主函数类pack

33、age info.haowei.Dao.test;import java.util.Date;import java.util.Iterator;import java.util.List;import info.haowei.Dao.factory.DAOFactory;import info.haowei.Dao.vo.Emp;public class DAOTest public static void main(String args) /* * 插入 Emp emp = null; for(int x = 0 ; x 5; x+ ) emp = new Emp(); emp.setE

34、mpno(1000+x); emp.setEname(zhw+x); emp.setJob(coding +x); emp.setHiredate(new Date(); emp.setSal(500+x); DAOFactory.getIEmpDAOInstance().doCreate(emp); */ Listall = DAOFactory.getIEmpDAOInstance().findAll(); Iteratoriter = all.iterator(); while(iter.hasNext() Emp emp = iter.next(); System.out.printl

35、n(emp.getEmpno()+ +emp.getEname(); 最简单的Web部件和最复杂的在线电子商务Web站点具有一个共同点:它们都要处理数据。大量的编程都涉及数据的访问和操作。随着Intemet的发展、廉价存储设备应用数量的大量增长、对分析论的更深入理解以及对信息访问的更大期待,数据以更加有趣和独特的方式受到影响。数据访问对象设计模式的目的是帮助构造出能够容易地、透明地处理所有这些数据的对象。数据访问对象模式的额外优点是提供数据库抽象层。现在,应用程序的主要处理代码不再需要知道数据库引擎或表关系。调用这种对象的公共方法会返回任何数据类型,并且不用考虑内在SQL所需的类型。使用将非规

36、格化表与另一个表相连接以提供特定结果集的关系数据库结构能够很好地说明这个问题,如果数据库管理员将非规格化表结构修改为完全规格化的,那么遍布应用程序中所有模块的每条SQL语句都需要被修改为添加额外的连接表。如果使用数据访问对象,那么就只需要编辑提供该信息的方法。再来看一下实际表结构发生变化的情况:对一个列的命名可能发生变化,或者可能添加额外的列。同样地,需要编辑代码的仍然是数据访问对象。SQL纯粹主义者会坚决主张添加的表列应当完全不影响査询,他们认为应当使用SQL语句中的指定列。我同意上述观点。然而,如果列名发生变化。这种做法将毫无用处。如果编程人员没有釆用数据访问对象设计模式,那么总是会出现问

37、题.将这些对象类型的全部能力与易于使用相对比,无疑添加更多功能的诱惑占了统治地位.不过,我更倾向于数据访问对象中的简单性。千万不要添加未经证明或不需要的额外功能。管理数据访问对象类中简单性的一个好方法是创建父-子关系。首先,创建一个基本的父对象。这个对象应当负责数据库连接、抽象地执行查询以及与子对象通信。使用数椐访问对象设计模式时,最好开始就将一对一关系的了类与数据库中的表相关联,这些子类具有必不可少的信息,如表名和主键。此外,子类可能包含一些特定的公共方法,这些方法通过只对子类有意义的方式来执行父类的査询。例如,名为userAddress的子类可能包含一个getAddressesByZip(

38、)方法。将该方法放入父DAO类是毫无邀辑意义的,并且会破坏这个父类希望实现的抽象性。处理引用特定数据库信息的实体时,最好的做法是创建一个数据访问对象。5-2 UML如图5-1所示,该UML图详细说明了一个使用数据访问对象设计模式的类设计,进一步的阐述如下所示1.BaseDAO类是tableNameDAO类扩展的一个抽象类,它具有连接数据源的私有方法connectToDB(),这个方法存储私有实例变量dbConnection中的接BaseDAO 类还包含两个公共方法fetch()和update(),2.fetch()方法期望接收名为keyltem的参数,该参数引用希望返回的数据源的主标识符。这个

39、方法会执行正常的数据库调用并返回结果集。3.update()方法期望接收名为keyedUpdateObject的参数,该参数是一个对象或数组,包含对数据库进行更新的键和值.在这个函数中,列和值被抽取出来并应用更新.4.tableNameDAO类直接关联数据库中的表。 tableName变量存储实际的表名,这个私存变量被用于创建fetch()和update()方法中的数据库调用。作为数据访问所具有的、不同于基对象的额外功能示例,searchBySpecificKey()函数也出现在UML图中,这个方法期望接收变量key,它会创建对父数据访问对象的适当数据库调用组合,从而获取指定的返冋样式。5.3

40、代码示例这个示例关注的是一个用户实体。MySQL数据库拥有一条记录,该记录包含对每个用户来说都是具体和特有的信息.这种功能性必须允许我们通过用户的主键或对用户名称的 査找返回一个用户。此外,我们必须能够对用户实体记彔的任意字段执行更新操作。考虑到上述需求,我们需要使用两个类。第一个类应当是基本数据访问对象类,它具有获取和更新数据的方法,如下所示:abstract class baseDAOprivate $_connection;public function _construct()$this-_connectToDB (DB_USER, DB_PASS, DB_HOST, DB_DATAB

41、ASE);private function _connectToDB($user, $pass, $host, $database)$this-_connection = mysql_connect($host, $user, $pass); mysql_select_db($database, $this-_connection);public function fetch($value, $key = NULL)if (is_null($hey)$key = $this-_primaryKey;$sql = select * from $this-_tableName where $key

42、 = $value; $results = mysql_query($sql,$this-_connection);$rows = array ();while ($result = mysql_fetch_array($results) $rows = $result;return $rows;)public function update ($keyedArray)$sql = update $this-_tableName set “;$updates = array ();foreach ($keyedArray as $column=$value)$updates=”$column=$value “;$sql .= implode(, $updates);$sql .= where $this-_primaryKey = $keyedArr

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论