??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲短视频男人的影院,亚洲人成在线播放,亚洲高清一区二区三区http://www.tkk7.com/os586/category/12511.html态度军_一切,思想军_?gu)\zh-cnThu, 21 Jun 2007 14:07:12 GMTThu, 21 Jun 2007 14:07:12 GMT60Hibernate的类型怎样映射数据库中字段的自定义cdhttp://www.tkk7.com/os586/archive/2007/06/21/125586.html水煮三国水煮三国Thu, 21 Jun 2007 07:48:00 GMThttp://www.tkk7.com/os586/archive/2007/06/21/125586.htmlhttp://www.tkk7.com/os586/comments/125586.htmlhttp://www.tkk7.com/os586/archive/2007/06/21/125586.html#Feedback1http://www.tkk7.com/os586/comments/commentRss/125586.htmlhttp://www.tkk7.com/os586/services/trackbacks/125586.html我在数据库中自定义了(jin)数据cdQ如UserName,其实它就是一个基本数据类型:(x)varchar(12)的? 但是q种自定义数据类型在hibernate当中我们该怎样q行数据cd的映?

水煮三国 2007-06-21 15:48 发表评论
]]>
再论Domaion Object [From JavaEye]http://www.tkk7.com/os586/archive/2006/10/19/76082.html水煮三国水煮三国Thu, 19 Oct 2006 02:01:00 GMThttp://www.tkk7.com/os586/archive/2006/10/19/76082.htmlhttp://www.tkk7.com/os586/comments/76082.htmlhttp://www.tkk7.com/os586/archive/2006/10/19/76082.html#Feedback0http://www.tkk7.com/os586/comments/commentRss/76082.htmlhttp://www.tkk7.com/os586/services/trackbacks/76082.html既然大家都统一?jin)观点,那么有了(jin)一个很好的讨论问题的基?jin)。Martin Fowler的Domain ModelQ或者说我们的第二种模型N是完无~的吗?当然不是Q接下来我就要分析一下它的不I以及(qing)可能的解军_法,而这些都来源于我个h的实跉|索?/p>

在第二种模型中,我们可以清楚的把q?个类分ؓ(f)三层Q?/p>

1、实体类层,即ItemQ带有domain logic的domain object
2、DAO层,即ItemDao和ItemDaoHibernateImplQ抽象持久化操作的接口和实现c?
3、业务逻辑层,即ItemManagerQ接受容器事务控Ӟ向Web层提供统一的服务调?/p>

在这三层中我们大家可以看刎ͼdomain object和DAO都是非常E_的层Q其实原因也很简单,因ؓ(f)domain object是映数据库字段的,数据库字D不?x)频J变动,所以domain object也相对稳定,而面向数据库持久化编E的DAO层也不过是CRUD而已Q不?x)有更多的花P所以也很稳定?/p>

问题在于这个充当business workflow facade的业务逻辑对象Q它的变动是相当频繁的?span style="COLOR: red">业务逻辑对象通常都是无状态的、受事务控制的、Singletonc?/span>Q我们可以考察一下业务逻辑对象都有哪几cM务逻辑Ҏ(gu)Q?/p>

W一c:(x)DAO接口Ҏ(gu)的代?/span>Q就是上面例子中的loadItemByIdҎ(gu)和findAllҎ(gu)?/p>

ItemManager之所以要代理q种c,目的有两个:(x)向Web层提供统一的服务调用入口点和给持久化方法增加事务控制功?/span>。这两点都很Ҏ(gu)理解Q你不能既给Web层程序员提供xxxManagerQ也l他提供xxxDaoQ所以你需要用xxxManager装xxxDaoQ在q里Q充当了(jin)一个简单代理功能;而事务控制也是持久化Ҏ(gu)必须的,事务可能需要跨多个DAOҎ(gu)调用Q所以必L在业务逻辑层,而不能放在DAO层?/p>

但是必须看到Q对于一个典型的web应用来说Q绝大多数的业务逻辑都是单的CRUD逻辑Q所以这U情况下Q针Ҏ(gu)个DAOҎ(gu)QxxxManager都需要提供一个对应的装Ҏ(gu)Q这不但是非常枯燥的Q也是o(h)人感觉非怸好的?/p>

W二c:(x)domain logic的方法代?/span>。就是上面例子中placeBidҎ(gu)。虽然Item已经有了(jin)placeBidҎ(gu)Q但是ItemManager仍然需要封装一下Item的placeBidQ然后再提供一个简单封装之后的代理Ҏ(gu)?/p>

q和W一U情늱|其原因也一P也是Z(jin)lWeb层提供一个统一的服务调用入口点和给隐式的持久化动作提供事务控制?/p>

同样Q和W一U情况一P针对每个domain logicҎ(gu)QxxxManager都需要提供一个对应的装Ҏ(gu)Q同h枯燥的,令h不爽的?/p>

W三c:(x)需要多个domain object和DAO参与协作的business workflow。这U情冉|业务逻辑对象真正应该完成的职责?/p>

在这个简单的例子中,没有涉及(qing)到这U情况,不过大家都可以想像的出来q种应用场景Q因此不必D例说明了(jin)?/p>

通过上面的分析可以看出,只有W三cM务逻辑Ҏ(gu)才是业务逻辑对象真正应该承担的职责,而前两类业务逻辑Ҏ(gu)都是“无奈之䏀,不得不ؓ(f)之的事情Q不但枯燥,而且令h沮?/p>

分析完了(jin)业务逻辑对象Q我们再回头看一下domain objectQ我们要仔细考察一下domain logic的话Q会(x)发现domain logic也分Zc:(x)

W一c:(x)需要持久层框架隐式的实现透明持久化的domain logicQ例如Item的placeBidҎ(gu)中的q一句:(x)

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

上面已经着重提刎ͼ虽然q仅仅只是一个Java集合的添加新元素的操作,但是实际上通过事务的控Ӟ?x)潜在的触发两条SQLQ一条是insert一条记录到bid表,一条是更新item表相应的记录。如果我们让ItemqHibernateq行单元试Q它?yu)是一个单U的Java集合操作Q如果我们把他加入到Hibernate框架中,他就?x)潜在的触发两条SQLQ?span style="COLOR: red">q就是隐式的依赖于持久化的domain logic?
特别h意的一Ҏ(gu)Q在没有Hibernate/JDOq类可以实现“透明的持久化”工具出C前,q类domain logic是无法实现的?

对于q一cdomain logicQ业务逻辑对象必须提供相应的封装方法,以实C务控制?/p>

W二c:(x)完全不依赖持久化的domain logicQ例如readonly例子中的TopicQ如下:(x)

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

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

注意q个isAllowReplyҎ(gu)Q他和持久化完全不发生一丁点关系。在实际的开发中Q我们同样会(x)遇到很多q种不需要持久化的业务逻辑(主要发生在日期运、数D和枚Dq算斚w)Q这Udomain logic不管q不脱L在的框架Q它的行为都是一致的。对于这Udomain logicQ业务逻辑层ƈ不需要提供封装方法,它可以适用于Q何场合?/p>

水煮三国 2006-10-19 10:01 发表评论
]]>
ȝ一下最q关于domain object以及(qing)相关的讨?[From:JAVAEYE]http://www.tkk7.com/os586/archive/2006/10/19/76070.html水煮三国水煮三国Thu, 19 Oct 2006 01:19:00 GMThttp://www.tkk7.com/os586/archive/2006/10/19/76070.htmlhttp://www.tkk7.com/os586/comments/76070.htmlhttp://www.tkk7.com/os586/archive/2006/10/19/76070.html#Feedback2http://www.tkk7.com/os586/comments/commentRss/76070.htmlhttp://www.tkk7.com/os586/services/trackbacks/76070.html在最q的围绕domain object的讨Z现出来?jin)三U模型,(q有一些其他的旁枝Q不一一分析?Q经q一番讨论,各种问题逐渐清晰hQ在q里我试囑ց一个ȝQ便于大家了(jin)解和掌握?/p>

W一U模型:(x)只有getter/setterҎ(gu)的纯数据c,所有的业务逻辑完全由business object来完?又称TransactionScript)Q这U模型下的domain object被Martin FowlerUC为“血的domain object”。下面用举一个具体的代码来说明,代码来自Hibernate的caveatemptorQ但l过我的改写Q?/p>

一个实体类叫做ItemQ指的是一个拍卖项?
一个DAO接口cd做ItemDao
一个DAO接口实现cd做ItemDaoHibernateImpl
一个业务逻辑cd做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Ҏ(gu)省略不写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Ҏ(gu)调用之前打开SessionQDAOҎ(gu)调用之后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;
}
}

事务的管理是在ItemMangerq一层完成的QItemManager实现具体的业务逻辑。除?jin)常见的和CRUD有关的简单逻辑之外Q这里还有一个placeBid的逻辑Q即目的竞标?/p>

以上是一个完整的W一U模型的CZ代码。在q个CZ中,placeBidQloadItemByIdQfindAll{等业务逻辑l统攑֜ItemManager中实玎ͼ而Item只有getter/setterҎ(gu)?br />




W二U模型,也就是Martin Fowler指的rich domain object是下面这样子的:(x)

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

java代码
publicclass ItemimplementsSerializable{
// 所有的属性和getter/setterҎ(gu)同上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意这一句,透明的进行了(jin)持久化,但是不能在这里调?span class="constant">ItemDaoQItem不能对ItemDao产生依赖Q?/span>

returnnewBid;
}
}

竞标q个业务逻辑被放入到Item中来。请注意this.getBids.add(newBid); 如果没有Hibernate或者JDOq种O/R Mapping的支持,我们是无法实现这U透明的持久化行ؓ(f)的。但是请注意QItem里面不能去调用ItemDAOQ对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">DAOQ保持持久化
}
}

在第二种模型中,placeBid业务逻辑是放在Item中实现的Q而loadItemById和findAll业务逻辑是放在ItemManager中实现的。不q值得注意的是Q即使placeBid业务逻辑攑֜Item中,你仍焉要在ItemManager中简单的装一层,以保证对placeBid业务逻辑q行事务的管理和持久化的触发?/p>

q种模型是Martin Fowler所指的真正的domain model。在q种模型中,有三个业务逻辑Ҏ(gu)QplaceBidQloadItemById和findAllQ现在的问题是哪个逻辑应该攑֜Item中,哪个逻辑应该攑֜ItemManager中。在我们q个例子中,placeBid攑֜Item?但是ItemManager也需要对它进行简单的装)QloadItemById和findAll是放在ItemManager中的?/p>

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

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

Item的placeBidq个业务逻辑Ҏ(gu)没有昑ּ的对持久化ItemDao接口产生依赖Q所以要攑֜Item中?span style="COLOR: red">h意,如果q?jin)Hibernateq个持久化框ӞItemq个domain object是可以进行单元测试的Q他不依赖于Hibernate的持久化机制。它是一个独立的Q可UL的,完整的,自包含的域对?/span>?/p>

而loadItemById和findAllq两个业务逻辑Ҏ(gu)是必L式的Ҏ(gu)久化ItemDao接口产生依赖Q否则这个业务逻辑无法完成。如果你要把q两个方法放在Item中,那么Item无法脱Hibernate框架Q无法在Hibernate框架之外独立存在?br />


W三U模型印象中好像是firebody或者是Archie提出?也有可能不是Q记不清楚了(jin))Q简单的来说Q这U模型就是把W二U模型的domain object和business object合二Z?jin)。所以ItemManager׃需要了(jin)Q在q种模型下面Q只有三个类Q他们分别是Q?/p>

ItemQ包含了(jin)实体cM息,也包含了(jin)所有的业务逻辑
ItemDaoQ持久化DAO接口c?
ItemDaoHibernateImplQDAO接口的实现类

׃ItemDao和ItemDaoHibernateImpl和上面完全相同,q略了(jin)?/p>

java代码
publicclass ItemimplementsSerializable{
// 所有的属性和getter/setterҎ(gu)都省?/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);// 调用DAOq行昑ּ持久?/span>
returnnewBid;
}
}

在这U模型中Q所有的业务逻辑全部都在Item中,事务理也在Item中实现?/p>

水煮三国 2006-10-19 09:19 发表评论
]]>
Pro Hibernate 3W记和小l(2Q之W一章Hibernate3介绍http://www.tkk7.com/os586/archive/2006/07/28/60487.html水煮三国水煮三国Fri, 28 Jul 2006 02:06:00 GMThttp://www.tkk7.com/os586/archive/2006/07/28/60487.htmlhttp://www.tkk7.com/os586/comments/60487.htmlhttp://www.tkk7.com/os586/archive/2006/07/28/60487.html#Feedback0http://www.tkk7.com/os586/comments/commentRss/60487.htmlhttp://www.tkk7.com/os586/services/trackbacks/60487.htmlPro Hibernate 3W记和小l(2Q之W一章Hibernate3介绍

/**
作者:(x)Willpower
来源QRifoo TechnologyQ?/font> http://www.rifoo.com Q?br />旉Q?006-05
备注Q{载请保留以上声明
**/


今天l箋W一章的学习(fn)Q我们先来看看EJB和Hibernate的区别?br />
Z么不用EJB来存储,昄Q查询数据库中的数据呢?严格的说QEJB服务器支持两U类型的持久化,是BEAN理的持久化QBMPQ和容器理的持久化QCMPQ。在BMP中,Bean自己负责执行所有的SQL语句来完成存储和查询数据。换句话_(d)我们自己要去~写JDBC逻辑代码。另一斚wQCMP是由容器来执行存储和(g)索bean数据的工作?br />
我们q里不选择EJB的原因如下:(x)
1 CMP实体bean需要和数据表一对一的映?br />2 它们很慢
3 有时候要人工参与的去军_哪一个bean字段对应表的哪一?br />4 它们Ҏ(gu)法命名有要求
5 EJB的容器是重量U的
6 它们和容器依赖强Q不Ҏ(gu)UL

下面看看Hibernate的特点:(x)
1 不需要强制映一个POJOC个表Q不强制一对一的关p?br />2 快启动q加载它的配|文件时?x)对性能有些负蝲Q但ȝ来说Q它是很快的工具
3 和容器没有强依赖Q很方便的移?br />4 可以很轻杄处理serializable POJOs

以上只是单的列DQ还有很多特炚w没有提及(qing)。MQHibernate在应用程序的持久层这一块是非常不错的框架。下面我们来看一个Hibernate的Hello worldE序Q?br />
Listing 1-4. Hibernate(g)索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代码量减少?jin)很多,SessionFactory通常用于原来cMEJB的JNDId操作?br />׃messageId是Motd对象的主键,我们只用?jin)一行代码就完成?jin)数据的(g)索工作:(x)

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

如果不是直接关键主键的那些更复杂一些的查询Q则需要用SQL或HQLQHibernate Query LanguageQ。实际上QHibernate3l我们提供了(jin)自动的事务和~存的功能,因此Q我们不用在出错处理上象JDBC那样~写q多的冗余代码了(jin)?br />
Hibernateq需要知道哪个表来关联哪个对象,q个实际上由一个XML映射文g来提供的。尽有些工具会(x)造成大量的冗余难L的XML文gQ但是Hibernate在这一块上处理非常dyQ针Ҏ(gu)个需要映到数据库中的那些POJO对象Q我们只需要创Z个简单而清晰的XML文g可以了(jin)。当?dng)也可以将所有信息都攑ֈ一个大的XML文g中,Hibernate照样能读懂它们,可是q种做法不被推荐使用Q因为可d可维护性都太差?jin)?br />
一个文档类型定义(Document Type DefinitionQ简UDTDQ文件提供给所有的Hibernate配置文gQ因此如果有好的XML~辑器,那么可以使用自动完成和自动验证XML的很多方便的功能来编辑XML配置文gQ有些工L(fng)臛_以自动创些配|文件。而Java 5中新加入的注释语法(annotationsQ能够完全取代它们?br />
下面是我们的Motd POJO对象到数据库的映文Ӟ(x)

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>


你可能会(x)问,是不是将复杂性简单地从应用的代码转移C(jin)XML映射文g中了(jin)呢?事实上ƈ不是q样?br />1 XML文g比从l果集返回的复杂的POJO对象更容易编辑和处理
2 使我们可以排除类似JDBC那样的错误处理机制的代码复杂?br />3 最重要的是Q如果POJO提供cMjavabean那样的属性访问方法(即getter和setterҎ(gu)Q,和一个默认的构造方法,那么Hibernate的工具可以方便的自动生成XML文g。关于工L(fng)使用在第10章中讨论


水煮三国 2006-07-28 10:06 发表评论
]]>
Pro Hibernate 3W记和小l(1Q之W一章Hibernate3介绍http://www.tkk7.com/os586/archive/2006/07/28/60481.html水煮三国水煮三国Fri, 28 Jul 2006 01:55:00 GMThttp://www.tkk7.com/os586/archive/2006/07/28/60481.htmlhttp://www.tkk7.com/os586/comments/60481.htmlhttp://www.tkk7.com/os586/archive/2006/07/28/60481.html#Feedback0http://www.tkk7.com/os586/comments/commentRss/60481.htmlhttp://www.tkk7.com/os586/services/trackbacks/60481.html /**
作者:(x)Willpower
来源QRifoo TechnologyQ?/font> http://www.rifoo.com Q?br />旉Q?006-05
备注Q{载请保留以上声明
**/

今天开始Hibernate3之旅Q在Hibernate2的基上改q了(jin)不少Q让我们一起借助q本书来学习(fn)吧?br />
本书分两个部分,W一部分是Hibernate入门知识Q第1?章)(j)Q第二部分是Hibernate高知识Q第5?4章)(j)?br />
我们今天来看看第一章的内容QHibernate 3的介l?br />
大多数重大的开发项目都?x)涉及(qing)到关系数据库的概念。许多商业应用的核心(j)?yu)是对规则有序的信息q行大规模的存储Q比如目录,客户列表Q合同资料等?br />
随着互联|的J荣Q对数据库的要求来高。在U书店的那些客户们可能自己都不知道,自己每一ơ的查询操作或者点?yn)L个按钮都?x)去操作数据库?br />
随着应用E序的需求不D|高,后来出现?jin)标准的EJB规范QEJB规范提供?jin)容器和Bean理的CMP。但是,q个复杂性很高,而性能却ƈ没有惛_中的高。后来,Hibernate的出现给数据的持久化带来?jin)很大的轰动。针对一些数据库持久化解x案,有用EJB的,有用传统JDBC的,有用Hibernate的。但Hibernate在易用性上昄?jin)突出的优势?br />
q一章我们会(x)提供l大家一个“Hello world”数据库范例。该范例能够通过一个简单的关键字来查找q显C数据库中被保存的一个message信息。下面我们会(x)提供原始JDBC写法和Hibernate写法Q?br />
Listing 1-1. q个MainҎ(gu)?x)调用我们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);
    }
  }
}



在理想的世界中,我们很Ҏ(gu)的获取Q何JAVA对象q将它持久化到数据库。不需要编写额外的Ҏ(gu)代码。也能够保证有良好的性能。对象关pL(Object Relational MappingQ技术能持久化传l的JAVA对象Q而这里的POJOQPlain Old Java ObjectsQ也是一U可重用的JAVA对象QPOJO可以是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;
}



下面是从数据库中(g)索Motd对象的传lJDBC的写法,代码如下Q?br />

Listing 1-3. (g)索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(jin)Q这D代码包括数据库q接建立Q释放资源等。对于每个查询的Ҏ(gu)Q都有这L(fng)代码Q其实这个显得很冗余。当然了(jin)Q我们也可以对它q行重构Q将q部分代码提取出来,提供一些样本方法?br />


水煮三国 2006-07-28 09:55 发表评论
]]>
Hibernate学习(fn)W记find?qing)iterate------之二http://www.tkk7.com/os586/archive/2006/07/25/60019.html水煮三国水煮三国Tue, 25 Jul 2006 08:03:00 GMThttp://www.tkk7.com/os586/archive/2006/07/25/60019.htmlhttp://www.tkk7.com/os586/comments/60019.htmlhttp://www.tkk7.com/os586/archive/2006/07/25/60019.html#Feedback0http://www.tkk7.com/os586/comments/commentRss/60019.htmlhttp://www.tkk7.com/os586/services/trackbacks/60019.html在hibernate当中重点比较?jin)find?qing)iterate的用,主要是他们在查询数据时的优劣势的比较Q而由session.find()Ҏ(gu)也引甛_?jin)query cacheq个概念?qing)对find在查询时的劣势的解闷Ҏ(gu)。虽然query cache在用上q是有很多的局限,但是它对提高find的性能起到?jin)很大的作用?br />
在Hibernate2.0当中使用Qsession.find(),session.iterate(),而hibernate3.0当中使用的是query.find(),query.iterate()来代ѝ?br />
下面我们着重分析一下这两个Ҏ(gu)的用:(x)

  1. 如果我们在用find,iterateq行查询时分别构Z们的HQLQ那么我们在控制台输出当中看到iterate()Ҏ(gu)所使用的SQL语句的次数要q远过Find()?br />
  但是Qؓ(f)什么iterate()q存在呢Q?br />
  2. 当我们在使用find构徏HQL后,而同L(fng)查询也让iterate()来执行一ơ的?前提是必M用find()构徏的HQL),那么iterate()的执行ƈ不再像前面介l的那样?x)比find()Ҏ(gu)多执行SQLQ而是Ҏ(gu)再执行一条SQL。这是iterate()Ҏ(gu)的用。它使用?jin)Hibernate~存机制.Find()Ҏ(gu)在查询出l果后把查询l果集置入缓存,而iterate()执行的时候先执行一条Select SQL,查询所有符合条件的l果集,接下来iterate()Ҏ(gu)查询的id在本地缓存中查找W合条g的结果集Q如果有完全W合条g的结果集Q则直接以此作ؓ(f)q回l果。如果没有找到再执行相应的SQL,q且把结果纳入缓存当中。以备?br />


3.~存机制q不对find()Ҏ(gu)起用。如果你两次执行相同条g的或相近条g的HQLQ第二个Ҏ(gu)的SQLq不减少。还?x)照常执行。这是说缓存机制ƈ不对find()Ҏ(gu)起作用。find()对缓存只写不读,而iterate()Ҏ(gu)可以充分利用缓存的优势?br />
4.内存斚w的考虑Q除?jin)缓存的优势之外Q我们还可以利用iterate()与evict()Ҏ(gu)来提升查询性能上的优势?br />
     q个问题主要是大数据量所带来的考虑。因为find()Ҏ(gu)可以对大数据量的l果集进行缓存,但是如果数据量超大的话,也会(x)带来内存溢出斚w的问题。利用iterate(),evict()可以对记录进行逐条处理Q将内存消耗保持在可接受的范围之内?br />
  它包括从session中消除对对象Q及(qing)从sessionFactory当中消除对象?/p>

5. 对于find()Ҏ(gu)在读取缓存问题方面的解决。Query Cache是一个解x案,不过目前的用受限比较大?br />
    使用Query Cache的条件是Q?br />
      A。数据库表结构不变。即未发生过update,insert,delete{操?br />
      B。相同的HSQL的重复执行操作?br />
׃以上两个原因Qquery Cache的用上受到?jin)很?的限制?br />
如果想用query cache我们需要配|?hibernate.cfg.xml文gQ?br />
<class ......>

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

</class>



在编码当中用:(x)Query.setQueryCache(true);卛_?br />



水煮三国 2006-07-25 16:03 发表评论
]]>
POJO与PO的概느?/title><link>http://www.tkk7.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.tkk7.com/os586/archive/2006/07/25/59911.html</guid><wfw:comment>http://www.tkk7.com/os586/comments/59911.html</wfw:comment><comments>http://www.tkk7.com/os586/archive/2006/07/25/59911.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/os586/comments/commentRss/59911.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/os586/services/trackbacks/59911.html</trackback:ping><description><![CDATA[ <span id="dsudmdu" 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没有增加别的属性和Ҏ(gu)。全都是q样子的Q?<br /><br /><br /></span> <table cellspacing="1" cellpadding="3" width="90%" align="center" border="0"> <tbody> <tr> <td> <span id="yoeydcw" 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="zlnwuwy" class="postbody"> <br /> <br />--------------------------------------------------------------------------- <br />首先要区别持久对象和POJO?<br /><br />持久对象实际上必d应数据库中的entityQ所以和POJO有所区别。比如说POJO是由new创徏Q由GC回收。但是持久对象是insert数据库创建,由数据库delete删除的。基本上持久对象生命周期和数据库密切相关。另外持久对象往往只能存在一个数据库Connection之中QConnnection关闭以后Q持久对象就不存在了(jin)Q而POJO只要不被GC回收QL存在的?<br /><br />׃存在诸多差别Q因此持久对象PO(Persistent Object)在代码上肯定和POJO不同Qv码PO相对于POJO?x)增加一些用来管理数据库entity状态的属性和Ҏ(gu)。而ORMq求的目标就是要PO在用上量和POJO一_(d)对于E序员来_(d)他们可以把PO当做POJO来用Q而感觉不到PO的存在?<br /><br />JDO的实现方法是q样的:(x) <br />1、编写POJO <br />2、编译POJO <br />3、用JDO的一个专门工P叫做EnhancerQ一般是一个命令行E序Q手工运行,或者在ant脚本里面q行Q对POJO的class文g处理一下,把POJO替换成同名的PO?<br />4、在q行期运行的实际上是POQ而不是POJO?<br /><br />该方法有点类gJSPQJSP也是在编译期被{换成Servlet来运行的Q在q行期实际上q行的是ServletQ而不是JSP?<br /><br />Hibernate的实现方法比较先q:(x) <br />1、编写POJO <br />2、编译POJO <br />3、直接运行,在运行期Q由Hibernate的CGLIB动态把POJO转换为PO?<br /><br />由此可以看出Hibernate是在q行期把POJO的字节码转换为PO的,而JDO是在~译期{换的。一般认为JDO的方式效率会(x)E高Q毕竟是~译期{换嘛。但是Hibernate的作者Gavin King说CGLIB的效率非怹高,q行期的PO的字节码生成速度非常之快Q效率损失几乎可以忽略不计?<br /><br />实际上运行期生成PO的好处非常大Q这样对于程序员来说Q是无法接触到PO的,PO对他们来说完全透明。可以更加自q以POJO的概忉|UPO。另外由于是q行期生成POQ所以可以支持增量编译,增量调试。而JDO则无法做到这一炏V实际上已经有很多h在抱怨JDO的编译期Enhancer问题?jin),而据说JBossDO采用运行期生成PO字节码,而不采用~译期生成PO字节码?<br /><br />另外一个相关的问题是,不同的JDO产品的Enhancer生成的PO字节码可能会(x)有所不同Q可能会(x)影响在JDO产品之间的可UL性,q一Ҏ(gu)点类似EJB的可UL性难题?<br /><br />----------------------------------------------------------------------------------- <br />p个问题另外引Z个JDO的缺陗?<br /><br />׃JDO的PO状态管理方式,所以当你在E序里面get/set的时候,实际上不是从PO的实例中取valuesQ而是从JDO StateManager中取出来Q所以一旦PM关闭QPO׃能进行存取了(jin)?<br /><br />在JDO中,也可以通过一些办法得PO可以在PM外面使用Q比如说定义PO是transient的,但是该PO在PM关闭后就没有PO identity?jin)。无法进行跨PM的状态管理?<br /><br />而Hibernate是从PO实例中取values的,所以即使Session关闭Q也一样可以get/setQ可以进行跨Session的状态管理?<br /><br />在分多层的应用中Q由于持久层和业务层和web层都是分开的,此时Hibernate的PO完全可以当做一个POJO来用Q也是当做一个VOQ在各层间自׃递,而不用去Session是开q是兟뀂如果你把这个POJO序列化的话,甚至可以用在分布式环境中。(不适合lazy loading的情况)(j) <br /><br />但是JDO的PO在PM关闭后就不能再用?jin),所以必dPM关闭前把PO拯一份VOQ把VO传递给业务层和web层用。在非分布式环境中,也可以用ThreadLocal模式保PM始终是打开状态,来避免每ơ必进行PO到VO的拷贝操作。但是不怎么_(d)qL权宜之计Q不如Hibernate的功能强?/span> <img src ="http://www.tkk7.com/os586/aggbug/59911.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/os586/" target="_blank">水煮三国</a> 2006-07-25 09:08 <a href="http://www.tkk7.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.tkk7.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.tkk7.com/os586/archive/2006/07/20/59237.html</guid><wfw:comment>http://www.tkk7.com/os586/comments/59237.html</wfw:comment><comments>http://www.tkk7.com/os586/archive/2006/07/20/59237.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.tkk7.com/os586/comments/commentRss/59237.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/os586/services/trackbacks/59237.html</trackback:ping><description><![CDATA[ <p>xmlBuddy2.0.72是支持Eclipse3.1版的。但是在下蝲?jin)xmlbuddy后解压后把解压后的文件复制到Eclipse下的plugins下却不显C?br /><br />一直认为xmlBuddy2.0.72可能不支?.1的EclipseQ后来上|上看资料后认是支持的?br /><br />但是启动?jin)N遍eclipse也不能找到xmlbuddy的两个图标?br /><br />后来Q看见网上也有相似的问题发生?br /><br />解决的办法是在eclipse的启动参数后面加?-clean后就可?/p> <img src ="http://www.tkk7.com/os586/aggbug/59237.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/os586/" target="_blank">水煮三国</a> 2006-07-20 17:16 <a href="http://www.tkk7.com/os586/archive/2006/07/20/59237.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从今儿开始学?fn)Hibernatehttp://www.tkk7.com/os586/archive/2006/06/26/55059.html水煮三国水煮三国Mon, 26 Jun 2006 01:02:00 GMThttp://www.tkk7.com/os586/archive/2006/06/26/55059.htmlhttp://www.tkk7.com/os586/comments/55059.htmlhttp://www.tkk7.com/os586/archive/2006/06/26/55059.html#Feedback3http://www.tkk7.com/os586/comments/commentRss/55059.htmlhttp://www.tkk7.com/os586/services/trackbacks/55059.html对Java的理解还不是太深,现在看到那么多的开源工??j)里很?

大家对Struts,Spring,Hibernateq些开源工h怎样理解?

我对Strutsq是?jin)解一?但是对Spring,Hibernateq不是很?jin)?

如果有一起学?fn)这些工L(fng)|友?

我们可以在这里交学?/p>

水煮三国 2006-06-26 09:02 发表评论
]]>
վ֩ģ壺 ľþþƷ1| 99Ʒѹۿ| ޹Ʒyw߹ۿ| һƷ˾þ| ޹Ʒ˾Ʒ| ɫػaëƬѹۿ| ޾Ʒѹۿ| ԭƵ| ִˬֻƵƵ| ѿڿŮ| ŷ У԰| þþƷ޾Ʒɫ| ˾Ʒձվ| av߹ۿҰ| һ| Ƶ| av߹ۿַ| ɫͼƵ߹ۿ| avһ | ޺Сvideos| һ| ޸һ| ձѵӰһ| ձvƬһ| ҹƬ7777| Ұ߹ۿ| 99re6ƵƷѹۿ| Ʒ99Ʒþ| aëƬ| vAѾƷ߹ۿ| պëƬһ| ҳƵ߹ۿ| ѴƬ߹ۿcom| ѹۿƵ| һۺ| ޹Ʒ˾þõӰ| þԭavapp| avպav߹ۿ| ޹һ| ޾ƷĻAV| ѹۿƵ|