一、多对一的问题

比如某个地址可以被多个人引用:张三住在北京中关村,李四也住在北京中关村,这里面地址就是一的一端,人就是多的一端。

建立如下的两个类person和address

Person{

Private Integer id;

Private String name;

Private Address address;

//在多的一端添加属性(address类)

}

Address{

 Private Integer addressed;

Private String addressDetail;

}

接下来配置两者的映射文件

Address类的映射文件

<hibernate-mapping>

    <class name="manytoone.address" table="testaddress" catalog="friend">

        <id name="addressId" type="java.lang.Integer">

            <column name="address_id" />

            <generator class="identity"></generator>

        </id>

        <property name="addressDetail" type="string"></property>

    </class>

</hibernate-mapping>

User类的映射文件

<hibernate-mapping>

    <class name="manytoone.user" table="testuser" catalog="friend">

        <id name="id" type="java.lang.Integer">

            <column name="id" />

            <generator class="identity"></generator>

        </id>

        <property name="name" type="string"></property>       <many-to-one name="address" class="manytoone.address" cascade="all" column="address_id"></many-to-one>

    </class>

</hibernate-mapping>

在一的一端也就是user类的映射文件中指定引用的类,同时指定引用的外键 address_id

则在实际建表是会在user表中创建一个外键列address_id,它引用address表中的address_id列。

开启hibernate的自动建表hbm2ddl属性设为update,实际表如下所示

 

 

如果想要定义一对一的关系,只需要在多的一端many-to-one后面加上unique=true属性即可,这时候useraddress之间就是一对一的关系,即一个人对应一个地址

基于逐渐的单向一对一关联

<hibernate-mapping>

    <class name="manytoone.user" table="testuser" catalog="friend">

        <id name="id" type="java.lang.Integer">

            <column name="id" />

            <generator class="foreign">

 <param name=”property”>address</param>

//基于主键关联时,主键生成策略是foreign,表明根据关联类的主键生成该实体的主键

</generator>

        </id>

        <property name="name" type="string"></property>       <many-to-one name="address" class="manytoone.address" cascade="all" column="address_id"></many-to-one>

    </class>

</hibernate-mapping>

三、单向一对多的关联映射

 

假如一个人可以有多个住址,即user是一的一端,address是多的一端

修改两个类如下所示:

Class user{

 Private Integer id;

Private String name;m

Private int age;

Private Set<address> addresses=new HashSet<address>();

}

Address类如下:

Class address{

 Private Integer addressed;

Private Stirng addressDetail;

Private user u;

}

User的映射文件如下所示:

<hibernate-mapping>

    <class name="manytoone.user" table="testuser" catalog="friend">

        <id name="id" type="java.lang.Integer">

            <column name="id" />

            <generator class="identity"></generator>

        </id>

        <property name="name" type="string"/>

        <property name="age" type="int"></property>

//addresses属性用set来设置

       <set name="addresses" inverse="true">

        <key column="id"/>

        <one-to-many class="manytoone.address"/>

       </set>

    </class>

</hibernate-mapping>

Address的映射文件如下所示

<hibernate-mapping>

    <class name="manytoone.address" table="testaddress" catalog="friend">

        <id name="addressId" type="java.lang.Integer">

            <column name="address_id" />

            <generator class="identity"></generator>

        </id>

        <property name="addressDetail" type="string"></property>

        <many-to-one name="u" class="manytoone.user" column="id" not-null="true"/>

    </class>

</hibernate-mapping>

 

Transaction tx=session.beginTransaction();

   tx.begin();

    user u=new user();

    u.setName("jhon");

    u.setAge(23);

    session.save(u);

    address a=new address("广州天河");

    a.setU(u);

    session.persist(a);

    address a2=new address("北京海淀区");

    a2.setU(u);

    session.persist(a2);

tx.commit();

一般情况下,不应该让1的一端控制关联关系,而应该由N的一端来控制关联关系。我们可以在<set/>元素中指定inverse=true,用于指定1的一端不控制关联关系。

上面是测试数据,由于address是主表,它引用了user表的id作为外键,先保存一个user,然后新建address属性通过setU()方法来指定address的引用

posted on 2013-11-04 15:17  物是人非CJT  阅读(222)  评论(0)    收藏  举报