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.xmlpublic 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.javapackage 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.javapackage 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.javapackage 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=基础部
相关文章推荐
- Hibernate关系映射级别注解(一对多单向外键关联、一对多(多对一)双向外键关联)
- Hibernate 单向多对一、单向一对多、双向一对多关联关系详解
- Java的Hibernate框架中一对多的单向和双向关联映射
- hibernate对象关系映射(一对一,一对多,多对一,多对多的单向,双向映射)
- hibernate 关联映射:多对一(一对多)双向关联关系
- hibernate对象关系映射( 一对一,一对多,多对一,多对多的单向,双向映射 ——)
- hibernate对象关系映射( 一对一,一对多,多对一,多对多的单向,双向映射 ——)
- hibernate映射关系 一对多、多对一单向关联 一对多双向关联
- hibernate 关联映射 双向多对一(一对多)
- Hibernate关系映射----单向一对多实例
- hibernate映射一对多,双向关系[关联自身],初学例子四
- Hibernate关联关系映射-----基于连接表的单向一对多映射配置
- Hibernate关联关系映射-----双向一对多/多对一映射配置
- Hibernate在关于一对多,多对一双向关联映射
- Hibernate -- 映射多对多双向关联关系
- Hibernate映射详解(二)--多对一,一对多单向,一对多双向关联映射
- Hibernate关联关系映射-----基于连接表的单向一对多映射
- Hibernate关联关系映射-----双向一对多/多对一映射配置
- Hibernate关联映射(单项多对一和一对多、双向一对多)
- 框架 day32 Hibernate,一级缓存,关联关系映射(一对多,多对多)