ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>成年人免费在线视频,亚洲成a人v欧美综合天堂下载,精品久久久久久久一区二区蜜臀http://www.aygfsteel.com/os586/category/12511.html态度军_®šä¸€åˆ‡ï¼Œæ€æƒ³å†›_®šå‡ø™µ\zh-cnThu, 21 Jun 2007 14:07:12 GMTThu, 21 Jun 2007 14:07:12 GMT60Hibernate的类型怎样映射数据库中字段的自定义¾cÕdž‹http://www.aygfsteel.com/os586/archive/2007/06/21/125586.html水煮三国水煮三国Thu, 21 Jun 2007 07:48:00 GMThttp://www.aygfsteel.com/os586/archive/2007/06/21/125586.htmlhttp://www.aygfsteel.com/os586/comments/125586.htmlhttp://www.aygfsteel.com/os586/archive/2007/06/21/125586.html#Feedback1http://www.aygfsteel.com/os586/comments/commentRss/125586.htmlhttp://www.aygfsteel.com/os586/services/trackbacks/125586.html我在数据库中自定义了数据¾cÕdž‹åQšå¦‚UserName,其实它就是一个基本数据类型:varchar(12)çš„ã€? 但是˜q™ç§è‡ªå®šä¹‰æ•°æ®ç±»åž‹åœ¨hibernate当中我们该怎样˜q›è¡Œæ•°æ®¾cÕdž‹çš„æ˜ ž®„?

水煮三国 2007-06-21 15:48 发表评论
]]>
再论Domaion Object [From JavaEye]http://www.aygfsteel.com/os586/archive/2006/10/19/76082.html水煮三国水煮三国Thu, 19 Oct 2006 02:01:00 GMThttp://www.aygfsteel.com/os586/archive/2006/10/19/76082.htmlhttp://www.aygfsteel.com/os586/comments/76082.htmlhttp://www.aygfsteel.com/os586/archive/2006/10/19/76082.html#Feedback0http://www.aygfsteel.com/os586/comments/commentRss/76082.htmlhttp://www.aygfsteel.com/os586/services/trackbacks/76082.html既然大家都统一了观点,那么ž®±æœ‰äº†ä¸€ä¸ªå¾ˆå¥½çš„讨论问题的基¼‹€äº†ã€‚Martin Fowlerçš„Domain ModelåQŒæˆ–者说我们的第二种模型éšùN“是完¾ŸŽæ— ¾~ºçš„吗?当然不是åQŒæŽ¥ä¸‹æ¥æˆ‘就要分析一下它的不­‘»I¼Œä»¥åŠå¯èƒ½çš„解军_Šžæ³•ï¼Œè€Œè¿™äº›éƒ½æ¥æºäºŽæˆ‘ä¸ªäh的实跉|Ž¢ç´¢ã€?/p>

在第二种模型中,我们可以清楚的把˜q?ä¸ªç±»åˆ†äØ“ä¸‰å±‚åQ?/p>

1、实体类层,即ItemåQŒå¸¦æœ‰domain logicçš„domain object
2、DAO层,即ItemDaoå’ŒItemDaoHibernateImplåQŒæŠ½è±¡æŒä¹…化操作的接口和实现¾c?
3、业务逻辑层,即ItemManageråQŒæŽ¥å—容器事务控åˆÓž¼Œå‘Web层提供统一的服务调ç”?/p>

在这三层中我们大家可以看刎ͼŒdomain objectå’ŒDAO都是非常½E›_®šçš„层åQŒå…¶å®žåŽŸå› ä¹Ÿå¾ˆç®€å•ï¼Œå› äØ“domain object是映ž®„数据库字段的,数据库字ŒDµä¸ä¼šé¢‘¾Jå˜åŠ¨ï¼Œæ‰€ä»¥domain object也相对稳定,而面向数据库持久化编½E‹çš„DAO层也不过ž®±æ˜¯CRUD而已åQŒä¸ä¼šæœ‰æ›´å¤šçš„èŠ±æ øP¼Œæ‰€ä»¥ä¹Ÿå¾ˆç¨³å®šã€?/p>

问题ž®±åœ¨äºŽè¿™ä¸ªå……当business workflow facade的业务逻辑对象åQŒå®ƒçš„变动是相当频繁的ã€?span style="COLOR: red">业务逻辑对象通常都是无状态的、受事务控制的、Singleton¾c?/span>åQŒæˆ‘们可以考察一下业务逻辑对象都有哪几¾cÖM¸šåŠ¡é€»è¾‘æ–ÒŽ³•åQ?/p>

½W¬ä¸€¾c»ï¼šDAO接口æ–ÒŽ³•的代ç?/span>åQŒå°±æ˜¯ä¸Šé¢ä¾‹å­ä¸­çš„loadItemByIdæ–ÒŽ³•å’ŒfindAllæ–ÒŽ³•ã€?/p>

ItemManager之所以要代理˜q™ç§¾c»ï¼Œç›®çš„æœ‰ä¸¤ä¸ªï¼šå‘Web层提供统一的服务调用入口点和给持久化方法增加事务控制功èƒ?/span>。这两点都很å®ÒŽ˜“理解åQŒä½ ä¸èƒ½æ—¢ç»™Web层程序员提供xxxManageråQŒä¹Ÿ¾l™ä»–提供xxxDaoåQŒæ‰€ä»¥ä½ éœ€è¦ç”¨xxxManagerž®è£…xxxDaoåQŒåœ¨˜q™é‡ŒåQŒå……当了一个简单代理功能;而事务控制也是持久化æ–ÒŽ³•必须的,事务可能需要跨­‘Šå¤šä¸ªDAOæ–ÒŽ³•调用åQŒæ‰€ä»¥å¿…™åÀL”¾åœ¨ä¸šåŠ¡é€»è¾‘å±‚ï¼Œè€Œä¸èƒ½æ”¾åœ¨DAO层ã€?/p>

但是必须看到åQŒå¯¹äºŽä¸€ä¸ªå…¸åž‹çš„web应用来说åQŒç»å¤§å¤šæ•°çš„业务逻辑都是½Ž€å•çš„CRUD逻辑åQŒæ‰€ä»¥è¿™¿Uæƒ…况下åQŒé’ˆå¯Òޝä¸ªDAOæ–ÒŽ³•åQŒxxxManager都需要提供一个对应的ž®è£…æ–ÒŽ³•åQŒè¿™ä¸ä½†æ˜¯éžå¸¸æž¯ç‡¥çš„åQŒä¹Ÿæ˜¯ä×oäººæ„Ÿè§‰éžå¸æ€¸å¥½çš„ã€?/p>

½W¬äºŒ¾c»ï¼šdomain logic的方法代ç?/span>。就是上面例子中placeBidæ–ÒŽ³•。虽然Item已经有了placeBidæ–ÒŽ³•åQŒä½†æ˜¯ItemManager仍然需要封装一下Itemçš„placeBidåQŒç„¶åŽå†æä¾›ä¸€ä¸ªç®€å•封装之后的代理æ–ÒŽ³•ã€?/p>

˜q™å’Œ½W¬ä¸€¿Uæƒ…å†ëб»ä¼û|¼Œå…¶åŽŸå› ä¹Ÿä¸€æ øP¼Œä¹Ÿæ˜¯ä¸ÞZº†¾l™Web层提供一个统一的服务调用入口点和给隐式的持久化动作提供事务控制ã€?/p>

同样åQŒå’Œ½W¬ä¸€¿Uæƒ…å†µä¸€æ øP¼Œé’ˆå¯¹æ¯ä¸ªdomain logicæ–ÒŽ³•åQŒxxxManager都需要提供一个对应的ž®è£…æ–ÒŽ³•åQŒåŒæ äh˜¯æž¯ç‡¥çš„,令äh不爽的ã€?/p>

½W¬ä¸‰¾c»ï¼šéœ€è¦å¤šä¸ªdomain objectå’ŒDAO参与协作的business workflow。这¿Uæƒ…冉|˜¯ä¸šåŠ¡é€»è¾‘å¯¹è±¡çœŸæ­£åº”è¯¥å®Œæˆçš„èŒè´£ã€?/p>

在这个简单的例子中,没有涉及到这¿Uæƒ…况,不过大家都可以想像的出来˜q™ç§åº”用场景åQŒå› æ­¤ä¸å¿…ä‹D例说明了ã€?/p>

通过上面的分析可以看出,只有½W¬ä¸‰¾cÖM¸šåŠ¡é€»è¾‘æ–ÒŽ³•才是业务逻辑对象真正应该承担的职责,而前两类业务逻辑æ–ÒŽ³•都是“无奈之ä¸ä€ï¼Œä¸å¾—ä¸äØ“ä¹‹çš„äº‹æƒ…åQŒä¸ä½†æž¯ç‡¥ï¼Œè€Œä¸”令ähæ²®ä“áã€?/p>

分析完了业务逻辑对象åQŒæˆ‘们再回头看一下domain objectåQŒæˆ‘们要仔细考察一下domain logic的话åQŒä¼šå‘现domain logic也分ä¸ÞZ¸¤¾c»ï¼š

½W¬ä¸€¾c»ï¼šéœ€è¦æŒä¹…层框架隐式的实现透明持久化的domain logicåQŒä¾‹å¦‚Itemçš„placeBidæ–ÒŽ³•中的˜q™ä¸€å¥ï¼š

代码
						this
						.
						getBids
						().
						add
						(
						newBid
						);
				

上面已经着重提刎ͼŒè™½ç„¶˜q™ä»…仅只是一个Java集合的添加新元素的操作,但是实际上通过事务的控åˆÓž¼Œä¼šæ½œåœ¨çš„触发两条SQLåQšä¸€æ¡æ˜¯insert一条记录到bid表,一条是更新item表相应的记录。如果我们让Itemè„Þq¦»Hibernate˜q›è¡Œå•å…ƒ‹¹‹è¯•åQŒå®ƒž®±æ˜¯ä¸€ä¸ªå•¾U¯çš„Java集合操作åQŒå¦‚果我们把他加入到Hibernate框架中,他就会潜在的触发两条SQLåQ?span style="COLOR: red">˜q™å°±æ˜¯éšå¼çš„依赖于持久化的domain logicã€?
特别è¯äh³¨æ„çš„一ç‚ÒŽ˜¯åQšåœ¨æ²¡æœ‰Hibernate/JDO˜q™ç±»å¯ä»¥å®žçŽ°â€œé€æ˜Žçš„æŒä¹…åŒ–â€å·¥å…·å‡ºçŽîC¹‹å‰ï¼Œ˜q™ç±»domain logic是无法实现的ã€?

对于˜q™ä¸€¾c»domain logicåQŒä¸šåŠ¡é€»è¾‘å¯¹è±¡å¿…é¡»æä¾›ç›¸åº”çš„å°è£…æ–¹æ³•ï¼Œä»¥å®žçŽîCº‹åŠ¡æŽ§åˆ¶ã€?/p>

½W¬äºŒ¾c»ï¼šå®Œå…¨ä¸ä¾èµ–持久化的domain logicåQŒä¾‹å¦‚readonly例子中的TopicåQŒå¦‚下:

java代码
class Topic{
booleanisAllowReply(){
CalendardueDate=Calendar.getInstance();
dueDate.setTime(lastUpdatedTime);
dueDate.add(Calendar.DATE,forum.timeToLive);

Datenow=newDate();
returnnow.after(dueDate.getTime());
}
}

注意˜q™ä¸ªisAllowReplyæ–ÒŽ³•åQŒä»–和持久化完全不发生一丁点关系。在实际的开发中åQŒæˆ‘们同样会遇到很多˜q™ç§ä¸éœ€è¦æŒä¹…化的业务逻辑(主要发生在日期运½Ž—ã€æ•°å€ÆD¿½Ž—和枚ä‹D˜qç®—æ–šw¢)åQŒè¿™¿Udomain logic不管è„Þq¦»ä¸è„±¼›ÀL‰€åœ¨çš„æ¡†æž¶åQŒå®ƒçš„行为都是一致的。对于这¿Udomain logicåQŒä¸šåŠ¡é€»è¾‘å±‚åÆˆä¸éœ€è¦æä¾›å°è£…æ–¹æ³•ï¼Œå®ƒå¯ä»¥é€‚ç”¨äºŽä“Q何场合ã€?/p>

水煮三国 2006-10-19 10:01 发表评论
]]>
æ€È»“一下最˜q‘关于domain object以及相关的讨è®?[From:JAVAEYE]http://www.aygfsteel.com/os586/archive/2006/10/19/76070.html水煮三国水煮三国Thu, 19 Oct 2006 01:19:00 GMThttp://www.aygfsteel.com/os586/archive/2006/10/19/76070.htmlhttp://www.aygfsteel.com/os586/comments/76070.htmlhttp://www.aygfsteel.com/os586/archive/2006/10/19/76070.html#Feedback2http://www.aygfsteel.com/os586/comments/commentRss/76070.htmlhttp://www.aygfsteel.com/os586/services/trackbacks/76070.html在最˜q‘的围绕domain object的讨è®ÞZ¸­‹¹®çŽ°å‡ºæ¥äº†ä¸‰¿Uæ¨¡åž‹ï¼Œ(˜q˜æœ‰ä¸€äº›å…¶ä»–的旁枝åQŒä¸ä¸€ä¸€åˆ†æžäº?åQŒç»˜q‡ä¸€ç•ªè®¨è®ºï¼Œå„种问题逐渐清晰èµäh¥åQŒåœ¨˜q™é‡Œæˆ‘试囑ցšä¸€ä¸ªæ€È»“åQŒä¾¿äºŽå¤§å®¶äº†è§£å’ŒæŽŒæ¡ã€?/p>

½W¬ä¸€¿Uæ¨¡åž‹ï¼šåªæœ‰getter/setteræ–ÒŽ³•的纯数据¾c»ï¼Œæ‰€æœ‰çš„业务逻辑完全由business object来完æˆ?又称TransactionScript)åQŒè¿™¿Uæ¨¡åž‹ä¸‹çš„domain object被Martin Fowler¿UîC¹‹ä¸ºâ€œè‚÷血的domain object”。下面用举一个具体的代码来说明,代码来自Hibernateçš„caveatemptoråQŒä½†¾lè¿‡æˆ‘的改写åQ?/p>

一个实体类叫做ItemåQŒæŒ‡çš„æ˜¯ä¸€ä¸ªæ‹å–项ç›?
一个DAO接口¾cÕd«åšItemDao
一个DAO接口实现¾cÕd«åšItemDaoHibernateImpl
一个业务逻辑¾cÕd«åšItemManager(或者叫做ItemService)

java代码
						public
						class 
						Item
						implements
						Serializable
						{
						
private Long id = null ;
private int version ;
private String name ;
private User seller ;
private String description ;
private MonetaryAmount initialPrice ;
private MonetaryAmount reservePrice ;
private Date startDate ;
private Date endDate ;
private Set categorizedItems = new HashSet ();
private Collection bids = new ArrayList ();
private Bid successfulBid ;
private ItemState state ;
private User approvedBy ;
private Date approvalDatetime ;
private Date created = new Date ();
/ / getter / setteræ–ÒŽ³•省略不写åQŒé¿å…ç¯‡òq…太é•?/span>
}

java代码
						public
						interface
						ItemDao
						{
						
public Item getItemById ( Long id );
public Collection findAll ();
public void updateItem ( Item item );
}

ItemDao定义持久化操作的接口åQŒç”¨äºŽé𔼛ÀLŒä¹…化代码ã€?/p>

java代码
						public
						class 
						ItemDaoHibernateImpl
						implements
						ItemDao
						extends
						HibernateDaoSupport
						{
						
public Item getItemById ( Long id ) {
return ( Item ) getHibernateTemplate (). load ( Item . class , id );
}
public Collection findAll () {
return ( List ) getHibernateTemplate (). find (" from Item ");
}
public void updateItem ( Item item ) {
getHibernateTemplate (). update ( item );
}
}

ItemDaoHibernateImpl完成具体的持久化工作åQŒè¯·æ³¨æ„åQŒæ•°æ®åº“资源的获取和释放是在ItemDaoHibernateImpl里面处理的,每个DAOæ–ÒŽ³•调用之前打开SessionåQŒDAOæ–ÒŽ³•调用之后åQŒå…³é—­Sessionã€?Session攑֜¨ThreadLocal中,保证一‹Æ¡è°ƒç”¨åªæ‰“开关闭一‹Æ?

java代码
publicclass ItemManager{
privateItemDaoitemDao;
publicvoidsetItemDao(ItemDaoitemDao){this.itemDao=itemDao;}
publicBidloadItemById(Longid){
itemDao.loadItemById(id);
}
publicCollectionlistAllItems(){
returnitemDao.findAll();
}
publicBidplaceBid(Itemitem,Userbidder,MonetaryAmountbidAmount,
BidcurrentMaxBid,BidcurrentMinBid)throwsBusinessException{
if(currentMaxBid!=null&&currentMaxBid.getAmount().compareTo(bidAmount)>0){
thrownewBusinessException("Bid too low.");
}

//Auctionisactive
if(!state.equals(ItemState.ACTIVE))
thrownewBusinessException("Auction is not active yet.");

//Auctionstillvalid
if(item.getEndDate().before(newDate()))
thrownewBusinessException("Can't place new bid, auction already ended.");

//CreatenewBid
BidnewBid=newBid(bidAmount,item,bidder);

//PlacebidforthisItem
item.getBids().add(newBid);
itemDao.update(item);// 调用DAO完成持久化操�/span>
returnnewBid;
}
}

事务的管理是在ItemManger˜q™ä¸€å±‚完成的åQŒItemManager实现具体的业务逻辑。除了常见的和CRUD有关的简单逻辑之外åQŒè¿™é‡Œè¿˜æœ‰ä¸€ä¸ªplaceBid的逻辑åQŒå³™å¹ç›®çš„竞标ã€?/p>

以上是一个完整的½W¬ä¸€¿Uæ¨¡åž‹çš„½CÞZ¾‹ä»£ç ã€‚在˜q™ä¸ª½CÞZ¾‹ä¸­ï¼ŒplaceBidåQŒloadItemByIdåQŒfindAll½{‰ç­‰ä¸šåŠ¡é€»è¾‘¾lŸç»Ÿæ”‘Öœ¨ItemManager中实玎ͼŒè€ŒItem只有getter/setteræ–ÒŽ³•ã€?br />




½W¬äºŒ¿Uæ¨¡åž‹ï¼Œä¹Ÿå°±æ˜¯Martin Fowler指的rich domain object是下面这样子的:

一个带有业务逻辑的实体类åQŒå³domain object是Item
一个DAO接口ItemDao
一个DAO实现ItemDaoHibernateImpl
一个业务逻辑对象ItemManager

java代码
publicclass ItemimplementsSerializable{
// 所有的属性和getter/setteræ–ÒŽ³•同上åQŒçœç•?/span>
publicBidplaceBid(Userbidder,MonetaryAmountbidAmount,
BidcurrentMaxBid,BidcurrentMinBid)
throwsBusinessException{

//Checkhighestbid(canalsobeadifferentStrategy(pattern))
if(currentMaxBid!=null&&currentMaxBid.getAmount().compareTo(bidAmount)>0){
thrownewBusinessException("Bid too low.");
}

//Auctionisactive
if(!state.equals(ItemState.ACTIVE))
thrownewBusinessException("Auction is not active yet.");

//Auctionstillvalid
if(this.getEndDate().before(newDate()))
thrownewBusinessException("Can't place new bid, auction already ended.");

//CreatenewBid
BidnewBid=newBid(bidAmount,this,bidder);

//PlacebidforthisItem
this.getBids.add(newBid);// è¯äh³¨æ„è¿™ä¸€å¥ï¼Œé€æ˜Žçš„进行了持久化,但是不能在这里调ç”?span class="constant">ItemDaoåQŒItem不能对ItemDao产生依赖åQ?/span>

returnnewBid;
}
}

竞标˜q™ä¸ªä¸šåŠ¡é€»è¾‘è¢«æ”¾å…¥åˆ°Item中来。请注意this.getBids.add(newBid); 如果没有Hibernate或者JDO˜q™ç§O/R Mapping的支持,我们是无法实现这¿Ué€æ˜Žçš„æŒä¹…åŒ–è¡ŒäØ“çš„ã€‚ä½†æ˜¯è¯·æ³¨æ„åQŒItem里面不能去调用ItemDAOåQŒå¯¹ItemDAO产生依赖åQ?/p>

ItemDao和ItemDaoHibernateImpl的代码同上,省略�/p>

java代码
publicclass ItemManager{
privateItemDaoitemDao;
publicvoidsetItemDao(ItemDaoitemDao){this.itemDao=itemDao;}
publicBidloadItemById(Longid){
itemDao.loadItemById(id);
}
publicCollectionlistAllItems(){
returnitemDao.findAll();
}
publicBidplaceBid(Itemitem,Userbidder,MonetaryAmountbidAmount,
BidcurrentMaxBid,BidcurrentMinBid)throwsBusinessException{
item.placeBid(bidder,bidAmount,currentMaxBid,currentMinBid);
itemDao.update(item);// 必须昑ּçš„è°ƒç”?span class="constant">DAOåQŒä¿æŒæŒä¹…化
}
}

在第二种模型中,placeBid业务逻辑是放在Item中实现的åQŒè€ŒloadItemByIdå’ŒfindAll业务逻辑是放在ItemManager中实现的。不˜q‡å€¼å¾—注意的是åQŒå³ä½¿placeBid业务逻辑攑֜¨Item中,你仍焉™œ€è¦åœ¨ItemManager中简单的ž®è£…一层,以保证对placeBid业务逻辑˜q›è¡Œäº‹åŠ¡çš„ç®¡ç†å’ŒæŒä¹…åŒ–çš„è§¦å‘ã€?/p>

˜q™ç§æ¨¡åž‹æ˜¯Martin Fowler所指的真正的domain model。在˜q™ç§æ¨¡åž‹ä¸­ï¼Œæœ‰ä¸‰ä¸ªä¸šåŠ¡é€»è¾‘æ–ÒŽ³•åQšplaceBidåQŒloadItemByIdå’ŒfindAllåQŒçŽ°åœ¨çš„é—®é¢˜æ˜¯å“ªä¸ªé€»è¾‘åº”è¯¥æ”‘Öœ¨Item中,哪个逻辑应该攑֜¨ItemManager中。在我们˜q™ä¸ªä¾‹å­ä¸­ï¼ŒplaceBid攑֜¨Itemä¸?但是ItemManager也需要对它进行简单的ž®è£…)åQŒloadItemByIdå’ŒfindAll是放在ItemManager中的ã€?/p>

切分的原则是什么呢åQ?Rod Johnson提出原则是“case by case”,可重用度高的åQŒå’Œdomain object状态密切关联的攑֜¨Item中,可重用度低的åQŒå’Œdomain object状态没有密切关联的攑֜¨ItemManager中ã€?/p>

我提出的原则是:看业务方法是否显式的依赖持久化�/span>

Itemçš„placeBid˜q™ä¸ªä¸šåŠ¡é€»è¾‘æ–ÒŽ³•没有昑ּçš„对持久化ItemDao接口产生依赖åQŒæ‰€ä»¥è¦æ”‘Öœ¨Item中ã€?span style="COLOR: red">è¯äh³¨æ„ï¼Œå¦‚æžœè„Þq¦»äº†Hibernate˜q™ä¸ªæŒä¹…化框æžÓž¼ŒItem˜q™ä¸ªdomain object是可以进行单元测试的åQŒä»–不依赖于Hibernate的持久化机制。它是一个独立的åQŒå¯¿UÀL¤çš„,完整的,自包含的域对è±?/span>ã€?/p>

而loadItemByIdå’ŒfindAll˜q™ä¸¤ä¸ªä¸šåŠ¡é€»è¾‘æ–ÒŽ³•是必™åÀL˜¾å¼çš„å¯ÒŽŒä¹…化ItemDao接口产生依赖åQŒå¦åˆ™è¿™ä¸ªä¸šåŠ¡é€»è¾‘ž®±æ— æ³•完成。如果你要把˜q™ä¸¤ä¸ªæ–¹æ³•放在Item中,那么Itemž®±æ— æ³•脱¼›»Hibernate框架åQŒæ— æ³•在Hibernate框架之外独立存在ã€?br />


½W¬ä¸‰¿Uæ¨¡åž‹å°è±¡ä¸­å¥½åƒæ˜¯firebody或者是Archie提出çš?也有可能不是åQŒè®°ä¸æ¸…楚了)åQŒç®€å•的来说åQŒè¿™¿Uæ¨¡åž‹å°±æ˜¯æŠŠ½W¬äºŒ¿Uæ¨¡åž‹çš„domain objectå’Œbusiness object合二ä¸ÞZ¸€äº†ã€‚所以ItemManagerž®×ƒ¸éœ€è¦äº†åQŒåœ¨˜q™ç§æ¨¡åž‹ä¸‹é¢åQŒåªæœ‰ä¸‰ä¸ªç±»åQŒä»–们分别是åQ?/p>

ItemåQšåŒ…含了实体¾cÖM¿¡æ¯ï¼Œä¹ŸåŒ…含了所有的业务逻辑
ItemDaoåQšæŒä¹…åŒ–DAO接口¾c?
ItemDaoHibernateImplåQšDAO接口的实现类

ç”׃ºŽItemDaoå’ŒItemDaoHibernateImpl和上面完全相同,ž®Þqœç•¥äº†ã€?/p>

java代码
publicclass ItemimplementsSerializable{
// 所有的属性和getter/setteræ–ÒŽ³•都省ç•?/span>
privatestaticItemDaoitemDao;
publicvoidsetItemDao(ItemDaoitemDao){this.itemDao=itemDao;}

publicstaticItemloadItemById(Longid){
return(Item)itemDao.loadItemById(id);
}
publicstaticCollectionfindAll(){
return(List)itemDao.findAll();
}

publicBidplaceBid(Userbidder,MonetaryAmountbidAmount,
BidcurrentMaxBid,BidcurrentMinBid)
throwsBusinessException{

//Checkhighestbid(canalsobeadifferentStrategy(pattern))
if(currentMaxBid!=null&&currentMaxBid.getAmount().compareTo(bidAmount)>0){
thrownewBusinessException("Bid too low.");
}

//Auctionisactive
if(!state.equals(ItemState.ACTIVE))
thrownewBusinessException("Auction is not active yet.");

//Auctionstillvalid
if(this.getEndDate().before(newDate()))
thrownewBusinessException("Can't place new bid, auction already ended.");

//CreatenewBid
BidnewBid=newBid(bidAmount,this,bidder);

//PlacebidforthisItem
this.addBid(newBid);
itemDao.update(this);// 调用DAO˜q›è¡Œæ˜‘Ö¼æŒä¹…åŒ?/span>
returnnewBid;
}
}

在这¿Uæ¨¡åž‹ä¸­åQŒæ‰€æœ‰çš„业务逻辑全部都在Item中,事务½Ž¡ç†ä¹Ÿåœ¨Item中实现ã€?/p>

水煮三国 2006-10-19 09:19 发表评论
]]>
Pro Hibernate 3½W”记和小¾l“(2åQ‰ä¹‹½W¬ä¸€ç« Hibernate3介绍http://www.aygfsteel.com/os586/archive/2006/07/28/60487.html水煮三国水煮三国Fri, 28 Jul 2006 02:06:00 GMThttp://www.aygfsteel.com/os586/archive/2006/07/28/60487.htmlhttp://www.aygfsteel.com/os586/comments/60487.htmlhttp://www.aygfsteel.com/os586/archive/2006/07/28/60487.html#Feedback0http://www.aygfsteel.com/os586/comments/commentRss/60487.htmlhttp://www.aygfsteel.com/os586/services/trackbacks/60487.htmlPro Hibernate 3½W”记和小¾l“(2åQ‰ä¹‹½W¬ä¸€ç« Hibernate3介绍

/**
作者:Willpower
来源åQšRifoo TechnologyåQ?/font> http://www.rifoo.com åQ?br />æ—‰™—´åQ?006-05
备注åQšè{载请保留以上声明
**/


今天¾l§ç®‹½W¬ä¸€ç« çš„学习åQŒæˆ‘们先来看看EJBå’ŒHibernate的区别ã€?br />
ä¸ÞZ»€ä¹ˆä¸ç”¨EJB来存储,昄¡¤ºåQŒæŸ¥è¯¢æ•°æ®åº“中的数据呢?严格的说åQŒEJB服务器支持两¿Uç±»åž‹çš„æŒä¹…化,ž®±æ˜¯BEAN½Ž¡ç†çš„æŒä¹…化åQˆBMPåQ‰å’Œå®¹å™¨½Ž¡ç†çš„æŒä¹…化åQˆCMPåQ‰ã€‚在BMP中,Bean自己负责执行所有的SQL语句来完成存储和查询数据。换句话è¯ß_¼Œæˆ‘们自己要去¾~–写JDBC逻辑代码。另一斚w¢åQŒCMP是由容器来执行存储和‹‚€ç´¢bean数据的工作ã€?br />
我们˜q™é‡Œä¸é€‰æ‹©EJB的原因如下:
1 CMP实体bean需要和数据表一对一的映ž®?br />2 它们很慢
3 有时候要人工参与的去军_®šå“ªä¸€ä¸ªbean字段对应表的哪一åˆ?br />4 它们å¯ÒŽ–¹æ³•命名有要求
5 EJB的容器是重量¾U§çš„
6 它们和容器依赖强åQŒä¸å®ÒŽ˜“¿UÀL¤

下面看看Hibernate的特点:
1 不需要强制映ž®„一个POJOåˆîC¸€ä¸ªè¡¨åQŒä¸å¼ºåˆ¶ä¸€å¯¹ä¸€çš„å…³¾p?br />2 ž®½å¿«å¯åЍòq¶åŠ è½½å®ƒçš„é…¾|®æ–‡ä»¶æ—¶ä¼šå¯¹æ€§èƒ½æœ‰äº›è´Ÿè²åQŒä½†æ€Èš„来说åQŒå®ƒæ˜¯å¾ˆå¿«çš„工具
3 和容器没有强依赖åQŒå¾ˆæ–¹ä¾¿çš„ç§»æ¤?br />4 可以很轻杄¡š„处理serializable POJOs

以上只是½Ž€å•的列ä‹DåQŒè¿˜æœ‰å¾ˆå¤šç‰¹ç‚šwƒ½æ²¡æœ‰æåŠã€‚æ€ÖM¹‹åQŒHibernate在应用程序的持久层这一块是非常不错的框架。下面我们来看一个Hibernateçš„Hello world½E‹åºåQ?br />
Listing 1-4. Hibernate‹‚€ç´¢POJO的范例代ç ?br />
CODE:

public static Motd getMotd(int messageId)
                  throws MotdException
{
  SessionFactory sessions =
            new Configuration().configure().buildSessionFactory();
  Session session = sessions.openSession();
  Transaction tx = null;
  try {
    tx = session.beginTransaction();
    Motd motd =
            (Motd)session.get( Motd.class,
            new Integer(messageId));
    tx.commit();
    tx = null;
    return motd;
  } catch ( HibernateException e ) {
    if ( tx != null ) tx.rollback();
        log.log(Level.SEVERE, "Could not acquire message", e);
        throw new MotdException(
            "Failed to retrieve message from the database.",e);
  } finally {
    session.close();
  }
}


大家可以看到åQŒä»£ç é‡å‡å°‘了很多,SessionFactory通常用于原来¾cÖM¼¼EJBçš„JNDIå¯Õd€æ“ä½œã€?br />ç”׃ºŽmessageId是Motd对象的主键,我们只用了一行代码就完成了数据的‹‚€ç´¢å·¥ä½œï¼š

Motd motd = (Motd)session.get(Motd.class, new Integer(messageId));

如果不是直接关键主键的那些更复杂一些的查询åQŒåˆ™éœ€è¦ä‹É用SQL或HQLåQˆHibernate Query LanguageåQ‰ã€‚实际上åQŒHibernate3¾l™æˆ‘们提供了自动的事务和¾~“存的功能,因此åQŒæˆ‘们不用在出错处理上象JDBC那样¾~–写˜q‡å¤šçš„冗余代码了ã€?br />
Hibernate˜q˜éœ€è¦çŸ¥é“哪个表来关联哪个对象,˜q™ä¸ªå®žé™…上由一个XML映射文äšg来提供的。尽½Ž¡æœ‰äº›å·¥å…·ä¼šé€ æˆå¤§é‡çš„冗余难è¯ÀL‡‚çš„XMLæ–‡äšgåQŒä½†æ˜¯Hibernate在这一块上处理非常è½ÕdéyåQŒé’ˆå¯Òޝä¸ªéœ€è¦æ˜ ž®„到数据库中的那些POJO对象åQŒæˆ‘们只需要创å»ÞZ¸€ä¸ªç®€å•而清晰的XMLæ–‡äšgž®±å¯ä»¥äº†ã€‚当ç„Óž¼Œä¹Ÿå¯ä»¥å°†æ‰€æœ‰ä¿¡æ¯éƒ½æ”‘Öˆ°ä¸€ä¸ªå¤§çš„XMLæ–‡äšg中,Hibernate照样能读懂它们,可是˜q™ç§åšæ³•不被推荐使用åQŒå› ä¸ºå¯è¯Õd’Œå¯ç»´æŠ¤æ€§éƒ½å¤ªå·®äº†ã€?br />
一个文档类型定义(Document Type DefinitionåQŒç®€¿U°DTDåQ‰æ–‡ä»¶æä¾›ç»™æ‰€æœ‰çš„Hibernate配置文äšgåQŒå› æ­¤å¦‚果有好的XML¾~–辑器,那么可以使用自动完成和自动验证XML的很多方便的功能来编辑XML配置文äšgåQŒæœ‰äº›å·¥å…ïL”šè‡›_¯ä»¥è‡ªåŠ¨åˆ›å»ø™¿™äº›é…¾|®æ–‡ä»¶ã€‚而Java 5中新加入的注释语法(annotationsåQ‰èƒ½å¤Ÿå®Œå…¨å–代它们ã€?br />
下面是我们的Motd POJO对象到数据库的映ž®„æ–‡ä»Óž¼š

Listing 1-5. 映射POJO到数据库的XMLæ–‡äšg
CODE:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"[url]http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd[/url]">

<hibernate-mapping>
  <class name="Motd" table="Motd">
    <id name="id" type="int" column="id">
        <generator class="native"/>
    </id>
    <property name="message" column="message" type="string"/>
  </class>
</hibernate-mapping>


你可能会问,是不是将复杂性简单地从应用的代码转移åˆîCº†XML映射文äšgä¸­äº†å‘¢ï¼Ÿäº‹å®žä¸ŠåÆˆä¸æ˜¯˜q™æ ·ã€?br />1 XMLæ–‡äšg比从¾l“果集返回的复杂的POJO对象更容易编辑和处理
2 使我们可以排除类似JDBC那样的错误处理机制的代码复杂æ€?br />3 最重要的是åQŒå¦‚æžœPOJO提供¾cÖM¼¼javabean那样的属性访问方法(即getterå’Œsetteræ–ÒŽ³•åQ‰ï¼Œå’Œä¸€ä¸ªé»˜è®¤çš„æž„造方法,那么Hibernate的工具可以方便的自动生成XMLæ–‡äšg。关于工å…ïLš„使用在第10章中讨论


]]>
Pro Hibernate 3½W”记和小¾l“(1åQ‰ä¹‹½W¬ä¸€ç« Hibernate3介绍http://www.aygfsteel.com/os586/archive/2006/07/28/60481.html水煮三国水煮三国Fri, 28 Jul 2006 01:55:00 GMThttp://www.aygfsteel.com/os586/archive/2006/07/28/60481.htmlhttp://www.aygfsteel.com/os586/comments/60481.htmlhttp://www.aygfsteel.com/os586/archive/2006/07/28/60481.html#Feedback0http://www.aygfsteel.com/os586/comments/commentRss/60481.htmlhttp://www.aygfsteel.com/os586/services/trackbacks/60481.html /**
作者:Willpower
来源åQšRifoo TechnologyåQ?/font> http://www.rifoo.com åQ?br />æ—‰™—´åQ?006-05
备注åQšè{载请保留以上声明
**/

今天开始Hibernate3之旅åQŒåœ¨Hibernate2的基¼‹€ä¸Šæ”¹˜q›äº†ä¸å°‘åQŒè®©æˆ‘们一起借助˜q™æœ¬ä¹¦æ¥å­¦ä¹ å§ã€?br />
本书分两个部分,½W¬ä¸€éƒ¨åˆ†æ˜¯Hibernate入门知识åQˆç¬¬1åˆ?章)åQŒç¬¬äºŒéƒ¨åˆ†æ˜¯Hibernate高çñ”知识åQˆç¬¬5åˆ?4章)ã€?br />
我们今天来看看第一章的内容åQšHibernate 3的介¾lã€?br />
大多数重大的开发项目都会涉及到关系数据库的概念。许多商业应用的核心ž®±æ˜¯å¯¹è§„则有序的信息˜q›è¡Œå¤§è§„模的存储åQŒæ¯”如目录,客户列表åQŒåˆåŒèµ„料等ã€?br />
随着互联¾|‘çš„¾Jè£åQŒå¯¹æ•°æ®åº“的要求­‘Šæ¥­‘Šé«˜ã€‚在¾U¿ä¹¦åº—的那些客户们可能自己都不知道,自己每一‹Æ¡çš„æŸ¥è¯¢æ“ä½œæˆ–者点å‡ÀLŸä¸ªæŒ‰é’®éƒ½ä¼šåŽ»æ“ä½œæ•°æ®åº“ã€?br />
随着应用½E‹åºçš„需求不ŒD‰|é«˜ï¼ŒåŽæ¥å‡ºçŽ°äº†æ ‡å‡†çš„EJB规范åQŒEJB规范提供了容器和Bean½Ž¡ç†çš„CMP。但是,˜q™ä¸ªå¤æ‚æ€§å¾ˆé«˜ï¼Œè€Œæ€§èƒ½å´åÆˆæ²¡æœ‰æƒ›_ƒä¸­çš„高。后来,Hibernate的出现给数据的持久化带来了很大的轰动。针对一些数据库持久化解å†Ïx–¹æ¡ˆï¼Œæœ‰ç”¨EJB的,有用传统JDBC的,有用Hibernate的。但Hibernate在易用性上昄¡¤ºäº†çªå‡ºçš„优势ã€?br />
˜q™ä¸€ç« æˆ‘们会提供¾l™å¤§å®¶ä¸€ä¸ªâ€œHello world”数据库范例。该范例能够通过一个简单的关键字来查找òq¶æ˜¾½Cºæ•°æ®åº“中被保存的一个message信息。下面我们会提供原始JDBC写法和Hibernate写法åQ?br />
Listing 1-1. ˜q™ä¸ªMainæ–ÒŽ³•会调用我们Hibernate或JDBC的持久化操作
CODE:


public static void main(String[] args) {
  if (args.length != 1) {
    System.err.println("Nope, enter one message number");
  } else {
  try {
    int messageId = Integer.parseInt(args[0]);
    //˜q™ä¸€å¥æ˜¯è°ƒç”¨çš„æ–¹æ³?br />    [b]Motd motd = getMotd(messageId);[/b]
    if (motd != null) {
        System.out.println(motd.getMessage());
    } else {
        System.out.println("No such message");
    }
  } catch (NumberFormatException e) {
    System.err.println("You must enter an integer - " + args[0]
        + " won't do.");
  } catch (MotdException e) {
    System.err.println("Couldn't get the message: " + e);
    }
  }
}



在理想的世界中,我们ž®†å¾ˆå®ÒŽ˜“的获取ä“Q何JAVA对象òq¶å°†å®ƒæŒä¹…化到数据库。不需要编写额外的ç‰ÒŽ®Šä»£ç ã€‚也能够保证有良好的性能。对象关¾pÀL˜ ž®„(Object Relational MappingåQ‰æŠ€æœ¯èƒ½æŒä¹…化传¾lŸçš„JAVA对象åQŒè€Œè¿™é‡Œçš„POJOåQˆPlain Old Java ObjectsåQ‰ä¹Ÿæ˜¯ä¸€¿Uå¯é‡ç”¨çš„JAVA对象åQŒPOJO可以是ä“Q意的JAVA对象åQŒè€Œä¸éœ€è¦Entity Bean那样的命名约束。Hibernate能够帮助我们很轻村֜°åŽÀLŒä¹…化POJOã€?br />
下面我们¾~–写POJO部分åQ?br />

Listing 1-2. 本范例中使用到的POJO
CODE:

public class Motd {
  protected Motd() {
  }

  public Motd(int messageId, String message) {
    this.messageId = messageId;
    this.message = message;
  }
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getMessage() {
    return message;
  }
  public void setMessage(String message) {
    this.message = message;
  }
  private int messageId;
  private String message;
}



下面是从数据库中‹‚€ç´¢Motd对象的传¾lŸJDBC的写法,代码如下åQ?br />

Listing 1-3. ‹‚€ç´¢POJO
CODE:


public static Motd getMotd(int messageId) throws MotdException {
  Connection c = null;
  PreparedStatement p = null;
  Motd message = null;
  try {
  Class.forName("org.postgresql.Driver");
  c = DriverManager.getConnection(
    "jdbc:postgresql://127.0.0.1/hibernate",
    "hibernate",
    "hibernate");
  p = c.prepareStatement(
  "select message from motd where id = ?");
  p.setInt(1, messageId);
  ResultSet rs = p.executeQuery();
    if (rs.next()) {
        String text = rs.getString(1);
        message = new Motd(messageId, text);
        if (rs.next()) {
          log.warning(
          "Multiple messages retrieved for message ID: "
          + messageId);
          }
        }
    } catch (Exception e) {
    log.log(Level.SEVERE, "Could not acquire message", e);
    throw new MotdException(
    "Failed to retrieve message from the database.", e);
  } finally {
    if (p != null) {
        try {
          p.close();
        } catch (SQLException e) {
          log.log(Level.WARNING,
          "Could not close ostensibly open statement.", e);
        }
    }
    if (c != null) {
        try {
          c.close();
        } catch (SQLException e) {
        log.log(Level.WARNING,
        "Could not close ostensibly open connection.", e);
        }
    }
  }  
return message;
}


大家都看åˆîCº†åQŒè¿™ŒDµä»£ç åŒ…括数据库˜qžæŽ¥å»ºç«‹åQŒé‡Šæ”¾èµ„源等。对于每个查询的æ–ÒŽ³•åQŒéƒ½æœ‰è¿™æ ïLš„代码åQŒå…¶å®žè¿™ä¸ªæ˜¾å¾—很冗余。当然了åQŒæˆ‘们也可以对它˜q›è¡Œé‡æž„åQŒå°†˜q™éƒ¨åˆ†ä»£ç æå–出来,提供一些样本方法ã€?br />


]]>
Hibernate学习½W”è®°find及iterate------之二http://www.aygfsteel.com/os586/archive/2006/07/25/60019.html水煮三国水煮三国Tue, 25 Jul 2006 08:03:00 GMThttp://www.aygfsteel.com/os586/archive/2006/07/25/60019.htmlhttp://www.aygfsteel.com/os586/comments/60019.htmlhttp://www.aygfsteel.com/os586/archive/2006/07/25/60019.html#Feedback0http://www.aygfsteel.com/os586/comments/commentRss/60019.htmlhttp://www.aygfsteel.com/os586/services/trackbacks/60019.html在hibernate当中重点比较了find及iterateçš„ä‹É用,主要是他们在查询数据时的优劣势的比较åQŒè€Œç”±session.find()æ–ÒŽ³•也引甛_‡ºäº†query cache˜q™ä¸ªæ¦‚念及对find在查询时的劣势的解闷æ–ÒŽ¡ˆã€‚虽然query cache在ä‹É用上˜q˜æ˜¯æœ‰å¾ˆå¤šçš„局限,但是它对提高find的性能起到了很大的作用ã€?br />
在Hibernate2.0当中使用åQšsession.find(),session.iterate(),而hibernate3.0当中使用的是query.find(),query.iterate()来代æ›Ñ€?br />
下面我们着重分析一下这两个æ–ÒŽ³•çš„ä‹É用:

  1. 如果我们在ä‹É用find,iterate˜q›è¡ŒæŸ¥è¯¢æ—¶åˆ†åˆ«æž„å»ÞZ»–们的HQLåQŒé‚£ä¹ˆæˆ‘们在控制台输出当中看到iterate()æ–ÒŽ³•所使用的SQL语句的次数要˜qœè¿œ­‘…过Find()ã€?br />
  但是åQŒäؓ什么iterate()˜q˜å­˜åœ¨å‘¢åQ?br />
  2. 当我们在使用find构徏HQL后,而同æ ïLš„æŸ¥è¯¢ä¹Ÿè®©iterate()来执行一‹Æ¡çš„è¯?前提是必™åÖM‹É用find()构徏的HQL),那么iterate()çš„æ‰§è¡ŒåÆˆä¸å†åƒå‰é¢ä»‹¾lçš„那样会比find()æ–ÒŽ³•多执行SQLåQŒè€Œæ˜¯æ ÒŽœ¬å†æ‰§è¡Œä¸€æ¡SQL。这ž®±æ˜¯iterate()æ–ÒŽ³•çš„ä‹É用。它使用了Hibernate¾~“存机制.Find()æ–ÒŽ³•在查询出¾l“果后把查询¾l“果集置入缓存,而iterate()执行的时候先执行一条Select SQL,查询所有符合条件的¾l“果集,接下来iterate()æ ÒŽ®æŸ¥è¯¢çš„id在本地缓存中查找½W¦åˆæ¡äšg的结果集åQŒå¦‚果有完全½W¦åˆæ¡äšg的结果集åQŒåˆ™ç›´æŽ¥ä»¥æ­¤ä½œäØ“˜q”回¾l“果。如果没有找到再执行相应的SQL,òq¶ä¸”把结果纳入缓存当中。以备ä‹Éç”?br />


3.¾~“存机制òq¶ä¸å¯¹find()æ–ÒŽ³•èµ·ä‹É用。如果你两次执行相同条äšg的或相近条äšgçš„HQLåQŒç¬¬äºŒä¸ªæ–ÒŽ³•çš„SQLòq¶ä¸å‡å°‘。还会照常执行。这ž®±æ˜¯è¯´ç¼“å­˜æœºåˆ¶åÆˆä¸å¯¹find()æ–ÒŽ³•起作用。find()对缓存只写不读,而iterate()æ–ÒŽ³•ž®±å¯ä»¥å……分利用缓存的优势ã€?br />
4.内存斚w¢çš„考虑åQŒé™¤äº†ç¼“存的优势之外åQŒæˆ‘们还可以利用iterate()与evict()æ–ÒŽ³•来提升查询性能上的优势ã€?br />
     ˜q™ä¸ªé—®é¢˜ä¸»è¦æ˜¯å¤§æ•°æ®é‡æ‰€å¸¦æ¥çš„考虑。因为find()æ–ÒŽ³•可以对大数据量的¾l“果集进行缓存,但是如果数据量超大的话,也会带来内存溢出斚w¢çš„问题。利用iterate(),evict()可以对记录进行逐条处理åQŒå°†å†…存消耗保持在可接受的范围之内ã€?br />
  它包括从session中消除对对象åQŒåŠä»ŽsessionFactory当中消除对象ã€?/p>

5. 对于find()æ–ÒŽ³•在读取缓存问题方面的解决。Query Cache是一个解å†Ïx–¹æ¡ˆï¼Œä¸è¿‡ç›®å‰çš„ä‹É用受限比较大ã€?br />
    使用Query Cache的条件是åQ?br />
      A。数据库表结构不变。即未发生过update,insert,delete½{‰æ“ä½?br />
      B。相同的HSQL的重复执行操作�br />
ç”׃ºŽä»¥ä¸Šä¸¤ä¸ªåŽŸå› åQŒquery Cacheçš„ä‹É用上受到了很å¤?的限制ã€?br />
如果想ä‹É用query cache我们需要配¾|?hibernate.cfg.xmlæ–‡äšgåQ?br />
<class ......>

   <property nam="hibernate,cache.use_query_cache">True</property>

</class>



在编码当中ä‹É用:Query.setQueryCache(true);卛_¯ã€?br />



]]>
POJO与PO的概å¿ëА†è§?/title><link>http://www.aygfsteel.com/os586/archive/2006/07/25/59911.html</link><dc:creator>水煮三国</dc:creator><author>水煮三国</author><pubDate>Tue, 25 Jul 2006 01:08:00 GMT</pubDate><guid>http://www.aygfsteel.com/os586/archive/2006/07/25/59911.html</guid><wfw:comment>http://www.aygfsteel.com/os586/comments/59911.html</wfw:comment><comments>http://www.aygfsteel.com/os586/archive/2006/07/25/59911.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/os586/comments/commentRss/59911.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/os586/services/trackbacks/59911.html</trackback:ping><description><![CDATA[ <span id="wmqeeuq" class="postbody">摘自JAVA视线论坛<br /><br />POJO = pure old java object or plain ordinary java object or what ever. <br /><br />PO = persisent object 持久对象 <br /><br />ž®±æ˜¯è¯´åœ¨ä¸€äº›Object/Relation Mapping工具中,能够做到¾l´æŠ¤æ•°æ®åº“表记录的persisent object完全是一个符合Java Bean规范的纯Java对象åQŒæ²¡æœ‰å¢žåŠ åˆ«çš„å±žæ€§å’Œæ–ÒŽ³•。全都是˜q™æ ·å­çš„åQ?<br /><br /><br /></span> <table cellspacing="1" cellpadding="3" width="90%" align="center" border="0"> <tbody> <tr> <td> <span id="wmqeeuq" class="genmed"> <b>java代码: </b> </span> </td> </tr> <tr> <td class="code"> <div style="FONT-FAMILY: 'Courier New', Courier, monospace"> <br /> <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span> <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span> User <span style="COLOR: #000000">{</span><br />  <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">private</span> long id; <br />  <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">private</span><span style="COLOR: #aaaadd" ?="">String</span> name; <br />  <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">void</span> setId<span style="COLOR: #000000">(</span>long id<span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />this.<span style="COLOR: #000000">id</span> = id; <br /><span style="COLOR: #000000">}</span>  <br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">void</span> setName<span style="COLOR: #000000">(</span><span style="COLOR: #aaaadd" ?="">String</span> name<span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />this.<span style="COLOR: #000000">name</span>=name; <br /><span style="COLOR: #000000">}</span><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span> long getId<span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">return</span> id; <br /><span style="COLOR: #000000">}</span>  <br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="COLOR: #aaaadd" ?="">String</span> getName<span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">return</span> name; <br /><span style="COLOR: #000000">}</span><br /><span style="COLOR: #000000">}</span> </div> <br /> </td> </tr> </tbody> </table> <span id="wmqeeuq" class="postbody"> <br /> <br />--------------------------------------------------------------------------- <br />首先要区别持久对象和POJOã€?<br /><br />持久对象实际上必™åÕd¯¹åº”数据库中的entityåQŒæ‰€ä»¥å’ŒPOJO有所区别。比如说POJO是由new创徏åQŒç”±GC回收。但是持久对象是insert数据库创建,由数据库delete删除的。基本上持久对象生命周期和数据库密切相关。另外持久对象往往只能存在一个数据库Connection之中åQŒConnnection关闭以后åQŒæŒä¹…对象就不存在了åQŒè€ŒPOJO只要不被GC回收åQŒæ€ÀL˜¯å­˜åœ¨çš„ã€?<br /><br />ç”׃ºŽå­˜åœ¨è¯¸å¤šå·®åˆ«åQŒå› æ­¤æŒä¹…对象PO(Persistent Object)在代码上肯定和POJO不同åQŒè“v码PO相对于POJO会增加一些用来管理数据库entity状态的属性和æ–ÒŽ³•。而ORM˜q½æ±‚的目标就是要PO在ä‹É用上ž®½é‡å’ŒPOJO一è‡ß_¼Œå¯¹äºŽ½E‹åºå‘˜æ¥è¯ß_¼Œä»–们可以把PO当做POJO来用åQŒè€Œæ„Ÿè§‰ä¸åˆ°PO的存在ã€?<br /><br />JDO的实现方法是˜q™æ ·çš„: <br />1、编写POJO <br />2、编译POJO <br />3、ä‹É用JDOçš„ä¸€ä¸ªä¸“é—¨å·¥å…øP¼Œå«åšEnhanceråQŒä¸€èˆ¬æ˜¯ä¸€ä¸ªå‘½ä»¤è¡Œ½E‹åºåQŒæ‰‹å·¥è¿è¡Œï¼Œæˆ–者在ant脚本里面˜qè¡ŒåQŒå¯¹POJOçš„classæ–‡äšg处理一下,把POJO替换成同名的POã€?<br />4、在˜qè¡ŒæœŸè¿è¡Œçš„实际上是POåQŒè€Œä¸æ˜¯POJOã€?<br /><br />该方法有点类ä¼égºŽJSPåQŒJSP也是在编译期被è{换成Servlet来运行的åQŒåœ¨˜qè¡ŒæœŸå®žé™…上˜qè¡Œçš„æ˜¯ServletåQŒè€Œä¸æ˜¯JSPã€?<br /><br />Hibernate的实现方法比较先˜q›ï¼š <br />1、编写POJO <br />2、编译POJO <br />3、直接运行,在运行期åQŒç”±Hibernateçš„CGLIB动态把POJO转换为POã€?<br /><br />由此可以看出Hibernate是在˜qè¡ŒæœŸæŠŠPOJO的字节码转换为PO的,而JDO是在¾~–译期è{换的。一般认为JDO的方式效率会½Eé«˜åQŒæ¯•竟是¾~–译期è{换嘛。但是Hibernate的作者Gavin King说CGLIBçš„æ•ˆçŽ‡éžå¸æ€¹‹é«˜ï¼Œ˜qè¡ŒæœŸçš„PO的字节码生成速度非常之快åQŒæ•ˆçŽ‡æŸå¤±å‡ ä¹Žå¯ä»¥å¿½ç•¥ä¸è®¡ã€?<br /><br />实际上运行期生成PO的好处非常大åQŒè¿™æ ·å¯¹äºŽç¨‹åºå‘˜æ¥è¯´åQŒæ˜¯æ— æ³•接触到PO的,PO对他们来说完全透明。可以更加自ç”Þqš„以POJO的概忉|“¾UµPO。另外由于是˜qè¡ŒæœŸç”ŸæˆPOåQŒæ‰€ä»¥å¯ä»¥æ”¯æŒå¢žé‡ç¼–译,增量调试。而JDO则无法做到这一炏V€‚实际上已经有很多äh在抱怨JDO的编译期Enhancer问题了,而据说JBossDOž®†é‡‡ç”¨è¿è¡ŒæœŸç”ŸæˆPO字节码,而不采用¾~–译期生成PO字节码ã€?<br /><br />另外一个相关的问题是,不同的JDO产品的Enhancer生成的PO字节码可能会有所不同åQŒå¯èƒ½ä¼šå½±å“åœ¨JDO产品之间的可¿UÀL¤æ€§ï¼Œ˜q™ä¸€ç‚ÒŽœ‰ç‚¹ç±»ä¼¼EJB的可¿UÀL¤æ€§éš¾é¢˜ã€?<br /><br />----------------------------------------------------------------------------------- <br />ç”Þp¿™ä¸ªé—®é¢˜å¦å¤–引å‡ÞZ¸€ä¸ªJDO的缺陗÷€?<br /><br />ç”׃ºŽJDOçš„PO状态管理方式,所以当你在½E‹åºé‡Œé¢get/set的时候,实际上不是从PO的实例中取valuesåQŒè€Œæ˜¯ä»ŽJDO StateManager中取出来åQŒæ‰€ä»¥ä¸€æ—¦PM关闭åQŒPOž®×ƒ¸èƒ½è¿›è¡Œå­˜å–了ã€?<br /><br />在JDO中,也可以通过一些办法ä‹Éå¾—PO可以在PM外面使用åQŒæ¯”如说定义PO是transient的,但是该PO在PM关闭后就没有PO identity了。无法进行跨PM的状态管理ã€?<br /><br />而Hibernate是从PO实例中取values的,所以即使Session关闭åQŒä¹Ÿä¸€æ ·å¯ä»¥get/setåQŒå¯ä»¥è¿›è¡Œè·¨Session的状态管理ã€?<br /><br />在分多层的应用中åQŒç”±äºŽæŒä¹…层和业务层和web层都是分开的,此时Hibernateçš„PO完全可以当做一个POJO来用åQŒä¹Ÿž®±æ˜¯å½“做一个VOåQŒåœ¨å„层间自ç”׃¼ é€’,而不用去½Ž¡Session是开˜q˜æ˜¯å…Ÿë€‚如果你把这个POJO序列化的话,甚至可以用在分布式环境中。(不适合lazy loading的情况) <br /><br />但是JDOçš„PO在PM关闭后就不能再用了,所以必™åÕdœ¨PM关闭前把PO拯‚´ä¸€ä»½VOåQŒæŠŠVO传递给业务层和web层ä‹É用。在非分布式环境中,也可以ä‹É用ThreadLocal模式¼‹®ä¿PM始终是打开状态,来避免每‹Æ¡å¿…™å»è¿›è¡ŒPO到VO的拷贝操作。但是不½Ž¡æ€Žä¹ˆè¯ß_¼Œ˜q™æ€ÀL˜¯æƒå®œä¹‹è®¡åQŒä¸å¦‚Hibernate的功能强ã€?/span> <img src ="http://www.aygfsteel.com/os586/aggbug/59911.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/os586/" target="_blank">水煮三国</a> 2006-07-25 09:08 <a href="http://www.aygfsteel.com/os586/archive/2006/07/25/59911.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse3.1 安装xmlBuddy2.0.72的问题解å†?/title><link>http://www.aygfsteel.com/os586/archive/2006/07/20/59237.html</link><dc:creator>水煮三国</dc:creator><author>水煮三国</author><pubDate>Thu, 20 Jul 2006 09:16:00 GMT</pubDate><guid>http://www.aygfsteel.com/os586/archive/2006/07/20/59237.html</guid><wfw:comment>http://www.aygfsteel.com/os586/comments/59237.html</wfw:comment><comments>http://www.aygfsteel.com/os586/archive/2006/07/20/59237.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.aygfsteel.com/os586/comments/commentRss/59237.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/os586/services/trackbacks/59237.html</trackback:ping><description><![CDATA[ <p>xmlBuddy2.0.72是支持Eclipse3.1版的。但是在下蝲了xmlbuddy后解压后把解压后的文件复制到Eclipse下的plugins下却不显½Cºã€?br /><br />一直认为xmlBuddy2.0.72可能不支æŒ?.1çš„EclipseåQŒåŽæ¥ä¸Š¾|‘上看资料后¼‹®è®¤æ˜¯æ”¯æŒçš„ã€?br /><br />但是启动了N遍eclipse也不能找到xmlbuddy的两个图标ã€?br /><br />后来åQŒçœ‹è§ç½‘上也有相似的问题发生ã€?br /><br />解决的办法是在eclipse的启动参数后面加å…?-clean后就可ã€?/p> <img src ="http://www.aygfsteel.com/os586/aggbug/59237.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/os586/" target="_blank">水煮三国</a> 2006-07-20 17:16 <a href="http://www.aygfsteel.com/os586/archive/2006/07/20/59237.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从今儿开始学习Hibernatehttp://www.aygfsteel.com/os586/archive/2006/06/26/55059.html水煮三国水煮三国Mon, 26 Jun 2006 01:02:00 GMThttp://www.aygfsteel.com/os586/archive/2006/06/26/55059.htmlhttp://www.aygfsteel.com/os586/comments/55059.htmlhttp://www.aygfsteel.com/os586/archive/2006/06/26/55059.html#Feedback3http://www.aygfsteel.com/os586/comments/commentRss/55059.htmlhttp://www.aygfsteel.com/os586/services/trackbacks/55059.html对Java的理解还不是太深,现在看到那么多的开源工å…?心里很痒.

大家对Struts,Spring,Hibernate˜q™äº›å¼€æºå·¥å…äh˜¯æ€Žæ ·ç†è§£çš?

我对Struts˜q˜æ˜¯äº†è§£ä¸€äº?但是对Spring,Hibernate˜q˜ä¸æ˜¯å¾ˆäº†è§£.

如果有一起学习这些工å…ïLš„¾|‘友ä»?

我们可以在这里交‹¹å­¦ä¹?/p>

]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ¼Ò¾Ó| ÆÖ¶«ÐÂÇø| ÐÂÓàÊÐ| ÆÕ°²ÏØ| ÕòÐÛÏØ| ¾£ÖÝÊÐ| Î÷Ï¿ÏØ| ¹Ê³ÇÏØ| ººÊÙÏØ| ÍòÈÙÏØ| ÓÀÖÝÊÐ| ¶þÊÖ·¿| ÇåÔ·ÏØ| ʯʨÊÐ| ÎåºÓÏØ| º×ɽÊÐ| Äþ»¯ÏØ| ÎäѨÊÐ| Î÷Ï¿ÏØ| л¯ÏØ| º£ÄþÊÐ| Ð˺ÍÏØ| ·±ÖÅÏØ| ¸·¿µÊÐ| ºÏÑôÏØ| µÂÖÝÊÐ| º¼½õºóÆì| Ì«²ÖÊÐ| ÁùÖ¦ÌØÇø| ³¤µºÏØ| À¼Æº| Í­¹ÄÏØ| ¶¨ÖÝÊÐ| Áú¿ÚÊÐ| ÃÖ¶ÉÏØ| µÂÁî¹þÊÐ| »ôÉ½ÏØ| ¼òÑôÊÐ| ãþÑôÏØ| Á½µ±ÏØ| Ë·ÖÝÊÐ|