一、关联关系一对一外键(双向)

1、实体类,代码如下:

package learn.hibernate.bean;

import java.util.Date;

/**
* 持久化类设计
* 注意:
* 持久化类通常建议要有一个持久化标识符(ID)
* 持久化标识符通常建议使用封装类(例如:Integer 因为基本类型存在默认值)
* 持久化类通常建议手动添加一个无参构造函数 (因为有些操作是通过放射机制进行的)
* 属性通常建议提供 getter/setter 方法
* 持久化类不能使用 final 修饰
* 持久化类中如果使用了集合类型数据,只能使用集合所对应的接口类型来声明(List/Map/Set)
* 如下:ArrayList list = new ArrayList(); 不行
* List list = new ArrayList(); 可行
*/
public class Person { private Integer id;
private String name;
private int age;
private int passwork;
private Date birthday; private Address addres; public Person() { } public Person(String name, int age, int passwork, Date birthday) {
super();
this.name = name;
this.age = age;
this.passwork = passwork;
this.birthday = birthday;
} @Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age
+ ", passwork=" + passwork + ", birthday=" + birthday + "]";
} public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getPasswork() {
return passwork;
}
public void setPasswork(int passwork) {
this.passwork = passwork;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
} public Address getAddres() {
return addres;
} public void setAddres(Address addres) {
this.addres = addres;
} }
package learn.hibernate.bean;

public class Address {

    private Integer id;
private String zipCode;
private String address;
private Person person; public Address() {
super();
} public Address(String zipCode, String address) {
super();
this.zipCode = zipCode;
this.address = address;
} @Override
public String toString() {
return "Address [zipCode=" + zipCode + ", address=" + address + "]";
}
public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
} public Person getPerson() {
return person;
} public void setPerson(Person person) {
this.person = person;
}
}

2、映射配置,代码如下:

<?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="learn.hibernate.bean">
<class name="Person" table="t_person">
<id name="id" column="person_id">
<generator class="native"/>
</id>
<property name="name" column="t_name"/>
<property name="age"/>
<property name="passwork"/>
<property name="birthday"/>
<!--
one-to-one 表示一对一的配置
name 指定 Person 类中的关联关系的 address 属性
cascade 表示级联操作
级联是对象之间的关联操作,只影响添加、删除、更新,不影响查询
all:所有情况下都进行关联操作(save、update、delete)
none:所有情况下都不进行关联操作(默认值)
save-update:在执行 (save、update、saveOrUpdate)进行关联操作
delete:在执行 delete 时进行关联操作
-->
<one-to-one name="addres" cascade="all"/>
</class>
<class name="Address" table="t_address">
<id name="id">
<generator class="native"/>
</id>
<property name="zipCode"/>
<property name="address"/>
<!--
基于外键的一对一配置,在从表一端使用 many-to-one
name Address类中关联关系 Person 类的引用变量名
column 指定外键列名,可选
unique 唯一约束,因为使用的是一对一外键关联
not-null 指定列是否为空
-->
<many-to-one name="person" column="person_id" unique="true" not-null="true"/>
</class>
</hibernate-mapping>

3、测试类,代码如下:

package learn.hibernate.test;

import static org.junit.Assert.*;

import java.util.Date;

import learn.hibernate.bean.Address;
import learn.hibernate.bean.Person;
import learn.hibernate.bean.Phones; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; public class TestHibernate { SessionFactory factory = null;
Session session = null;
Transaction tx = null; /**
* 测试之前初始化数据
* @throws Exception
*/
@SuppressWarnings("deprecation")
@Before
public void setUp() throws Exception {
System.out.println("---------初始化数据----------"); Configuration config = new Configuration().configure();
ServiceRegistry sr = new ServiceRegistryBuilder()
.applySettings(config.getProperties()).buildServiceRegistry();
factory = config.buildSessionFactory(sr);
session = factory.openSession();
} /**
* 测试之后释放(销毁)数据
* @throws Exception
*/
@After
public void tearDown() throws Exception {
System.out.println("---------释放数据----------");
if(session.isOpen()){
session.close();
}
} @Test
public void testAdd(){
Person p = new Person("tiger",22,123456,new Date());
Address address = new Address("410000","湖南长沙");
p.setAddres(address);
address.setPerson(p); tx = session.beginTransaction();
// 进行数据保存的时候先持久化主表,在持久化从表;否则会执行 update 语句
session.persist(p);
session.persist(address);
tx.commit();
} /**
* 通过主表获取数据
* 通过 left outer join 进行数据查询
*/
@Test
public void testGet(){
Person p = (Person)session.get(Person.class, 1);
System.out.println(p);
System.out.println("------------------------");
System.out.println(p.getAddres());
} /**
* 通过从表获取数据
* 先查询从表数据,获取主表数据时再通过 left outer join 进行数据查询
*/
@Test
public void testGet2(){
Address address = (Address)session.get(Address.class, 1);
System.out.println(address);
System.out.println("------------------------");
System.out.println(address.getPerson());
} /**
* 更新
*/
@Test
public void testUpdate(){
Person p = (Person)session.get(Person.class, 2);
p.setAge(25);
Address address = p.getAddres();
address.setAddress("湖北武汉");
tx = session.beginTransaction();
session.merge(p);
tx.commit();
} /**
* 删除
*/
@Test
public void testDel(){
tx = session.beginTransaction();
Person p = (Person)session.get(Person.class, 1);
session.delete(p);
tx.commit();
}
}

4、测试

(1)、测试 testAdd(),控制台打印:

(2)、测试 testGet(),控制台打印:

(3)、测试 testGet2(),控制台打印:

(4)、测试 testUpdate(),控制台打印:

(5)、测试 testDel(),控制台打印:

如果映射配置文件没有添加  cascade="all" 或者  cascade="delete",删除的时候会报如下错误:

org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:72)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:211)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3400)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3630)
at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:114)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:349)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
at learn.hibernate.test.TestHibernate.testDel(TestHibernate.java:115)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`hibernate`.`t_address`, CONSTRAINT `FK_sydlu68t7mra095us6fku8eyt` FOREIGN KEY (`person_id`) REFERENCES `t_person` (`person_id`))
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1039)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3609)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3541)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2624)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2127)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2427)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2345)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2330)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208)
... 38 more

三、关联关系一对一主键(双向)

除了配置文件不一样之外,其他的都是一样的;配置文件代码如下:

<?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="learn.hibernate.bean">
<class name="Person" table="t_person">
<id name="id" column="person_id">
<generator class="native"/>
</id>
<property name="name" column="t_name"/>
<property name="age"/>
<property name="passwork"/>
<property name="birthday"/>
<one-to-one name="addres" cascade="all"/>
</class>
<class name="Address" table="t_address">
<id name="id">
<!-- 表示adderss的主键不再由 自己产生,而是使用Person对应表的主键 -->
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<property name="zipCode"/>
<property name="address"/>
<!--
基于 主键 的 一对一 双向 关联
constrained 表示主键约束 true表示启用主键约束
-->
<one-to-one name="person" constrained="true"/>
</class>
</hibernate-mapping>

四、关联关系一对多(双向)

1、实体类,代码如下:

package learn.hibernate.bean;

import java.util.Date;
import java.util.HashSet;
import java.util.Set; /**
* 持久化类设计
* 注意:
* 持久化类通常建议要有一个持久化标识符(ID)
* 持久化标识符通常建议使用封装类(例如:Integer 因为基本类型存在默认值)
* 持久化类通常建议手动添加一个无参构造函数 (因为有些操作是通过放射机制进行的)
* 属性通常建议提供 getter/setter 方法
* 持久化类不能使用 final 修饰
* 持久化类中如果使用了集合类型数据,只能使用集合所对应的接口类型来声明(List/Map/Set)
* 如下:ArrayList list = new ArrayList(); 不行
* List list = new ArrayList(); 可行
*/
public class Person { private Integer id;
private String name;
private int age;
private int passwork;
private Date birthday; private Set<Address> addres = new HashSet<Address>(); public Person() { } public Person(String name, int age, int passwork, Date birthday) {
super();
this.name = name;
this.age = age;
this.passwork = passwork;
this.birthday = birthday;
} @Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age
+ ", passwork=" + passwork + ", birthday=" + birthday + "]";
} public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getPasswork() {
return passwork;
}
public void setPasswork(int passwork) {
this.passwork = passwork;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
} public Set<Address> getAddres() {
return addres;
} public void setAddres(Set<Address> addres) {
this.addres = addres;
}
}

2、配置文件,代码如下:

<?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="learn.hibernate.bean">
<class name="Person" table="t_person">
<id name="id" column="person_id">
<generator class="native"/>
</id>
<property name="name" column="t_name"/>
<property name="age"/>
<property name="passwork"/>
<property name="birthday"/>
<!--
通过Set配置一个人对应的多个地址的关联关系
inverse=true 表示在Person端不维护关系;因为多的一端有外键,管理关联关系更高效
-->
<set name="addres" cascade="all" inverse="true">
<!-- 指定 addres 集合中的数据对应t_person的的一个外键 -->
<key column="p_id"/>
<!-- 指定Person 关联的实例类型 -->
<one-to-many class="Address"/>
</set> <!-- inverse="false" 一定要为 false 因为要控制顺序 -->
<!-- <list name="addres" inverse="false" cascade="all">
<key column="p_id"/>
<index column="indexs" type="integer"/>
<one-to-many class="Address"/>
</list> -->
<!-- inverse="false" 一定要为 false 因为要控制顺序 -->
<!-- <map name="addres" inverse="false" cascade="all">
<key column="p_id"/>
<index column="map_key" type="string"/>
<one-to-many class="Address"/>
</map> -->
</class>
<class name="Address" table="t_address">
<id name="id">
<generator class="native"/>
</id>
<property name="zipCode"/>
<property name="address"/>
<!--
多的一端使用 many-to-one 进行配置
-->
<many-to-one name="person" column="p_id"/>
</class>
</hibernate-mapping>

3、测试代码,如下:

package learn.hibernate.test;

import static org.junit.Assert.*;

import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set; import learn.hibernate.bean.Address;
import learn.hibernate.bean.Person;
import learn.hibernate.bean.Phones; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; public class TestHibernate { SessionFactory factory = null;
Session session = null;
Transaction tx = null; /**
* 测试之前初始化数据
* @throws Exception
*/
@SuppressWarnings("deprecation")
@Before
public void setUp() throws Exception {
System.out.println("---------初始化数据----------"); Configuration config = new Configuration().configure();
ServiceRegistry sr = new ServiceRegistryBuilder()
.applySettings(config.getProperties()).buildServiceRegistry();
factory = config.buildSessionFactory(sr);
session = factory.openSession();
} /**
* 测试之后释放(销毁)数据
* @throws Exception
*/
@After
public void tearDown() throws Exception {
System.out.println("---------释放数据----------");
if(session.isOpen()){
session.close();
}
} @Test
public void testAdd(){
Person p = new Person("tiger",22,123456,new Date());
Address address1 = new Address("410000","湖南长沙");
Address address2 = new Address("410001","湖南郴州");
Address address3 = new Address("410002","湖南常德");
Address address4 = new Address("410003","湖南衡阳"); Set<Address> set = new HashSet<Address>(); set.add(address1);
set.add(address2);
set.add(address3);
set.add(address4); // person 与多个 Address 建立关联
p.setAddres(set);
// Address 与 person 建立关联;如果不建立关联,那么外键为 null
address1.setPerson(p);
address2.setPerson(p);
address3.setPerson(p);
address4.setPerson(p); tx = session.beginTransaction();
session.persist(p);
tx.commit();
} /**
* 通过主表获取数据
* 通常从表的数据时延迟查询
*/
@Test
public void testGet(){
Person p = (Person)session.get(Person.class, 1);
System.out.println(p);
System.out.println("------------------------");
Iterator<Address> it = p.getAddres().iterator();
while(it.hasNext()){
Address address = it.next();
System.out.println(address);
}
} /**
* 通过从表获取数据
* 先查询从表数据,主表数据是延迟查询
*/
@Test
public void testGet2(){
Address address = (Address)session.get(Address.class, 1);
System.out.println(address);
System.out.println("------------------------");
System.out.println(address.getPerson());
} /**
* 删除主表时,会将所对应的从表数据删除
*/
@Test
public void testDel(){
tx = session.beginTransaction();
Person p = (Person)session.get(Person.class, 1);
session.delete(p);
tx.commit();
} /**
* 删除从表数据,只会删除从表自己的数据
*/
@Test
public void testDel2(){
tx = session.beginTransaction();
Address address = (Address)session.get(Address.class, 5);
session.delete(address);
tx.commit();
}
}

五、关联关系多对多(双向)

1、实体类,代码如下:

package learn.hibernate.bean;

import java.util.Date;
import java.util.HashSet;
import java.util.Set; /**
* 持久化类设计
* 注意:
* 持久化类通常建议要有一个持久化标识符(ID)
* 持久化标识符通常建议使用封装类(例如:Integer 因为基本类型存在默认值)
* 持久化类通常建议手动添加一个无参构造函数 (因为有些操作是通过放射机制进行的)
* 属性通常建议提供 getter/setter 方法
* 持久化类不能使用 final 修饰
* 持久化类中如果使用了集合类型数据,只能使用集合所对应的接口类型来声明(List/Map/Set)
* 如下:ArrayList list = new ArrayList(); 不行
* List list = new ArrayList(); 可行
*/
public class Person { private Integer id;
private String name;
private int age;
private int passwork;
private Date birthday; private Set<Address> addres = new HashSet<Address>(); public Person() { } public Person(String name, int age, int passwork, Date birthday) {
super();
this.name = name;
this.age = age;
this.passwork = passwork;
this.birthday = birthday;
} @Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age
+ ", passwork=" + passwork + ", birthday=" + birthday + "]";
} public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getPasswork() {
return passwork;
}
public void setPasswork(int passwork) {
this.passwork = passwork;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
} public Set<Address> getAddres() {
return addres;
} public void setAddres(Set<Address> addres) {
this.addres = addres;
}
}
package learn.hibernate.bean;

import java.util.Set;

public class Address {

    private Integer id;
private String zipCode;
private String address;
private Set<Person> person; public Address() { } public Address(String zipCode, String address) {
super();
this.zipCode = zipCode;
this.address = address;
} @Override
public String toString() {
return "Address [zipCode=" + zipCode + ", address=" + address + "]";
}
public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
} public Set<Person> getPerson() {
return person;
} public void setPerson(Set<Person> person) {
this.person = person;
}
}

2、配置文件,代码如下:

<?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="learn.hibernate.bean">
<class name="Person" table="t_person">
<id name="id" column="person_id">
<generator class="native"/>
</id>
<property name="name" column="t_name"/>
<property name="age"/>
<property name="passwork"/>
<property name="birthday"/>
<!--
通过Set配置一个人对应的多个地址的关联关系
inverse=true 表示在Person端不维护关系;因为多的一端有外键,管理关联关系更高效
-->
<set name="addres" cascade="all" inverse="true" table="person_address">
<!-- 指定 addres 集合中的数据对应t_person的的一个外键 -->
<key column="p_id"/>
<!-- 指定Person 关联的实例类型 -->
<many-to-many class="Address" column="a_id"/>
</set>
</class>
<class name="Address" table="t_address">
<id name="id">
<generator class="native"/>
</id>
<property name="zipCode"/>
<property name="address"/> <set name="person" cascade="all" table="person_address">
<key column="a_id"/>
<many-to-many class="Person" column="p_id"/>
</set>
</class>
</hibernate-mapping>

3、测试类,代码如下:

package learn.hibernate.test;

import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set; import learn.hibernate.bean.Address;
import learn.hibernate.bean.Person; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; public class TestHibernate { SessionFactory factory = null;
Session session = null;
Transaction tx = null; /**
* 测试之前初始化数据
* @throws Exception
*/
@SuppressWarnings("deprecation")
@Before
public void setUp() throws Exception {
System.out.println("---------初始化数据----------"); Configuration config = new Configuration().configure();
ServiceRegistry sr = new ServiceRegistryBuilder()
.applySettings(config.getProperties()).buildServiceRegistry();
factory = config.buildSessionFactory(sr);
session = factory.openSession();
} /**
* 测试之后释放(销毁)数据
* @throws Exception
*/
@After
public void tearDown() throws Exception {
System.out.println("---------释放数据----------");
if(session.isOpen()){
session.close();
}
} @Test
public void testAdd(){
Person p1 = new Person("tiger",22,123456,new Date());
Person p2 = new Person("admin",25,123456,new Date()); Set<Person> pset = new HashSet<Person>();
pset.add(p1);
pset.add(p2); Address address1 = new Address("410000","湖南长沙");
Address address2 = new Address("410001","湖南郴州");
Address address3 = new Address("410002","湖南常德");
Address address4 = new Address("410003","湖南衡阳"); Set<Address> set = new HashSet<Address>(); set.add(address1);
set.add(address2);
set.add(address3);
set.add(address4); // person 与多个 Address 建立关联
p1.setAddres(set);
p2.setAddres(set); // Address 与 person 建立关联;如果不建立关联,那么外键为 null
address1.setPerson(pset);
address2.setPerson(pset);
address3.setPerson(pset);
address4.setPerson(pset); tx = session.beginTransaction();
session.persist(p1);
session.persist(p2);
tx.commit();
} /**
* 通过主表获取数据
* 通常从表的数据时延迟查询
*/
@Test
public void testGet(){
Person p = (Person)session.get(Person.class, 3);
System.out.println(p);
System.out.println("------------------------");
Iterator<Address> it = p.getAddres().iterator();
while(it.hasNext()){
Address address = it.next();
System.out.println(address);
}
} /**
* 通过从表获取数据
* 先查询从表数据,主表数据是延迟查询
*/
@Test
public void testGet2(){
Address address = (Address)session.get(Address.class, 9);
System.out.println(address);
System.out.println("------------------------");
Set<Person> pset = address.getPerson();
Person[] p = new Person[pset.size()];
pset.toArray(p);
System.out.println(Arrays.toString(p));
}
}

六、hibernate 的级联操作详解

cascade属性表明操作是否从父对象级联到被关联的对象,它的取得可以是以下几种:
none:在保存,删除或修改当前对象时,不对其附属对象(关联对象)进行级联操作。它是默认值。
save-update:在保存,更新当前对象时,级联保存,更新附属对象(临时对象,游离对象)。
delete:在删除当前对象时,级联删除附属对象。
all:所有情况下均进行级联操作,即包含save-update和delete操作。
delete-orphan:删除和当前对象解除关系的附属对象。

以上的文字来自:http://blog.csdn.net/owen_008/article/details/4429382

Hibernate学习---第七节:关联关系的更多相关文章

  1. VUE2.0实现购物车和地址选配功能学习第七节

    第七节 卡片选中,设置默认 1.卡片选中html:<li v-for="(item,index) in filterAddress" v-bind:class="{ ...

  2. SSH:Hibernate框架(七种关联关系映射及配置详解)

    概念 基本映射是对一个实体进行映射,关联映射就是处理多个实体之间的关系,将关联关系映射到数据库中,所谓的关联关系在对象模型中有一个或多个引用. 分类 关联关系分为上述七种,但是由于相互之间有各种关系, ...

  3. Hibernate学习---第六节:数组&list&map&set的映射配置

    1.实体类,代码如下: package learn.hibernate.bean; import java.util.Date; import java.util.HashMap; import ja ...

  4. Hibernate学习---第五节:普通组件和动态组件

    一.普通组件映射配置 1.创建组件类,代码如下: package learn.hibernate.bean; /** * 组件类 */ public class Phones { private St ...

  5. Hibernate学习(七)———— hibernate中查询方式详解

    序言 之前对hibernate中的查询总是搞混淆,不明白里面具体有哪些东西.就是因为缺少总结.在看这篇文章之前,你应该知道的是数据库的一些查询操作,多表查询等 --WH 一.hibernate中的5种 ...

  6. Coursera在线学习---第七节.支持向量机(SVM)

    一.代价函数   对比逻辑回归与支持向量机代价函数. cost1(z)=-log(1/(1+e-z)) cost0(z)=-log(1-1/(1+e-z)) 二.支持向量机中求解代价函数中的C值相当于 ...

  7. Hibernate学习---第十一节:Hibernate之数据抓取策略&批量抓取

    1.hibernate 也可以通过标准的 SQL 进行查询 (1).将SQL查询写在 java 代码中 /** * 查询所有 */ @Test public void testQuery(){ // ...

  8. Hibernate学习(七)

    Hibernate缓存 1.一级缓存:Session 级别的缓存 2.二级缓存: SessionFactory 级别的缓存 3.查询缓存:需二级缓存的支持,查询缓存依赖二级缓存 一级缓存 1.依赖于 ...

  9. JPA学习---第七节:使用JPA加载_更新_删除对象

    1.添加数据,代码如下: @Test public void save(){ EntityManagerFactory factory = Persistence.createEntityManage ...

随机推荐

  1. 【整理】Android中EditText中的InputType类型含义与如何定义( 转 )

    转自:[整理]Android中EditText中的InputType类型含义与如何定义 用到的时候查到了这篇文章觉得很不错,就在此记录下. [背景] 经过一些Android中EditText方面的折腾 ...

  2. selenium驱动Firefox跳转页慢慢慢的问题(待验证)

    转载至http://www.cnblogs.com/yicaifeitian/p/5198871.html 为了解决这个问题,我是查了很多资料,解决方案是百度出来的.抱歉,我忘记出处在哪了,代码如下: ...

  3. 嵌入式开发之手机arm汇总---科普手机arm

    http://www.leiphone.com/news/201406/1102-zzl-arm.html

  4. 多媒体开发之---h264格式slice_header

    从Slice_Header学习H.264 写在前面: $     H.264我是结合标准和毕厚杰的书一块学的.看句法语义时最是头疼,一大堆的元素,很需要耐心.标准中在介绍某个元素的语义时,经常会突然冒 ...

  5. 零基础学python-2.7 列表与元组

    事实上,能够把列表和元组看成普通的数组.可是这个数组能够存储不同的数据类型(对象) 列表和元组的差别   列表 元组 使用的符号 [] () 元素数量 可变 不可变 改动元素 不能够 能够 假设大家有 ...

  6. iOS 递归锁

    原理:递归锁也是通过 pthread_mutex_lock 函数来实现,在函数内部会判断锁的类型.NSRecursiveLock 与 NSLock 的区别在于内部封装的 pthread_mutex_t ...

  7. 转载:python基础之模块

    作者:武沛齐 出处:http://www.cnblogs.com/wupeiqi/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接. 模块,用一 ...

  8. Ogbect对象转换为泛型对象

    相信很多人都自己写个这个转换的方法,再次附上我自己的写转换方法仅供参考. T t = BeanUtil.dbObject2Bean(obj, tClass); public static <T& ...

  9. POJ 2187 Beauty Contest【凸包周长】

    题目: http://poj.org/problem?id=1113 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...

  10. OC常用函数及变量

    1.OC常用的的函数及变量 (1)算术函数 [算术函数] 函数名 说明 int rand() 随机数生成.(例)srand(time(nil)); //随机数初期化int val = rand()P; ...