之前讲过一对多映射,现在说一下其他的映射关系。这里包括一对一映射和多对多映射。
其中一对一映射一般分为两种形式:按照主键映射、按照外键映射。
一、按照主键映射:这里按照主键映射是指让两个表格的主键值相同。这里以用户地址映射为例来说明,这里把用户和地址设计成一对一映射关系。
1.新建工程:Hibernate08;
2.新建用户类:User,这个类包括id,用户名,用户地址三个属性。其中地址属性是一个地址类对象。
package com.test.model;
public class User {
private int id;
private String name;
private Address address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
3.新建地址类:包括id,地址,邮编,用户四个属性。其中用户是一个User类对象。
package com.test.model;
public class Address {
private int id;
private String address;
private String zipcode;
private User user;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
4.编写User类映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.test.model">
<class name="User" table="t_user">
<id name="id" column="userId">
<generator class="native"></generator>
</id>
<property name="name" column="userName"></property>
<one-to-one name="address" class="com.test.model.Address" cascade="all"></one-to-one>
</class>
</hibernate-mapping>
这里使用<one-to-one>标签来表示一对一映射关系。这里cascade值为all,表示级联删除、添加等操作一起执行。
5.编写地址类Address的映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.test.model">
<class name="Address" table="t_address">
<id name="id" column="addressId">
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>
<property name="address" column="address"></property>
<property name="zipcode" column="zipcode"></property>
<one-to-one name="user" class="com.test.model.User" constrained="true"></one-to-one>
</class>
</hibernate-mapping>
这里Address的主键属性设置为foreign,表示既是主键又是外键,与user属性表格的主键关联。在<one-to-one>标签中设置constrained=true,是约束两者共享主键,两者的主键值相同。
6.写配置文件hibernate.cfg.xml:
<session-factory>
<!--数据库连接设置 -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<!-- 方言 -->
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 控制台显示SQL -->
<property name="show_sql">true</property>
<!-- 自动更新表结构 -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="com/test/model/User.hbm.xml"/>
<mapping resource="com/test/model/Address.hbm.xml"/>
</session-factory>
7.写测试方法:
package com.test.service;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.test.model.Address;
import com.test.model.User;
import com.test.util.HibernateUtil;
public class UserTest {
private SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
private Session session;
@Before
public void setUp() throws Exception {
session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
}
@After
public void tearDown() throws Exception {
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
}
@Test
public void testSave1(){
User user = new User();
user.setName("张三");
Address address = new Address();
address.setAddress("在那桃花盛开的地方");
address.setZipcode("123456");
address.setUser(user);
user.setAddress(address);
session.save(user);
}
}
运行方法testSave1,看一下生成的数据库表的结构:
数据表中的数据为:
二、按照外键映射:通过外键实现两个表的关联关系
1.新建用户类User2:
package com.test.model;
public class User2 {
private int id;
private String name;
private Address2 address2;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address2 getAddress2() {
return address2;
}
public void setAddress2(Address2 address2) {
this.address2 = address2;
}
}
2.新建地址类Address2:
package com.test.model;
public class Address2 {
private int id;
private String address;
private String zipcode;
private User2 user2;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public User2 getUser2() {
return user2;
}
public void setUser2(User2 user2) {
this.user2 = user2;
}
}
3.写User2类的映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.test.model">
<class name="User2" table="t_user2">
<id name="id" column="userId">
<generator class="native"></generator>
</id>
<property name="name" column="userName"></property>
<many-to-one name="address2" class="com.test.model.Address2" column="addressId" cascade="all" unique="true"></many-to-one>
</class>
</hibernate-mapping>
这里要使用外键,所以使用了<many-to-one>标签,这里注意里面使用了unique属性,这个属性值为true,保证了映射是唯一的,也就是一个外键只能对应一个主键,从而保证了是一对一映射。
4.写Address2类的映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.test.model">
<class name="Address2" table="t_address2">
<id name="id" column="addressId">
<generator class="native"></generator>
</id>
<property name="address" column="address"></property>
<property name="zipcode" column="zipcode"></property>
<one-to-one name="user2" class="com.test.model.User2" property-ref="address2"></one-to-one>
</class>
</hibernate-mapping>
这里<one-to-one>标签里面使用了property-ref属性,这个属性的作用是使用 property-ref指定的字段作为关联字段,具体用法百度。
5.写好配置文件,写测试方法:
@Test
public void testSave2(){
User2 user2 = new User2();
user2.setName("李四");
Address2 address2 = new Address2();
address2.setAddress("在那桃花盛开的地方2");
address2.setZipcode("123456");
address2.setUser2(user2);
user2.setAddress2(address2);
session.save(user2);
}
运行测试方法,生成的数据库表结构为:
添加的数据为: