论坛首页 Java企业应用论坛

提问:关于使用lazy

浏览 12273 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-05-31  
在我的一个项目中使用了struts, hibernate. 当每次需要存取数据库时,我都先获得一个Session,用完之后,立即关闭。由于类之间的关系比较复杂,其中一个类表示一个呼叫记录(CallRecord),每个呼叫记录又包含呼叫目的(Purpose), 接话人(Agent), 客户(Caller) ... ... ,  而Purpose 又是树形结构(如整个Purpose分为抱怨,购物等几个大类, 而每个大类又分成几个小类,如抱怨又分为抱怨服务态度,抱怨送货迟到等。。。, 小类又可以再分为更小的类,这样最深达到5层),

public class CallRecord();{
  private int id;
  private Purpose purpose;
  private Agent agent;
  private String content;
  
  ... ...

}

public class Purpose();{
  private int id;
  private Purpose parent;
  private List children;
  private String desc;
  ... ...
}

配置文件

<class name="CallRecord" table="CallRecord">
  <id column="id" length="11" name="id" type="integer">
    <generator class="native"/>
  </id>	
  <many-to-one class="Purpose" column="purposeID" name="purpose" not-null="true" unique="true"/>	
  <many-to-one class="Agent" column="agentID" name="agent" not-null="true" unique="true"/>	
  <property column="content" length="500" name="content" type="string"/>
... ...
</class>


<class name="Purpose" table="Purpose">
  <jcs-cache usage="read-only"/>
    <id column="id" length="11" name="id" type="integer">
    <generator class="native"/>
  </id>
  <many-to-one class="Purpose" column="parent" name="parent" not-null="false" unique="false"/>		
  <list name="children" cascade="all" inverse="true" lazy="false">
            <key column="parent"/>
            <index column="itemIndex"/>
	    <one-to-many class="Purpose"/>
  </list>
  。。。 。。。
</class>


实际的类比上面的复杂的多。

由于我在查询CallRecord的时候并不知道哪些相关的Object是在业务层或表现层用不到的(如在有些情况下需要用到CallRecord中Purpose的信息, 在另外的情况下我又不需要Purpose信息)。所以,在配置文件中我都使用的是lazy="false", 这样所有与CallRecord相关的信息(如lPurpose信息)都取出来了,业务层或表现层想用的任何相关信息都可以从一个CallRecord目标来获得。

当然问题很明显,做一次这样的查询,要很多次访问数据库,速度就明显的受到影响。

所以就想到延迟加载,设置Lazy="true",  在一个request提交时,获得一个Session, 在request结束前关闭Session.  这样在需要的时候才加载其他信息。由于实际上只有在view层/business层才能知道哪些相关信息是需要的,但是很多人都在强调不应该把PO直接传给View层使用,所以如果我把PO转化为VO或DTO之后再传给View层的话,延迟加载就不能发挥作用。

大家是怎样解决这个问题的呢?



   发表时间:2005-06-01  
Open Session In View
0 请登录后投票
   发表时间:2005-06-01  
很明显 你的事务分析有问题,, 其实你只要根据查询条件取得你的CallRecord 记录。 然后根据你的事务走向, 取得相应的set 或者其他的object. 你甚至可以只传递你的CallRecordPP_id.然后根据事务的目的,分布处理。 不存在传递po的问题,也决不影响效率。

顺便强烈BS 楼上这种废话似地回帖。
0 请登录后投票
   发表时间:2005-06-01  
谢谢你的回答!

但我发现这样好像不是很舒服,比如我是否要在CallRecord 类中去掉Purpose purpose 属性,而代之以int purposeID呢?当在View层需要purpose信息时,再根据CallReocrd.porposeID去取得Purpsoe呢?

也可能是我没有理解您的意思,能就我上面的两个类和配置说一下你会怎样修改呢?
0 请登录后投票
   发表时间:2005-06-01  
suggestion:

add a table  "CallRecord_Purpose" like:
               id,
               CallRecord_id,
               purpose_id;

cuz your  Purpose table has many  static data. but you only use the purpose belong to the specify  CallRecord.

sorry  cant  type chinese  temp
0 请登录后投票
   发表时间:2005-06-02  
在我的CallRecord表中已经有个字段叫PurposeID, 而且, CallRecord与Purpose是多对1的关系,所以这样一个中间表的意义是什么我不知道。能具体点吗?

希望有更多的人参与进来。
0 请登录后投票
   发表时间:2005-06-02  
houwei 写道
很明显 你的事务分析有问题,, 其实你只要根据查询条件取得你的CallRecord 记录。 然后根据你的事务走向, 取得相应的set 或者其他的object. 你甚至可以只传递你的CallRecordPP_id.然后根据事务的目的,分布处理。 不存在传递po的问题,也决不影响效率。

顺便强烈BS 楼上这种废话似地回帖。


我看不出你所说的在思想上和2搂的有什么区别   而且二楼已经提供了关键字  楼主可以通过搜索的方式取得答案

而且后来所加的table...  why?楼主需要的完全是数据传递方式   难道通过修改库表结构可以解决VIEW层的问题么?

楼主的lazy问题在h3里已经解决  采用filter来实现session per request,或者直接使用Spring
0 请登录后投票
   发表时间:2005-06-02  
我只是发现你的purpose  似乎是静态数据。 也就是说你并不更新。只是使用。所以建议你加一个表 存储相关的信息 而不需要load整个纪录
0 请登录后投票
   发表时间:2005-06-02  
引用
我只是发现你的purpose 似乎是静态数据。 也就是说你并不更新。只是使用。所以建议你加一个表 存储相关的信息 而不需要load整个纪录


即使Purpose是静态的数据,也看不出增加新表有任何意义, 谢谢你 Houwei, 这么耐心的帮我想解决办法,继续。

采用filter来实现session per request,我已经在这么做,(虽然对此我也有些疑问,但是与该主题关系不大)。

bluemeteor 非常了解我的意思,我的问题在于
1。大家(包括我)几乎都认为PO不应该被传到View层;
2。只有View层知道PO中的某些属性(如CallRecord.purpose)是否要用到;
3。如果要用Lazy, 我就要把PO传到View层;

3和1就是矛盾。

希望解决这个矛盾,这是关键。
0 请登录后投票
   发表时间:2005-06-02  
为什么一定要死记公式.
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics