åœ¨ç¬¬äºŒç§æ¨¡åž‹ä¸ï¼Œæˆ‘们å¯ä»¥æ¸…楚的把˜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™ä¸€¾c»domain logicåQŒä¸šåŠ¡é€»è¾‘å¯¹è±¡å¿…é¡»æä¾›ç›¸åº”çš„å°è£…方法,以实çŽîCº‹åŠ¡æŽ§åˆ¶ã€?/p>
½W¬äºŒ¾c»ï¼šå®Œå…¨ä¸ä¾èµ–æŒä¹…化的domain logicåQŒä¾‹å¦‚readonly例åä¸çš„TopicåQŒå¦‚下:
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Œè¿™¿Udomain logicä¸ç®¡è„Þq¦»ä¸è„±¼›ÀL‰€åœ¨çš„æ¡†æž¶åQŒå®ƒçš„行为都是一致的。对于这¿Udomain logicå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)
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>
}
public interface ItemDao {
public Item getItemById ( Long id );
public Collection findAll ();
public void updateItem ( Item item );
}
ItemDao定义æŒä¹…化æ“作的接å£åQŒç”¨äºŽé𔼛ÀLŒä¹…化代ç ã€?/p>
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 );
}
}
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&¤tMaxBid.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
publicclass ItemimplementsSerializable{
// 所有的属性和getter/setteræ–ÒŽ³•åŒä¸ŠåQŒçœç•?/span>
publicBidplaceBid(Userbidder,MonetaryAmountbidAmount,
BidcurrentMaxBid,BidcurrentMinBid)
throwsBusinessException{
//Checkhighestbid(canalsobeadifferentStrategy(pattern))
if(currentMaxBid!=null&¤tMaxBid.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>
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>
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&¤tMaxBid.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>
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 />