只记录双向的情况(双向是单向的一种)
@OneToMany 和 @ManyToOne :一个Group 包含多个 User;
Group.class
package com.XX.model; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; @Entity @Table(name = "t_group") public class Group { private String id; private String name; private String title; private Set<User> users; //说明代码一 @Id @GeneratedValue(generator = "sys-uuid") @GenericGenerator(name = "sys-uuid", strategy = "uuid2") public String getId() { return id; } public String getName() { return name; } public String getTitle() { return title; } //说明代码二 @OneToMany(cascade = {CascadeType.ALL}, fetch=FetchType.EAGER, mappedBy = "group") public Set<User> getUsers() { return (users==null)? new HashSet<User>():users; } public void setId(String id) { this.id = id; } public void setName(String name) { this.name = name; } public void setTitle(String title) { this.title = title; } public void setUsers(Set<User> users) { this.users = users; } //说明代码三 /* public void addUser(User user) { if(this.users == null){ this.users = new HashSet<User>(); } users.add(user); }*/ }
User.class
package com.XX.model; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; @Entity @Table(name = "t_user") public class User { private String id; private String name; private int age; private Group group; @Id @GeneratedValue(generator = "sys-uuid") @GenericGenerator(name = "sys-uuid", strategy = "uuid2") public String getId() { return id; } public String getName() { return name; } public int getAge() { return age; } //说明代码二 @ManyToOne(cascade = {CascadeType.ALL}) public Group getGroup() { return group; } public void setId(String id) { this.id = id; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setGroup(Group group) { this.group = group; } }
测试代码:
package com.XX.model; import java.util.Set; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; public class GroupTest { private static SessionFactory sessionFactory; @BeforeClass public static void beforeClass(){ //hibernate 5.0.0.Final及之后的写法 StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build(); Metadata metadata = new MetadataSources(registry).getMetadataBuilder().build(); sessionFactory = metadata.getSessionFactoryBuilder().build(); } @Test public void test() { Group group = new Group(); group.setName("group1"); group.setTitle("test"); User user = new User(); user.setName("yuc"); user.setAge(0); Set<User> users = group.getUsers(); users.add(user); group.setUsers(users); //说明代码三 //group.addUser(user); Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); session.save(group); session.getTransaction().commit(); //说明代码四 session = sessionFactory.getCurrentSession(); session.beginTransaction(); session.get(Group.class, "1"); } @AfterClass public static void afterClass(){ sessionFactory.close(); } }
说明代码一:
ID用 String 存储,保存时自动生成,跨数据库(mysql、oracle均实用);
说明代码二:
@manytoone & @onetomany 双向关联时,manytoone 一方用mappedBy 进行关联(否则数据库会出现两个关联关系,重复);
代码说明三:
在多的一方辅助增加一个子元素。不足:破坏bean 的完整性(一般bean层级只有元素和对应的get/set方法);
代码说明四:
用于说明@manytoone 和 @onetomany 的默认加载方式:
@manytoone 默认加载方式是FetchType.LAZY;
@onetomany 默认加载方式是FetchType.EAGER;
运行代码如下:
数据库结果如下:
@manyToMany双向关联 :一个Teacher有多个Student,一个Student有多个Teacher;
Teacher.class
package com.ajs.model; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; @Entity @Table(name = "t_teacher") public class Teacher { private String id; private String name; private String title; private Set<Student> students; @Id @GeneratedValue(generator = "sys-uuid") @GenericGenerator(name = "sys-uuid", strategy = "uuid2") public String getId() { return id; } //说明代码五 @ManyToMany(targetEntity=Student.class, fetch = FetchType.EAGER, cascade={CascadeType.ALL}, mappedBy = "teachers") public Set<Student> getStudents() { return students; } public void setStudents(Set<Student> students) { this.students = students; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
Student.class
测试代码
@Test public void test() { Teacher teacher = new Teacher(); teacher.setName("tea1"); teacher.setTitle("test"); Student student = new Student(); student.setName("yuc"); student.setAge(20); Set<Student> students= new HashSet<Student>(); students.add(student); teacher.setStudents(students); Set<Teacher> teachers= new HashSet<Teacher>(); teachers.add(teacher); student.setTeachers(teachers); Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); session.save(teacher); session.getTransaction().commit(); session = sessionFactory.getCurrentSession(); session.beginTransaction(); session.get(Student.class, "1"); }
说明代码五:
package com.ajs.model; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; @Entity @Table(name = "t_student") public class Student { private String id; private String name; private int age; private Set<Teacher> teachers; @Id @GeneratedValue(generator = "sys-uuid") @GenericGenerator(name = "sys-uuid", strategy = "uuid2") public String getId() { return id; } public String getName() { return name; } public int getAge() { return age; } //说明代码五 @ManyToMany(targetEntity=Teacher.class, fetch = FetchType.EAGER, cascade={CascadeType.ALL}) @JoinTable(name="t_teacher_student", joinColumns=@JoinColumn(name="student_id"), inverseJoinColumns=@JoinColumn(name="teacher_id")) public Set<Teacher> getTeachers() { return teachers; } public void setId(String id) { this.id = id; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setTeachers(Set<Teacher> teachers) { this.teachers = teachers; } }
双向一样用 mappedBy 对其中一方进行限制,fetch = FetchType.EAGER手动将加载方式改为急加载,需要用targetEntity指定对应的关联类是哪一个;
@JoinTable(name="t_teacher_student", joinColumns=@JoinColumn(name="student_id"),inverseJoinColumns=@JoinColumn(name="teacher_id"))
@JoinTable可以自定义对应的中间表名字,当前实体对象关联的中间表字段名称,已经中间表关联另一方的对应名称;
运行代码如下:
数据库结果如下: