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

xiaoxiao2021-02-28  139

注意:我使用的是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) { 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=基础部
转载请注明原文地址: https://www.6miu.com/read-33225.html

最新回复(0)