一、多对一的问题
比如某个地址可以被多个人引用:张三住在北京中关村,李四也住在北京中关村,这里面地址就是一的一端,人就是多的一端。
建立如下的两个类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属性即可,这时候user和address之间就是一对一的关系,即一个人对应一个地址
基于逐渐的单向一对一关联
<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的引用
浙公网安备 33010602011771号