您的位置:首页 > 其它

Hibernate关联关系映射(单向一对多、单向多对一、双向一对多)

2017-06-07 09:32 561 查看

注意:我使用的是Hibernate5.2版本。

一、关联关系映射

单向关联:一对一、一对多、多对一。

使用连接表单向:一对一、一对多、多对一、多对多。

双向关联:一对一、一对多。

使用连接表的双向关联:一对一、一对多、多对多。

二、自动生成表

这里介绍一下Schema自动生成(Automatic schema generation)

可以从你的映射文件使用一个Hibernate工具生成DDL。 生成的schema包含有对实体和集合类表的完整性引用约束(主键和外键)。涉及到的标示符生成器所需的表和sequence也会同时生成。

在使用这个工具的时候,你必须 通过hibernate.dialet属性指定一个SQL方言(Dialet),因为DDL是与供应商高度相关的。

首先,要定制你的映射文件,来改善生成的schema。

注意:以前的版本生成方法不同请查看具体API

前提配置好classname.hbm.xml和hibernate.xml

public void testCreadDB(){
ServiceRegistry serviceRegistry=new StandardServiceRegistryBuilder().configure().build();
Metadata metadataImplementor=new MetadataSources(serviceRegistry).buildMetadata();
SchemaExport schemaExport=new SchemaExport();
schemaExport.create(EnumSet.of(TargetType.DATABASE), metadataImplementor);
}


三、单向一对多

Grade.java

package com.pojo;

import java.util.HashSet;
import java.util.Set;

import javassist.expr.NewArray;

public class Grade {
private int id;
private String name;
private Set<Student> students=new HashSet<Student>(0);
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
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;
}

}


Student.java

package com.pojo;
public class Student {
private int id;
private String name;
private int age;
//private Grade grade;

// private int gradeId;
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}

}


Grade.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 package="com.pojo">

<class name="Grade" >
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<!-- set是grade中集合的属性    name属性名称-->
<set name="students" table="student">
<!-- key表示外键  colume外键列名  not-null外键不能空-->
<key column="grade_id" not-null="true"></key>
<!-- 一对多 -->
<one-to-many  class="com.pojo.Student"/>
</set>
</class>

</hibernate-mapping>


Student.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 package="com.pojo">

<class name="Student" >
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<property name="age" />

</class>

</hibernate-mapping>


SessionFactoryUtil.java 单例创建sessionfactory

package com.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class SessionFactoryUtil {
private static SessionFactory  sessionfactory;
private SessionFactoryUtil(){

}
public static SessionFactory getSessionFactory(){
if(sessionfactory==null)
{
Configuration configuration=new Configuration();
configuration.configure();

sessionfactory=configuration.buildSessionFactory();
}
return sessionfactory;
}

}


测试代码:

package com.test;

import java.util.Iterator;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.pojo.Grade;
import com.pojo.Student;
import com.util.SessionFactoryUtil;
public class StudentDemo {
public static void main(String[] args) {
StudentDemo studentDemo = new StudentDemo();
studentDemo.oneTomany();
}

public void oneTomany() {
// 单向一对多
SessionFactory sessionFactory = SessionFactoryUtil.getSessionFactory();// 单例创建sessionfactory
Session session = sessionFactory.openSession();// 创建session对象
Transaction transaction = session.beginTransaction();// 开始事务
// 添加数据
Grade grade = new Grade();
grade.setName("基础部");

Student student = new Student();
student.setName("沈雪冰");
student.setAge(23);

Student student2 = new Student();
student2.setName("李四");
student2.setAge(19);
// 关联,建立单向关系
grade.getStudents().add(student);
grade.getStudents().add(student2);
// 保存顺序根据外键来决定的,如果外键不能为null 那么先保存一的一端,否则随意保存
session.save(grade);

session.save(student);
session.save(student2);

transaction.commit(); // 提交事务

// 取数据
Grade gradetemp = session.get(Grade.class, 1);// 取出id为1的grade对象
System.out.println("gradeName=" + gradetemp.getName());
System.out.println("grade所对应的一对多数据为:");

Iterator<Student> iterator = gradetemp.getStudents().iterator(); // 通过gradetemp获取student集合
while (iterator.hasNext()) {
// 取出student集合信息
Student temp = iterator.next(); // 取到一个数据
System.out.println("name=" + temp.getName() + ",age=" + temp.getAge());
}

session.close(); // 关闭session
}

}


运行结果:

gradeName=基础部
grade所对应的一对多数据为:
name=沈雪冰,age=23
name=李四,age=19


四、单向多对一

Grade.java

package com.pojo;

public class Grade {
private int id;
private String name;
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;
}

}


Studnet.java

package com.pojo;

public class Student {
private int id;
private String name;
private int age;
private Grade grade;
// private int gradeId;
public int getId() {
return id;
}
public void setId(int id) {

11f4d
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 Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
}


Grade.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 package="com.pojo">

<class name="Grade" >
<id name="id">
<generator class="native" />
</id>
<property name="name" />

</class>

</hibernate-mapping>


Student.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 package="com.pojo">

<class name="Student" >
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<property name="age" />
<!--
many-to-one属性:
* name:关联映射的(一那方的)属性名字。
* column:和一那方关联的表的外键。数据库字段
* class:name属性对应持久化类的全路径。
* not-null:是否允许为空。
-->
<many-to-one name="grade" class="Grade"
column="grade_id"  not-null="true" foreign-key="FKgrade"
></many-to-one>
</class>

</hibernate-mapping>


测试代码:

package com.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.pojo.Grade;
import com.pojo.Student;
import com.util.SessionFactoryUtil;

public class StudentDemo {
public static void main(String[] args) {
StudentDemo studentDemo=new StudentDemo();
studentDemo.manytoOne();
}
public void manytoOne(){
//单向多对一
SessionFactory sessionFactory=SessionFactoryUtil.getSessionFactory();//单例创建
Session session=sessionFactory.openSession();//创建一个session
Transaction transaction=session.beginTransaction();//开始事务
//添加数据
Grade grade=new Grade();
grade.setName("基础部");

Student student=new Student();
student.setName("沈雪冰");
student.setAge(23);
student.setGrade(grade);
Student student2=new Student();
student2.setName("李四");
student2.setAge(19);
student2.setGrade(grade);

Student student3=new Student();
student3.setName("王麻子");
student3.setAge(30);
student3.setGrade(grade);
//保存数据
session.save(grade);
session.save(student);
session.save(student2);
session.save(student3);

transaction.commit();//提交数据
session.close();//关闭数据

//取数据
Grade temp=new Grade();
Grade temp2=new Grade();
Grade temp3=new Grade();
System.out.println("多对一:");
System.out.println("每位学生所对应数据:");
temp=student.getGrade();//取出student对应的grade
System.out.println("name="+student.getName()+",age="+student.getAge()+",grade="+temp.getName());
temp2=student2.getGrade();//取出student3对应的grade
System.out.println("name="+student2.getName()+",age="+student2.getAge()+",grade="+temp2.getName());
temp3=student3.getGrade();//取出student3对应的grade
System.out.println("name="+student3.getName()+",age="+student3.getAge()+",grade="+temp3.getName());

}

}


运行结果:

多对一:
每位学生所对应数据:
name=沈雪冰,age=23,grade=基础部
name=李四,age=19,grade=基础部
name=王麻子,age=30,grade=基础部


五、双向一对多

Grade.java

package com.pojo;

import java.util.HashSet;
import java.util.Set;

import javassist.expr.NewArray;

public class Grade {
private int id;
private String name;
private Set<Student> students=new HashSet<Student>(0);
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
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;
}

}


Student.java

package com.pojo;
/**
***********************************
*
*@类名    Student
*@时间    2017年6月5日下午3:11:28
*@作者    沈雪冰
*@描述
*
***********************************
*/
public class Student {
private int id;
private String name;
private int age;
private Grade grade;
// private int gradeId;
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}

}


Grade.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 package="com.pojo">

<class name="Grade" >
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<!-- set是grade中集合的属性    name属性名称
-->
<set name="students" table="student" >
<!-- key表示外键  colume外键列名  not-null外键不能空-->
<key column="grade_id" not-null="true"></key>
<!-- 一对多 -->
<one-to-many  class="com.pojo.Student"/>
</set>
</class>

</hibernate-mapping>


Student.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 package="com.pojo">

<class name="Student" >
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<property name="age" />

</class>

</hibernate-mapping>


测试代码:

package com.test;

import java.util.Iterator;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.pojo.Grade;
import com.pojo.Student;
import com.util.SessionFactoryUtil;

public class StudentDemo {
public static void main(String[] args) {
StudentDemo studentDemo = new StudentDemo();
studentDemo.oneTomany();
}

public void oneTomany() {
// 双向一对多
SessionFactory sessionFactory = SessionFactoryUtil.getSessionFactory();// 单例创建sessionfactory
Session session = sessionFactory.openSession();// 创建session
Transaction transaction = session.beginTransaction();// 开始事务

Grade grade = new Grade();
grade.setName("基础部");

Student student = new Student();
student.setName("沈雪冰");
student.setAge(23);

Student student2 = new Student();
student2.setName("李四");
student2.setAge(19);
// 建立双向关系
grade.getStudents().add(student);
grade.getStudents().add(student2);
student.setGrade(grade);
student2.setGrade(grade);
// 保存顺序根据外键来决定的,如果外键不能为null 那么先保存一的一端,否则随意保存
session.save(grade);

session.save(student);
session.save(student2);

transaction.commit(); // 提交事务

// 取数据
Grade gradetemp = session.get(Grade.class, 1); // 获取id为1grade对象
System.out.println("gradeName=" + grade.getName());
System.out.println("grade所对应的一对多数据为:");
Iterator<Student> iterator = gradetemp.getStudents().iterator();// 这里的学生信息是根据gradetemp信息获取的

while (iterator.hasNext()) {
Student temp = iterator.next(); // 取到一个数据
System.out.println("name=" + temp.getName() + ",age=" + temp.getAge() + "" + ",gradename="
+ temp.getGrade().getName());// 这里的grade信息是通过student信息获取的
}

session.close(); // 关闭session
}

}


运行结果:

要注意和上边单向一对多的区别

gradeName=基础部
grade所对应的一对多数据为:
name=沈雪冰,age=23,gradename=基础部
name=李四,age=19,gradename=基础部
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐