hibernate关系映射
注:(1)在项目开发中,经常遇到无法映射class的情况,所以最好在映射文件中将name和class的路径写完全。
(2)在1的数据表中不会出现set中的column,只会在n的一端的表中出现这个column字段。一、双向1-N关联
使用无连接表的1-N关联
1.Person.java
person是1,address是n。一个人对应多个地址,所以在person类中有一个address的set集合。
package com.ru.domain;
import java.util.HashSet;
import java.util.Set;
public class Person {
private Integer p_id;
private String name;
private Set<Address> address=new HashSet<Address>();
public Integer getP_id() {
return p_id;
}
public void setP_id(Integer p_id) {
this.p_id = p_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Address> getAddress() {
return address;
}
public void setAddress(Set<Address> address) {
this.address = address;
}
}2.Address.java
一个地址只对应一个人,所以用了一个person对象。
package com.ru.domain;
public class Address {
private Integer aid;
private String addressname;
private Person person;
public Integer getAid() {
return aid;
}
public void setAid(Integer aid) {
this.aid = aid;
}
public String getAddressname() {
return addressname;
}
public void setAddressname(String addressname) {
this.addressname = addressname;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}注:在持久化类的映射文件中,1的一方不会在数据表中显示集合,通常只需要在n的一端数据表里增加一个外键。


3.Person.hbm.xml
注意:set集合里面的column并不会在数据表中出现,而是在n的一方address的数据表中出现,并且这个值和many-to-one里面的column属性值必须相同。
key里的column指向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>
<class name="com.ru.domain.Person" table="person">
<id name="p_id" column="person_id" type="java.lang.Integer">
<generator class="native"/>
</id>
<property name="name" column="name" type="java.lang.String"></property>
<!-- inverse=“true”是不控制关联关系 -->
<set name="address" inverse="true">
<key column="person_id"></key>
<one-to-many class="com.ru.domain.Address"/>
</set>
</class>
</hibernate-mapping>4.Address.hbm.xml
<?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>
<class name="com.ru.domain.Address" table="address">
<id name="aid" column="id" type="java.lang.Integer">
<generator class="native"/>
</id>
<property name="addressname" column="addressname" type="java.lang.String"></property>
<!-- 多对一个关联关系 -->
<many-to-one name="person" column="person_id" class="com.ru.domain.Person"></many-to-one>
</class>
</hibernate-mapping>5.testPerson.java
这个是service测试文件
package com.ru.service;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.ru.domain.Address;
import com.ru.domain.Person;
public class testPerson {
public static void main(String[] args){
Configuration cf=new Configuration().configure("hibernate.cfg.xml");
SessionFactory sf=cf.buildSessionFactory();
Session s=sf.openSession();
Transaction ts=s.beginTransaction();
try {
//人
Person p=new Person();
p.setName("如");
s.save(p);
//p.setAddress(address);
//第一个地址
Address a1=new Address();
a1.setAddressname("北京");
a1.setPerson(p);
s.save(a1);
//第二个地址
Address a2=new Address();
a2.setAddressname("天津");
a2.setPerson(p);
s.save(a2);
ts.commit();
s.close();
sf.close();
} catch (HibernateException e) {
e.printStackTrace();
}
}
}6.hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 配置mysql数据库 -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/ru</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 自动创建表 -->
<property name="hbm2ddl.auto">create</property>
<!-- 显示sql语句 -->
<property name="show_sql">true</property>
<!-- 如果使用getCurrentSession,必须配置下面的属性 -->
<!-- <property name="hibernate.current_session_context_class">thread</property> -->
<mapping resource="com/ru/domain/Person.hbm.xml"/>
<mapping resource="com/ru/domain/Address.hbm.xml"/>
</session-factory>
</hibernate-configuration>二、双向N-N映射
只能采用连接表来建立两个实体间的N-N关联关系。
1、Person.java
package com.ru.domain;
import java.util.HashSet;
import java.util.Set;
public class Person {
private Integer pid;
private String name;
//1-n关联关系,使用set保存关连实体
private Set<Address> address=new HashSet();2.Address.java
package com.ru.domain;
import java.util.Set;
public class Address {
private Integer aid;
private String addressdetail;
//同样1-n,记录person实体的属性
private Set<Person> person;3.Person.hbm.xml
<?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>
<class name="com.ru.domain.Person" table="person">
<id name="pid" column="pid" type="java.lang.Integer">
<generator class="identity"></generator>
</id>
<property name="name" column="name" type="java.lang.String"></property>
<!--映射n-n关联实体,两边的table属性必须有且必须相同 -->
<set name="address" table="p_a">
<!-- 这个key中的column对应的是address表中的外键字段-->
<key column="p_id"></key>
<!--映射到的关联类属性,这里的a_id会在person表的字段中-->
<many-to-many class="com.ru.domain.Address" column="a_id"></many-to-many>
</set>
</class>
</hibernate-mapping>4,Address.hbm.xml
<?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>
<class name="com.ru.domain.Address" >
<id name="aid" column="aid" type="java.lang.Integer">
<generator class="identity"></generator>
</id>
<property name="addressdetail" column="addressdetail" type="java.lang.String"></property>
<set name="person" table="p_a">
<key column="a_id"></key>
<!--这里的p_id是address表中字段-->
<many-to-many class="com.ru.domain.Person" column="p_id"></many-to-many>
</set>
</class>
</hibernate-mapping>5.test.java
package com.ru.service;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.ru.domain.Address;
import com.ru.domain.Person;
public class test1 {
public static void main(String[] args) {
Configuration cf=new Configuration().configure();
SessionFactory sf=cf.buildSessionFactory();
Session session=sf.getCurrentSession();
Transaction ts=session.beginTransaction();
try {
//向person中添加一条记录
Person p1=new Person();
p1.setName("如");
session.save(p1);
//向address中添加一条记录
Address a1=new Address();
a1.setAddressdetail("北京");
session.save(a1);
//主外键关系
p1.getAddress().add(a1);
//a1.getPerson().add(p1);
ts.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
}注:会产生三个表

三、双向1-1关联
第一种关联策略:主键关联
1.Person.java
package com.ru.domain;
public class Person {
private Integer id;
private String name;
//1-1关系
private IdCard idcard;2.IdCard.java
package com.ru.domain;
public class Person {
private Integer id;
private String name;
//1-1关系
private IdCard idcard;3.Person.hbm.xml
<?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>
<class name="com.ru.domain.Person" table="person">
<id name="id" column="id">
<!--定义主键生成策略-->
<generator class="identity"/>
</id>
<property name="name" column="name" type="java.lang.String"/>
<!--映射关联实体-->
<one-to-one name="idcard"></one-to-one>
</class>
</hibernate-mapping>4.IdCard.hbm.xml
<?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>
<class name="com.ru.domain.IdCard" table="IdCard">
<id name="id" column="id" type="java.lang.Integer">
<generator class="foreign">
<!--
该实体的主键根据person属性引用的实体的主键生成
-->
<param name="property">person</param>
</generator>
</id>
<property name="CardNo" column="cardno" type="java.lang.String"></property>
<one-to-one name="person"></one-to-one>
</class>
</hibernate-mapping>5.test.java
package com.ru.service;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.ru.domain.IdCard;
import com.ru.domain.Person;
public class test1 {
public static void main(String[] args) {
Configuration cf=new Configuration().configure();
SessionFactory sf=cf.buildSessionFactory();
Session session=sf.getCurrentSession();
Transaction ts=session.beginTransaction();
try {
//向person中添加一条记录
Person p1=new Person();
p1.setName("如");
session.save(p1);
//idcard
IdCard ic=new IdCard();
ic.setCardNo("1111");
//这个必须有不然idcard不能声称主键
ic.setPerson(p1);
session.save(ic);
//主外键关系
ts.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
}