当前位置:首页 » 软件设计 » dao设计

dao设计

发布时间: 2021-01-21 23:47:09

⑴ 什么是DAO设计模式

DAO设计模式学习冲刺(8个月) 2009-04-07 18:04 阅读88 评论0 字号: 大大 中中 小小 DAO设计模式 DAO(Data Access Object)模式实际上是两个模式的组合,即Data Accessor 模式和 Active Domain Object 模式,其中 Data Accessor 模式实现了数据访问和业务逻辑的分离,而Active Domain Object 模式,其中Data Accessor模式实现了数据访问和业务逻辑的分离,而Active Domain Object 模式实现了业务数据的对象化封装,一般我们将这两个模式组合使用,因此,考虑到这些因素,这里将其作为同一个主题加以讨论。如图展示了DAO模式的实现层次。

DAO模式通过对业务层提供数据抽象层接口,实现了以下目标:

1. 数据存储逻辑的分离
通过对数据访问逻辑进行抽象,为上层机构提供抽象化的数据访问接口。业务层无需关心具体的select,insert,update操作,这样,一方面避免了业务代码中混杂JDBC调用语句,使得业务落实实现更加清晰,另一方面,由于数据访问几口语数据访问实现分离,也使得开发人员的专业划分成为可能。某些精通数据库操作技术的开发人员可以根据接口提供数据库访问的最优化实现,而精通业务的开发人员则可以抛开数据曾德繁琐细节,专注于业务逻辑编码。

2. 数据访问底层实现的分离
DAO模式通过将数据访问计划分为抽象曾和实现曾,从而分离了数据使用和数据访问的地称实现细节。这意味着业务层与数据访问的底层细节无关,也就是说,我们可以在保持上层机构不变得情况下,通过切换底层实现来修改数据访问的具体机制,常见的一个例子就是,我们可以通过仅仅替换数据访问曾实现,将我们的系统部署在不同的数据库平台之上。

3. 资源管理和调度的分离
在数据库操作中,资源的管理和调度是一个非常值得关注的主题。大多数系统的性能瓶颈往往并非集中于业务逻辑处理本身。在系统涉及的各种资源调度过程中,往往存在着最大的性能黑洞,而数据库作为业务系统中最重要的系统资源,自然也成为关注的焦点。DAO模式将数据访问逻辑从业务逻辑中脱离开来,使得在数据访问层实现统一的资源调度成为可能,通过数据库连接池以及各种缓存机制(Statement Cache,Data Cache等,缓存的使用是高性能系统实现的一个关键所在)的配合使用,往往可以保持上层系统不变的情况下,大幅度提升系统性能。

4.数据抽象
在直接基于JDBC调用的代码中,程序员面对的数据往往是原始的RecordSet数据集,诚然这样的数据集可以提供足够的信息,但对于业务逻辑开发过程而言,如此琐碎和缺乏寓意的字段型数据实在令人厌倦。
DAO 模式通过对底层数据的封装,为业务曾提供一个面向对象的接口,使得业务逻辑开发员可以面向业务中的实体进行编码。通过引入DAO模式,业务逻辑更加清晰,且富于形象性和描述性,这将为日后的维护带来极大的便利。试想,在业务曾通过Customer.getName方法获得客户姓名,相对于直接通过SQL语句访问数据库表并从ResultSet中获得某个字符型字段而言,哪种方式更加易于业务逻辑的形象化和简洁化?

空洞地谈些理论固然没有什么价值,我们需要看到的是通过对应用设计模式之后,我们的代码到底有怎样的改观,进而才能对设计带来的优劣有所感悟。下面让我们来看看代码:

[code]Public BigDecimal calcAmount(String customerID,BigDecimal amount){ //根据客户ID获得客户记录 Customer customer = CustomerDAO.getCustomer(customerID); //根据客户登记获得打折规则 Promotion promotion = PromotionDAO.getPromotion(customer.getLevel()); //累积客户总消费额,并保存累计结果 Customer.setSumAmount(customer.getSumAmount().add(amount)); CustomerDAO.save(customer); //返回打折后金额 Return amount.multiply(promotion.getRatio()); }[/code]这样的代码相信已经足够明晰,即使对于缺乏数据库技术基础的读者也可以轻松阅读。

从上面这段代码中,我们可以看到,通过DAO模式对各个数据库对象进行封装,我们对业务层屏蔽了数据库访问的底层实现,业务曾仅包含与本领域相关的逻辑对象和算法,这样对于业务逻辑开发人员(以及日后专注于业务逻辑的代码阅读者)而言,面对的是一个简洁明快的逻辑实现结构。业务层的开发和维护将变得更加简单。
DAO模式中,数据库访问层实现被隐藏到Data Accessor中,前面说过,DAO模式实际上是两个模式的组合,即Data Accessor 和 Domain Object模式。
何谓 Data Accessor?即将数据访问的实现机制加以封装,与数据的使用代码相分离,从外部来看,Data Accessor 提供了黑盒式的数据存取接口。

Domain Object则提供了对所面向领域内对象的封装。
从某种意义上,我们可以这么理解:
[code]Data Accessor object (DAO) =Data +Accessor + domain object[/code]

这个等式自左向右,形象地描述了设计分离的3个层次。
现在,对于上面的例子,来看看业务层后所隐藏的实现细节:
首先,我们这个计算打折后金额的业务过程中,涉及了两个业务对象,即客户对象Customer,和促销规则对象Promotion。自然,这两个对象也就成为了此业务领域(Business Domain)中的Domain Object,所谓Domain Object,简单来讲就是对领域内(Domain)涉及的各个数据对象,反映到代码,就是一个拥有相关属性的getter,setter方法的JavaClass(Java Bean)

以Customer和CustomerDao为例,实现代码如下(Promotion 和 PromotionDAO的实现代码与此类似):

DAO 模式的进一步改良

上面的例子中我们通过DAO模式实现了业务路基与数据逻辑的分离。对于专项开发(为特定客户环境指定的特定业务系统)而言,这样的分离设计差不多已经可以实现开发过程中业务层面与数据层面的相对独立,并且在实现复杂性与结构清晰性上达到较好的平衡。

然而,对于一个产品化的业务系统而言,目前的设计却仍稍显不足。相对专项原发的软件项目而言,软件产品往往需要在不同客户环境下及时部署。一个典型情况就是常见的论坛系统,一个商业论坛系统可能会部署在厂前上万个不同的客户环境中。诚然,由于java良好的跨平台支持,我们在操作系统之间大可轻易迁移,但在另外一个层面,数据库层,却仍然面临着平台迁移的窘境。客户可能已经购买了Oracle,SQLServer,Sybase 或者其他类型的 数据库。这就意味着我们的产品必须能部署在这些平台上,才能满足客户的需求。

对于我们现有的设计而言,为了满足不同客户的需求,我们可以实现针对不同类型数据库的
Data Accessor,并根据客户实际部署环境,通过类文件的静态替换来实现。显然,这样的实现方式在面对大量客户和复杂的部署环境时,将大大增加部署和维护工作的难度和复杂性。回忆一下“开闭原则”(Open-Close Principle) –对扩展开放,对修改封闭。我们应该采取适当的设计,将此类因素带来的变动(类的静态替换)屏蔽在系统之外。

为了实现跨数据库平台移植,或者展开来说,为了支持不同数据访问机制之间的可配置切换,我们需要在目前的DAO层引入Factory模式和Proxy模式。

这里所谓的不同数据访问机制,包括了不同数据库本身的访问实现,同时也包括了对于同一数据库德不同访问机制的兼容。例如我们的系统部署在小客户环境中,可能采用了基于JDBC的实现,而在企业环境中部署时,可能采用CMP作为数据访问的底层实现,以获得服务器集群上的性能优势(CMP具体怎样还有待商榷,这里暂且将其作为一个理由)。

Factory模式的引入

由于需要针对不同的数据库访问机制分别提供各自版本的Data Accessor实现,自然我们会想通过 Java Interface 定义一个调用接口,然后对这个调用接口实现不同数据库的 Data Accessor。通过以接口作为调用界面和实现规范,我们就可以避免代码只能给对具体实现的依赖。
对于例子中的CustomerDAO而言,我们可以抽象出如下的接口:
[code]Public interface CustomerDAO{ Public Customer getCustomer(String custID); Puboic void save (Customer customer); }[/code]

这里作为示例,提供了两个实现,一个基于MySql数据库,一个基于Oracle,对这里的简单示例而言,基于Oracle和MySql的实现并没有什么太大区别,只是为了说明系统设计的结构。

作为最常用的创建模式,Factory模式在这里起到来接接口和实现的桥梁作用。通过Factory模式,我们可以根据具体需要加载相应得实现,并将此实现作为所对应接口的一个实例提供给业务层使用:
[code]CustomerDAO custDAO =(CustomerDAO)DAOFactory.getDAO(CustomerDAO.class); Customer customer = custDAO.getCustomer(customerID);[/code]

通过上面的代码我们可以看到,通过接口我们将具体的DAO实现从代码中分离。
也就是说,业务层通过接口调用底层实现,具体的DAO实现类不会出现在我们的业务代码中。而具体实现类在配置文件中加以配置,之后DAOFactory.getDAO方法通过读取配置文件获得当前我们期望使用的视线类的类名,再通过Java Class动态加载机制加载后返回。

从而我们的代码并不依赖于某个特定的实现类,只需要在部署的时候在配置文件中指定当前采用的实现类即可。
本例中,为了提高性能,避免每次调用都读取配置文件所引起的大量磁盘操作,采用了HashMap作为DAO缓存实现示例:
[code]package net.wanjin.lab.persistence.; import java.util.HashMap; public class DAOFactory { private static HashMap Map = null; /** * Return a implemetation instance of the specified DAO Interface * @return the DAO Implemmenation Class Instance */ public static Object getDAO(Class Interface){ initial(); Object = Map.get(Interface); if(null ==){ throw new DAOException("No Implementation found of DAO interface =>" +Interface.getName()); } return ; } /** * Initial the DAOFactory * Load DAO Interface and Implementation In Map for later use */ public static synchronized void initial(){ if(null==Map){ Map =DAOConfig.load();//根据配置文件加载DAO实现配置 } } }[/code]

[code]package net.wanjin.lab.persistence.; import java.util.Enumeration; import java.util.HashMap; import java.util.Properties; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; /** * DAOConfig 类实现了配置文件的读取功能,并根据配置文件中的内容加载制定的接口和实现类; * @author Administrator */ public class DAOConfig { private static Logger logger = LogManager.getLogger(DAOConfig.class); private static final String DAO_CONFIG_FILE=".xml"; private static final String DAO_CONFIG_SECTION="DAO"; /** * Load the DAO Interface_Implementation into a HashMap * @return */ public static synchronized HashMap load(){ HashMap map = new HashMap(); JFigLocator jfigLocator = new JFigLocator(DAO_CONFIG_FILE); JFigIF Config = JFig.getInstance(jfigLocator); Properties prop = Config.getSectionAsProperties(DAO_CONFIG_SECTION); Enumeration enumSection = prop.keys(); while(enumSection.hasMoreElements()){ String Iface =(String)enumSection.nextElement(); String Impl = prop.getProperty(Iface); try{ Class iface = ClassToolKit.loadClass(Iface); Class impl = ClassToolKit.loadClass(Impl); //将接口作为HashMap索引,实现类作为值 map.put(iface, impl); }catch(ClassNotFoundException e){ logger.debug("No Class Found"+e); } }//while enumSection return map; } }[/code[code]]//.xml 文件 <?xml version="1.0" encoding="UTF-8"?> <configuration> <section > <entry key="net.wanjin.lab.persistence..iface.CustomerDAO" value="net.wanjin.lab.persistence..impl.CustomerDAOImp_Mysql"/> <entry key="net.wanjin.lab.persistence..iface.PromotionDAO" value="net.wanjin.lab.persistence..impl.PromotionDAOImp_Mysql"/> </section> </configuration>[/code]

⑵ DAO属于一个设计模式吗

DAO是Data Access Object数据访问接口,数据访问:故名思义就是与数据库打交道。夹在业务逻辑与数据库资源中间。
DAO的功能:

1. DAO用来封装Data Source的..就比如,Connection conn = DAOFacotry.createConnection()..

就可以把Driver. URL. username, passpword这一些放在DAO中
以后要更改数据库的类型.比如要把MSSQL换成Oracle的话..只需要更改DAOFacory里面的getConnection()里面的Driver.URL.之类的..
2. DAO也是把对数据库的操作(比如最基本的CRUD操作)全部封装在里面..

比如说你要你要插入一个新的用户..那么.在DAO中我们只需要提供一个insertUser(User user)这一个方法就可以了..具体的操作是在DAO中实现的...
那么对于要调用DAO的时候.我们只要知道insertUser(User)是用来插入一个新的用户...而不需要知道是如何实现的。

一般 DAO是与Abstract Factory模式一起来用的

⑶ 100分求基于DAO模式的UML设计实例

你先明白啥叫DAO,DAO不是模式

⑷ 在DAO中如何体现DAO设计模式

接口编程

⑸ DAO国际设计机构大家了解吗做过什么项目

项目,包括:中国金融信息大厦、中国跨国采购会展中心、上海金山政府会议中心、广州大亚湾翡翠山城大酒店、上海浦东新区金桥商业中心、郑州亚新商务中心办公楼、上海旭辉国际虹桥商务中心办公楼、上海张江总部基地办公楼、重庆涪陵李渡新城、成都锦江198世界现代田园城市规划等。

DAO国际设计机构,是由美国斯道沃STOA建筑规划(中国)有限公司、上海陆道工程设计管理有限公司共同组建,为客户提供的多元化专业设计和管理的机构。在境外,设有包括休斯顿在内的6家分公司。在国内,除上海外,已设有成都、郑州分公司,并拟在武汉等城市增设分公司和办事处。

DAO国际设计机构拥有国际技术、人才和行业背景以及国家建设部批准的建筑工程设计综合甲级、城市规划乙级、市政工程乙级资质。2004年起,就致力于为客户提供全程一体化的综合解决方案。

发展至今,DAO国际设计机构已拥有一支近200名、由境内、外的建筑师、规划师、工程师、建筑管理专家组成的设计团队以及各类专业顾问团队。与美国第三大结构技术公司Desimone建立了长期战略合作关系。并致力于采用全程“BIM”技术为客户提供更优质的专业服务。

DAO国际设计机构提供策划研发、规划设计、建筑设计、市政设计、景观设计、室内设计、工程咨询、项目管理等建筑业综合服务。紧密的专业配合、国际的技术能力结合国内的资质背景,能为客户提供更全面、技术性更强的服务。机构承接过许多规模庞大、复杂度高的项目,先后与诸多知名地产开发企业、跨国公司和政府部门建立了长期的战略合作关系。服务的项目覆盖国内二十几个省份和四个直辖市。

DAO国际设计机构还长期专注城市可持续发展的研究。自2011年起,与中国低碳行动联盟合作成立“中国低碳城市设计研究院”,并成为“中国低碳行动联盟”指定设计单位。

⑹ 在DAO中如何体现DAO设计模式

sessionfactory!

⑺ java 中 层怎么设计

package ;

import java.util.List;
import vo.*;

public interface IUsersDAO {
//按姓名查询
public List<Users> findUsersByName(String uname) throws Exception;
//查询所有用户
public List<Users> findAllUsers() throws Exception;
//按id查询
public Users findUsersById(int id)throws Exception;
//修改操作
public boolean UsersUpdate(Users usr)throws Exception;

//增加操作
//public boolean doInsert(Person per)throws Exception;
//修改操作
//public boolean doUpdate(Person per)throws Exception;
//删除操作
//public boolean doDelete(int id)throws Exception;
//按id查询
//public Person findById(int id)throws Exception;
//查询全部
//public List<Proct> findAllProct() throws Exception;
//模糊查询
//public List<Proct> findByLike(String cond)throws Exception;
}

⑻ 软件设计:DAO层该如何设计

黔 新华为你解答:

关于Dao层的设计我现在也还是有点模糊,大大小小的项目也做了五六个了,负责的数据库设计也有三四个了。

在对Dao层进行设计时采用过两种方案:

方案一:每一表对应一个Dao类(接口也可),每个Dao将完成对该表的增删改查以及业务上要求的查询操作。这么设计的话如果表很多的话将会产生很多类,并且将会出现大量重复的代码,因为每一个Dao中都将涉及到基础的增删改查。

方案二:写一个基础的类,可以完成基本的增删改查,其他的对于业务上有额外需求的表单独在写一个类,不过这个类只包括额外的功能。这里的基础类写的时候是需要严格注意的,因为采用的类似映射的实现,需要你把实体类设计的同表结构一摸一样,因为在该类中对数据库的增删改查的Sql语句就是通过对实体类类名以及对实体类类中属性的提取完形成的。

这里给出一个基本的添加方法(vb.net实现):
Public Class SqlDao : Implements Dal.IDao

Private SqlDr As SqlDataReader
Private SqlCon As SqlConnection
Private SqlCmd As SqlCommand
'从配置文件app.config中取得连接数据库的字符串
Private strConnect As String = ConfigurationManager.AppSettings("strCon")
'得到类名
Private strClassName As String
'得到类的类型
Private mType As Type
'得到属性集
Private mProS As PropertyInfo()

'在初始化方法中连接数据库
'Public Sub Init(ByVal obj As Object) Implements IDao.Init
' SqlCon = New SqlConnection(strConnect)

' '在构造函数中对必要类型进行初始化
' strClassName = TypeName(obj)
' mType = obj.GetType()
' mProS = mType.GetProperties
'End Sub

'连接数据库的一个私有方法
Private Function GetCon() As SqlConnection Implements IDao.GetCon
Try
If (SqlCon.State = ConnectionState.Closed) Then
SqlCon.Open()
End If
Catch ex As Exception
MsgBox("打开数据库时:" + ex.Message)
End Try

Return SqlCon
End Function

''' <summary>
''' 将对象添加到对应的表中,参数为对象,返回值为Int型,表示影响的行数
''' </summary>
''' <param name="Entity "></param>
''' <returns>Integer</returns>
''' <remarks></remarks>
Public Function AddObj(Of T)(ByVal Entity As T) As Integer Implements IDao.AddObj
Dim res As Integer = 0 '用来返回该操作影响的行数
'定义单个属性
Dim mPro As PropertyInfo
'定义sql参数
Dim para As SqlParameter
Dim strFields As String = ""
Dim strCondition As String = ""
Dim strSql As String = ""
For Each mPro In mProS
'该循环用来进行参数组合
'再添加时不用添加时间
strFields = CStr(Trim(mPro.GetValue(Entity, Nothing))) '获取属性值
If strFields <> "0" And strFields <> "00:00:00" And strFields <> "" Then

strSql = strSql + "@" + mPro.Name + ","
'组合形成字段名
strCondition = strCondition + mPro.Name + ","
End If
Next
'最后再插入最后的括号

strSql = Left(strSql, Len(strSql) - 1) + ")"
strCondition = Left(strCondition, Len(strCondition) - 1) + ")"
strSql = "INSERT INTO " + strClassName + " (" + strCondition + " VALUES (" + strSql
'MsgBox(strSql)
Try
Using sCmd As New SqlCommand(strSql, GetCon)
'设定执行方式
sCmd.CommandType = CommandType.Text
For Each mPro In mProS
'进行参数的赋值
'Dim stra As String = mPro.GetValue(obj, Nothing)
'一般的添加不用加入时间,除了下机表
strFields = CStr(Trim(mPro.GetValue(Entity, Nothing))) '获取属性值
If strFields <> "0" And strFields <> "00:00:00" And strFields <> "" Then
para = New SqlParameter("@" + mPro.Name, mPro.GetValue(Entity, Nothing))

sCmd.Parameters.Add(para)
End If
Next
res = sCmd.ExecuteNonQuery
End Using
Catch ex As Exception
MsgBox("进行对象添加时:" + ex.Message)
End Try
Return res '返回该操作影响的行数
End Function
End Class
这几天从网上也查了一些资料主要就是关于Dao层该如何设计的问题,最直接的设计方案就是每一个表对应一个Dao,说是代码重复太多,不过这样设计那些基本的代码是不用写的,都有现成的工具,直接根据表生成对应的增删改查。

不过因为需要重复的代码太多了,因此有人提出这种方法:
public interface BaseDao<T> {
public void create (T t);
public void delete (T t);
public void update (T t);
}

public interface WindDao extends BaseDao<Wind> {
public void other (Wind wind);
}
将基本的增删改查通过泛型放置到一个基础的接口中,其他的只需实现该接口,如果有额外的需求便可自行添加方法。这可谓一个典型的继承的应用。不过说实话,这种方法也不能使代码量减少。

⑼ 在DAO中如何体现DAO设计模式

把对象的基本CRUD操作封装到一个DAO中就是这种设计模式

⑽ 求教java高手:什么是DAO设计模式,听老师说DAO设计模式通常会和工厂设计模式、代理设计模式一起使用,

class User {
private String name;
private int age;
public void setName(String name){
this.name=name;
}
public void setAge(int age){
this.age=age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
}
interface UserDAO {
public boolean doCreate(User user)throws Exception;
}
class UserDAOImpl implements UserDAO {
private String str=null;
public UserDAOImpl(String str){
this.str=str;
}
public boolean doCreate(User user)throws Exception{
boolean flag=false;
try{
System.out.println("真实主题类的数据库增加操作");
}catch(Exception e){
e.printStackTrace();
}finally{

}
return flag;
}
}
class UserDAOProxy implements UserDAO {
private UserDAOImpl =null;
private String str=null; //此处其实应该传入一个数据库的连接到真实主题类的,不过这里只是个演示,所有以字符串的形式传了进去
public UserDAOProxy(){
this.str=new String();
this.=new UserDAOImpl(this.str);
}
public boolean doCreate(User user)throws Exception{
boolean flag=true;
System.out.println("代理类的操作,打开数据库,同时取得真实主题类的实例去调用真实的数据层操作");
try{
this..doCreate(user);
}catch(Exception e){
e.printStackTrace();
}finally{
System.out.println("代理类的操作,调用完真实主题类的操作,同时关闭数据库");
}
return flag;
}
}
class UserDAOFactory {
public static UserDAO getUserDAONewInstance(){
System.out.println("通过工厂类取得代理类的实例去调用代理类的操作。");
return new UserDAOProxy();
}
}
public class FactoryDemo {
public static void main(String args[])throws Exception{
User user=new User();
user.setName("jhjjs");
user.setAge(20);
UserDAOFactory.getUserDAONewInstance().doCreate(user);
}
}
lz看下吧,刚做的

热点内容
美发店认证 发布:2021-03-16 21:43:38 浏览:443
物业纠纷原因 发布:2021-03-16 21:42:46 浏览:474
全国著名不孕不育医院 发布:2021-03-16 21:42:24 浏览:679
知名明星确诊 发布:2021-03-16 21:42:04 浏览:14
ipad大专有用吗 发布:2021-03-16 21:40:58 浏览:670
公务员协议班值得吗 发布:2021-03-16 21:40:00 浏览:21
知名书店品牌 发布:2021-03-16 21:39:09 浏览:949
q雷授权码在哪里买 发布:2021-03-16 21:38:44 浏览:852
图书天猫转让 发布:2021-03-16 21:38:26 浏览:707
宝宝水杯品牌 发布:2021-03-16 21:35:56 浏览:837