hibernate 一对一 怎样实现更好

hibernate提供两种一对一的方式

这里为了说明我们用一个小型的新闻表进行说明

第一种
其真实意义上的一对一,副表通过主键与主表的主键进行关联,两个主键是相同。

我们来看一上hbm.xml配置
    <!-- 新闻 -->
    <class name="News" table="SITE_NEWS" lazy="true" >
        <id name="nid">
   <generator class="increment" ></generator>
</id>

<natural-id mutable="true">
    <property name="title"  />
</natural-id>

        <one-to-one name="content" class="NewsContent" cascade="all" />

    </class>

    <!-- 新闻内容 -->
    <class name="NewsContent" table="SITE_NEWS_CONTENT" lazy="true" >
        <id name="did">
           <generator class="foreign">
               <param name="property"> news</param>
           </generator>
</id>

        <one-to-one name=" news" class="News" constrained="true"  />

    </class>


这段配置中最不好理解的是两个地方,其是"新闻内容"的主键生成方式"foreign"和约速constrained。
foreign主键生成方式,其参数property指向其自身配置的一个属性,而这个属性应是一个指向主表定义,也就是说在这个NewsContent类,一定要定义news属性,不管其有没有用。这样通过news就可以得到主键,从而赋值给本副表,完成其主键的生成。这里constrained在本表中一定是true,其声明本表是副表,需要引用约束完成性。其时声明constrained="true"的属性是可以延迟加载,以本例说,NewContent实例的news属性是可以延迟加,但在一般情况下没什么用。

这是一个很典型的一对一关联。其好处是两个表通过主键进行关联,没有什么多余的外键字段,但其也有一个最大的问题,就是News不法实现对content的延迟加载,而这往往是我们最需要的。

第二种

主键通过外键与副表进行关键,单从xml的配置定义上看不像一对一,但其确实实现了一对一。

hbm.xml配置如下:

    <!-- 新闻 -->
    <class name="News" table="SITE_NEWS" lazy="true" >

        <id name="nid">
<generator class="increment" >
</generator>
</id>

<natural-id mutable="true">
    <property name="title"  />
</natural-id>

<many-to-one name="content" column="tid" unique="true" not-null="true" cascade="save-update,delete"/>

    </class>

    <!-- 新闻内容 -->
    <class name="NewsContent" table="SITE_NEWS_CONTENT" lazy="true" >

        <id name="tid">
<generator class="increment" >
</generator>
</id>

<property name="htmlText" column="html_text" type="org.springframework.orm.hibernate3.support.ClobStringType"/>


    </class>

这个配置中我们重要关心主表配置,这里有两个配置有点意思,就是unique="true"和not-null="true",这正是一个主键的声明要求,为一并不为空。这时用一个多对一,来表示一对一关系。而副表,则不需要再引用news类,这是一个单向关联。其时我就的这是最好的,因为在一对一关联中,副表其时就是主表的辅助,通过主表类什么都可以查到,而没有必要从副表查找主表。

这里还有一个最大的好处就是,news可以对content进行延迟加载,这太好了,因为在这里划分副表(NewsContent)的意思就在于,对content的延迟加载。大家想想,在查看某个栏目的新闻列表时,对content属性延迟加载(默认),在查看某个新闻时再通过getContent得到某个新闻的内容。

如果你再建一个副表,只存放那些动态数据,不可被缓存的数据(例如:浏览次数),把News和NewsContent都定义到二级缓存中,用户查看新闻时,只修改NewsBrowseCount表。


 

你可能感兴趣的:(xml,Hibernate)