Kira-2006
-仅仅是一阵风也罢了,偏偏是这样永恒, 仅仅是一场梦也罢了,偏偏是如此的真实,
BlogJava
首页
新随笔
新文章
联系
聚合
管理
posts - 4,comments - 7,trackbacks - 0
<
2024年12月
>
日
一
二
三
四
五
六
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
常用链接
我的随笔
我的文章
我的评论
我的参与
最新评论
留言簿
(2)
给我留言
查看公开留言
查看私人留言
随笔档案
(3)
2008年4月 (2)
2006年3月 (1)
文章分类
(8)
design pattern
hibernate(6)
hsql(2)
java
文章档案
(10)
2008年5月 (4)
2008年4月 (4)
2006年9月 (1)
2006年3月 (1)
中国通信建设集团设计院有限公司第三分公司
中国通信建设集团设计院有限公司第三分公司
搜索
最新评论
1. re: Hibernate---SQL中datetime的映射[未登录]
aaa
--s
2. re: hsqldb编写批处理文件启动自己创建的数据库
评论内容较长,点击标题查看
--悬殊
3. re: Hibernate---SQL中datetime的映射
type="timestamp"
--cwjcsu@126.com
4. re: myeclipse自带Struts缺少jar文件,datasource配置
@隔叶黄莺
容器的数据源是什么意思呀?如果在struts1.3中手工加入数据源,会出错吗?
--tayoto
5. re: myeclipse自带Struts缺少jar文件,datasource配置
Struts 不建议在 struts-config.xml 中配置数据源,用容器的数据源吧。
所以 Struts1.3开始废除了在struts-config.xml中配置数据源。
--隔叶黄莺
阅读排行榜
1. Hibernate---SQL中datetime的映射(2736)
2. myeclipse自带Struts缺少jar文件,datasource配置(1253)
3. 一个计算机系学生的困惑?(340)
评论排行榜
1. Hibernate---SQL中datetime的映射(2)
2. myeclipse自带Struts缺少jar文件,datasource配置(2)
3. 一个计算机系学生的困惑?(2)
深入浅出Hibernate笔记--1.2.1持久化设计与解耦
解耦合的设计目标:
1. 应用层解耦合--应用逻辑与数据逻辑相分离。
2. 资源层解耦合--逻辑结构与物理结构相分离。
DAO模式:
即Data Accessor模式和Active Domain Object模式。
Data Accessor模式:实现数据访问和业务逻辑的分离。
Active Domain Object:实现了业务数据的对象化封装。
Domain Object:简单来讲就是对领域内涉及的各个数据对象,反映到代码,就是一个拥有相关属性的getter,setter方法的java Bean。
DAO模式通过对业务逻辑蹭提供数据抽象层接口,实现了以下目标:
1. 数据存储逻辑的分离:通过对数据访问逻辑进行抽象,为上层结构提供抽象化的数据访问接口。
2. 数据访问底层实现的分离:数据访问划分为抽象层和实现层,从而分离了数据使用和数据访问的底层实现细节。
3. 资源管理和调用的分离。
4.数据抽象:DAO模式通过对底层数据的封装,为业务层提供了一个面向对象的接口,使得业务逻辑开发人员可以面向业务中的实体进行编程。
DAO = Data+Accessor+Domain Object
DAO模式的进一步改良
Factory模式的引入:
由于需要针对不同的数据库访问机制分别提供各个版本的Data Accessor实现,自然我们会想到通过java interface定义一个调用接口,然后针对这个调用接口实现不同数据库的Data Accessor。通过接口作为调用界面和实现规范,可以避免对具体实现的依赖。
public
interface
CustomerDAO
{
public
Customer getCustomer(String custID);
public
void
save(Customer customer);
}
作为最常见的创建模式,Factory模式在这里起到连接接口和实现的桥梁作用,通过Factory模式,我们可以根据具体的需要加载相应的实现,并将此实现作为所对应接口的一个实例提供给业务层使用。
CustomerDAO custDAO
=
(CustomerDAO)DAOFactory.getDAO(CustomerDAO.
class
);
Customer customer
=
custDAO.getCustomer(custoemrID);
业务逻辑层通过接口调用底层实现,具体的DAO实现类不会出现在我们的业务代码中。而具体实现类在配置文件中加以配置,之后DAOFactory.getDAO方法通过读取配置文件获得当前我们期望使用的实现类的类名,再通过java Class动态加载机制加载返回。
从而我们的代码不依赖于某个特定的实现类,只需要在部署的时候在配置文件中指定当前采用的实现类即可。
public
class
DAOFactory
{
private
static
HashMap daoMap
=
null
;
//
根据指定的Class来获取DAO实例
public
static
Object getDAO(Class daoInterface)
{
initial();
Object dao
=
daoMap.get(daoInterface);
if
(
null
==
dao)
{
throw
new
DAOException(
"
No implementation found of DAO interface =>
"
+
daoInterface.getName());
}
return
dao;
}
//
初始化DAOFactory,加载DAO interface和
//
implementation到daoMap中
public
static
sychronized
void
initial()
{
if
(
null
==
daoMap)
{
//
根据配置文件中加载DAO实现配置
daoMap
=
DAOConfig.load();
}
}
}
//
DAOConfig类实现了配置文件的读取功能,并根据配文
//
件中的内容加载指定的接口和实现
public
class
DAOConfig
{
private
static
Logger logger
=
LogManager.getLogger(DAOConfig.
class
);
private
static
final
String DAO_CONFIG_FILE
=
"
dao.xml
"
;
private
static
final
String DAO_CONFIG_SECTION
=
"
DAO
"
;
public
static
synchronized
HashMap load()
{
HashMap map
=
new
HashMap();
JFigLocator jfigLocator
=
JFig.getInstance(jfigLocator);
Properties prop
=
daoConfig.getSectionAsProperties(DAO_CONFIG_SECTION);
Enumeration enumSection
=
prop.Keys();
while
(enumSection.hasMoreElements())
{
String daoIface
=
(String)enumSectioni.nextElement();
String daoImpl
=
(String)prop.getProperty(daoIface);
try
{
Class iface
=
ClassToolKit.loadClass(daoIface);
Class impl
=
ClassToolKit.loadClass(daoImpl);
//
将接口作为索引,实现作为值。
map.put(iface,impl);
}
catch
(ClassNotFoundException e)
{
logger.debug(
"
No Class Found =>
"
+
e);
}
}
return
map;
}
}
ClassToolKit.loadClass方法实现了类文件的动态加载:
public
class
ClassToolKit
{
public
static
Class loadClass(String className)
throws
ClassNotFoundException
{
Class cls
=
null
;
try
{
//
首先尝试用当前ClassLoader加载
cls
=
Thread.currentThread().getContextClassLoader().loadClass(className);
}
catch
(Exception e)
{
e.printStackTrace();
}
if
(cls
==
null
)
{
//
如果通过当前ClassLoader加载失败,使
//
用系统ClassLoader加载
cls
=
Class.forName(className);
}
return
cls;
}
}
这样,通过接口与实现的分离,并结合DAOFactory动态加载实现类,我们就实现了底层访问实现的参数化配置功能。从而为增强产品的部署能力提供了强有力的支持。
经过Factory模式的改造,业务层代码进行相应的修改:
public
BigDecimal calcAmount(String customerID,BigDecimal amount)
{
//
根据客户ID获得客户记录
CustomerDAO customerDAO
=
(CustomerDAO)DAOFactory.getDAO(CustomerDAO.
class
);
Customercustomer
=
customerDAO.getCustomer(customerID);
//
根据客户等级获得打折比率
PromotionDAO promoDAO
=
(PromotionDAO)DAOFactory.getDAO(PromotionDAO.
class
);
Promotion promotion
=
promoDAO.getPromotion(customer.getLevel());
//
累计客户总消费额,并更新数据库
customer.setSumAmount(customer.getSumAmount().add(amount));
customerDAO.save(customer);
//
返回打折后金额
return
amount.multiply(promotion.getRatio());
}
这段代码中混杂了数据访问层的内容,如DAOFactory.getDAO方法的调用。
Proxy模式的引入
为了保持业务逻辑代码的简洁,将Factory模式带来的Bad Smell排除在系统外,引入Proxy模式。
Proxy模式的作用:通过提供一个中间层(Proxy),将上层调用接口与下层实现相衔接。
经过Proxy模式改进后的业务层代码:
public
BigDecimal calcAmount(String customerID,BigDecimal amount)
{
Customer customer
=
CustomerProxy.getCustomer(customerID);
Promotion promotion
=
PromotionProxy.getPromotion(customer.getLevel());
customer.setSumAmount(customer.getSumAmount.add(amount));
CustomerProxy.save(customer);
return
amount.multiply(promotion.getRatio());
}
public
class
CustomerProxy
{
//
get Customer Object by CustomerID
public
static
Customer getCustomer(String customerID)
{
customerDAO custDAO
=
(CustomerDAO)DAOFactory.getDAO(CustomerDAO.
class
);
return
custDAO.getCustomer(customerID);
}
//
Save Customer Object to DataBase
public
static
void
save(Customer customer)
{
CustomerDAO custDAO
=
(CUstomerDAO)DAOFactory.getDAO(CustomerDAO.
class
);
custDAO.save(customer);
}
}
posted on 2008-05-02 19:33
Kira-2006
阅读(392)
评论(0)
编辑
收藏
所属分类:
hibernate
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
Chat2DB
C++博客
博问
管理
相关文章:
深入浅出Hibernate读书笔记--Hibernate常见优化策略
深入浅出Hibernate学习笔记--Criteria Query
深入浅出Hibernate学习笔记--数据关联
深入浅出Hibernate笔记--1.2.1持久化设计与解耦
Hibernate生成器