`
wumingdlz
  • 浏览: 32872 次
  • 性别: Icon_minigender_1
  • 来自: 江苏
最近访客 更多访客>>
社区版块
存档分类
最新评论

one-to-one的效率问题,用one-to-many来替代?

阅读更多
one-to-one的效率问题,用one-to-many来替代?
         由于最近在把以前的一个设计移到hibernate上来,所以需要用到one-to-one,因为在以前的设计中需要用到在一个主表中对于多个子表的主键关联,所以一开始就想到了one-to-one的应用,觉得这样解决不但不会引起以前数据设计的改变,也能够很好的利用 hibernate所带来的OR优势,可是当实际使用的时候发现,在插入数据的时候可以有选择的在任意子表中进行插入,所有的结果都在原来的预期之中,但是在查询的时候,比如说只查询主表中的内容

         From tableMain

仅仅执行看起来十分简单的一条语句,你所期望的是他紧紧查询T_MAIN这张主表,可是结果确实hibernate通过多个外连接将所有的子表一口气的全部查询出来

         select * from t_main main outer join t_sub1 sub1 on main.id = sub1.id outer join t_sub2 sub2 on main.id = sub2.id...

  如此的效率绝对让你头痛不已,不仅如此,如果你通过首先获得子表t_sub1的某个主键ID,然后通过这个主键查询出子表对象,在关联至住表,同样的情况又会发生,又会生成类似的SQL语句,这样一来看来对于这个设计应用one-to-one本身就是一种错误,是这样吗?

          或许有人认为我们在每个one-to-one中加入lazy="true"这个属性会杜绝上述情况的发生,经过笔者的证实即便你加入了lazy= "true",也不会带来任何的改变;又或者在hibernate.config中加入fetch depth属性以及在每个关联中设置outer-join="false",这些都不会引起本质上的变化,加入outer-join="false"其实结果只是将原有的outer join语句改变成多条sql语句而已,并没发生什么本质变化,反而效率更低了。

         该怎么办呢?我们先仔细研究一下one-to-one的概念,one to one代表一对一,在一般的模型中很少会遇到one-to-one这种概念,因为他十分强调一对一的概念,就好比一个人他只有一个身体和一个头而已,头和身体是十分好的例子,因为有身体必定只有一个头,而且说到了身体必定要说头,就好像看了某个女孩的身材必定想知道她的长相如何(-_-),所以在这时我们使用one-to-one,因为这种一对一的关系是很强的,而且从对象中取得body必定会取得他所关联的head,这样的情况下使用outer- join是十分方便和有效率的,因为它使用了outer join查询从而避免了两条到数据库的查询语句,而且在这种情况下也只需要在body_hbm.xml中设置一个one-to-one即可,所以在这种确实是一对一而且在主表中一对一的关联个数(即主表中one-to-one标签)十分少的情况下,使用one-to-one是一种很不错的解决办法。

          如果一个主表会对多个子表都进行one-to-one关联呢,就像我们一开始遇到的这种情况,比如你不仅仅只想了解那个你中意的女孩的身材和脸蛋,而且还想知道他的学历,身世等等一切,在这种情况下,如果我们都是用多个one-to-one在主表中的话,那情况正如我们一开始看见的,是十分可怕的,该怎么做呢?不妨考虑一下使用one-to-many,什么,many?一开始听到many这个词的时候,我也觉得挺惊讶的这明明是多个一对一的关联为什么要用到many呢?其实many并没有一定要说是大于一的,你就只在它的many中存在一个关联它有能乃你何呢?如果用到many的话,我们就需要改动数据表的设计了,在每个有关连的子表中加入一列main_id代表主表中该记录的主键子段值,只需要这样子改动就可以了,这样所带来的效果绝对是值得你这样做的,然后我们就按照以往的one-to-many来设计就好了

         在body.hbm.xml加入(一到head的关联举例,其他的关联按照这样的格式添加即可)
         <set name="head" inverse="true" lazy="true" cascade="all-delete-orphan">
            <key column="ID0000"/>
            <one-to-many class="com.xx.Head"/>
          </set>

         在head.hbm.xml加入
         <many-to-one name="body" column="ID0000" class="com.xx.Body" not-null="true"/>

          行了,经过上面的改动我们就摆脱了查询时多个outer-join的困扰,只在需要的时候才对子表进行查询,因为设置了lazy="true",所以一切的一切都在我们的预料之中,我们如果希望获得body的话hibernate绝对不会把它的head 也查询出来,节省了查询是所需要的负担,除非到了我们十分需要head的情况才会进行关联查询,获得所需要的head结果。

         所以由此看来在one-to-one这种一对一的关系不是很强的情况下,或者是在一张表中存在多个one-to-one的情况下,使用one-to-many来代替one-to-one不失为一种不错的做法,当然更重要的良好的数据库设计,hibernate毕竟只是末,千万不要本末倒置。
     

posted on 2005-03-30 13:26 一个人的日子,我独来独往 阅读(526) 评论(4)  编辑 收藏 收藏至365Key

FeedBack:
# re: one-to-one的效率问题,用one-to-many来替代?
2005-06-30 14:28 | dean
You can also use join to avoid modifying the existing database schema (but will add an associating table):

<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<join table="PersonAddress" optional="true">
<key column="personId" unique="true"/>
<many-to-one name="address" column="addressId"
not-null="true"/>
</join>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>

create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null primary key, addressId bigint not null )
create table Address ( addressId bigint not null primary key )
 
# re: one-to-one的效率问题,用one-to-many来替代?
2005-07-02 22:05 | ramon
if there is sth u want to say, speak it in Chinese next time please
 
# re: one-to-one的效率问题,用one-to-many来替代?
2005-08-30 21:57 | Roberto Sweater
一个月前Gavin King 在hibernate3.1 beta2 中进行了修改
Created: 23/Jul/05 06:24 PM Updated: 30/Jul/05 12:11 AM

http://opensource2.atlassian.com/projects/hibernate/browse/HHH-786?page=all

sswt163@gmail.com

 
# one-to-one的效率问题,用one-to-many来替代?
分享到:
评论

相关推荐

    XDoclet Tags

    8. **@many-to-one**: 表示多对一的关系,通常用在“多”的一方,指向“一”的一方。 9. **@many-to-many**: 定义多对多的关联,需要通过中间表进行关联管理。 10. **@collection**: 用于定义集合类型的属性,如...

    Hibernate中文API大全

    这个时候你就应该考虑一下使用one-to-many关联是否会更恰当。 尝试对这个组合元素重新建模为一个实体-但是需要注意的是,虽然Java模型和重新建模前是一样的,关系模型和持久性语义会有细微的变化。 请注意如果你...

    SSH面试题大全.doc

    Hibernate支持四种关联关系:一对一(one-to-one)、一对多(one-to-many)、多对一(many-to-one)和多对多(many-to-many),这些关联关系允许对象模型和数据库模型之间的复杂映射。 4. Hibernate的缓存机制: ...

    hibernate总结

    - **一对一(One-to-One)**:这种关系可以通过在双方类中都添加`@OneToOne`注解来建立,通常使用`@JoinColumn`指定外键所在的列。如果关系由一方维护,可以在另一方使用`@MapsId`来共享同一主键。 - **一对多...

    java与ssh面试题总结

    Hibernate支持四种关联关系:一对一(one-to-one)、一对多(one-to-many)、多对一(many-to-one)和多对多(many-to-many)。 4. **Hibernate的缓存机制**: Hibernate有一级缓存和二级缓存。一级缓存是每个...

    SSH面试总结 struts spring hibernate 面试

    - **一对多(one-to-many)**:一个实体可以与多个其他实体关联。 - **多对多(many-to-many)**:多个实体之间相互关联。 - **多对一(many-to-one)**:多个实体关联到另一个实体上。 - **实现方式**:通过`@...

    java软件工程师面试题库

    2. **一对多(One-to-Many)**:使用`&lt;one-to-many&gt;`标签定义。通常情况下,这种关系会对应于数据库中的外键关系。 3. **多对多(Many-to-Many)**:通过`&lt;many-to-many&gt;`标签定义。在数据库中,这通常会涉及一个...

    ssh框架.doc

    同样,我们可以使用`one-to-many`标签来映射这种关系。双向关联则意味着User和Group之间存在双向的引用,双方都可以获取对方的信息,这需要在两个实体类的映射文件中同时配置`many-to-one`和`one-to-many`标签,并...

    Apress.Pro.JPA.2.2nd.Edition.Oct.2013

    2. **实体映射**:讲解如何使用注解或XML来定义实体类,将Java对象与数据库表进行映射,包括主键(Primary Key)、关系映射(One-to-One, One-to-Many, Many-to-One, Many-to-Many)等。 3. **查询语言**:探讨JPQL...

    Hibernate笔试题加答案

    ### Hibernate笔试题解析 ...- **B)** `&lt;one-to-many&gt;`:这是不完整的描述,实际上应该放在`&lt;set&gt;`元素内部使用。 - **C)** `&lt;many-to-one&gt;`:这是不正确的,用于映射多对一的关系。 **正确答案:AB**

    Hibernate笔试题及答案

    - **解析**:在Hibernate配置中,class属性用于指定关联对象的类名,但在`&lt;one-to-many&gt;`节点中,正确的用法是使用`class`而非`type`。另外,column属性通常用于单向关联中的外键字段配置,而在此处,它不应出现在`...

    2022年StrutsHibernateSpring经典面试题收藏.doc

    在Hibernate中,通过配置文件的mapping元素,如many-to-one、one-to-many、many-to-many、one-to-one,可以实现不同类型的类间关系,如一对一、一对多、多对多。 Hibernate的缓存机制包括一级缓存(Session内部缓存...

    三大框架常问问题

    - **多对一**:使用`&lt;many-to-one&gt;`标签配置。 #### 四、Hibernate 的缓存机制 - **一级缓存**:存在于Hibernate Session中的缓存,属于事务级别缓存。 - **二级缓存**:可以在不同的Session之间共享数据,提高...

    struts+spring+hibernate资料

    - **一对一 (One-to-One)**:虽然通常推荐使用多对一 (Many-to-One) 替代,但在特定场景下也可以通过 `&lt;one-to-one&gt;` 元素定义。 #### 4. Hibernate 的缓存机制 **内部缓存(一级缓存)**:默认情况下,Hibernate ...

    Struts + Hibernate + Spring

    - **Many-to-One**:多对一关系。 - **Many-to-Many**:多对多关系。 **5. Hibernate 缓存机制** - **一级缓存**:默认启用,作用域为 Session 级别。 - **二级缓存**:需手动配置,作用域为整个应用程序级别。 *...

    javaWEB开发SSH面试题总结

    - **One-to-Many (一对多):** - 表示一个实体与多个实体之间的关系。 - 实现时通常会在“多”的一方添加外键指向“一”的一方。 - **Many-to-One (多对一):** - 与一对多相反,表示多个实体与一个实体之间的...

    hibernate题目

    10. **集合属性映射**:在 Customer.hbm.xml 文件中,用于映射 orders 属性,应使用 `&lt;set&gt;` 元素(A选项正确)来表示集合,并且需要一个 `&lt;one-to-many&gt;` 子元素来指定与之关联的 Order 类(B选项正确)。`&lt;many-to...

    高考英语一轮复习 Unit2精品导学案 译林牛津版必修3 学案.doc

    - adopt(采纳、收养)指接受并使用新的观点或孩子,如:Many people want to adopt homeless children from Sichuan. - adapt(适应、改编)指调整自己以适应环境或改变原有的内容,如:She had to adapt herself...

    struts sping hibernate 面试总结

    3. 尽量避免一对一关系,用多对一替代,因为一对一通常效率较低。 4. 配置对象缓存,避免使用集合缓存,因为集合缓存可能导致数据一致性问题。 5. 一对多集合推荐使用`Bag`,多对多集合使用`Set`,以保持元素唯一性...

    ssh(struts、spring、hibernate)面试题

    3. **关系映射**:Hibernate支持一对一、一对多、多对一和多对多等各种关系映射,通过配置文件中的many-to-one、one-to-many、many-to-many等标签实现。 4. **缓存机制**:包括一级缓存(内部缓存)和二级缓存。一级...

Global site tag (gtag.js) - Google Analytics