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();
		}
		
	}

}

猜你喜欢

转载自tydldd.iteye.com/blog/1720176