1、单向一对一
User1.java
@Entity
public class User1 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
// CascadeType.ALL为级联操作
@OneToOne(cascade = CascadeType.ALL)
// name为外键列名,unique为true表示本外键不可重复
@JoinColumn(name = "hobby_id", unique = true)
private Hobby1 hobby;
//省略getter setter
...
}
Hobby1.java
//普通持久化模型
@Entity
public class Hobby1 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
//省略getter setter
...
}
测试:
@Test
public void test01() {
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Hobby1 hobby = new Hobby1();
hobby.setName("coding");
User1 user = new User1();
user.setName("renhq");
user.setHobby(hobby);
//此处只保存use即可,因为user设置了级联cascade = CascadeType.ALL
session.save(user);
session.getTransaction().commit();
}
表关系:
hobby_id为外键参照表hobby1主键id
2、双向一对一
@Entity
public class User2 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "hobby_id", unique = true)
private Hobby2 hobby2; //本属性名为从表中mappedBy
//省略getter setter
...
}
@Entity
public class Hobby2 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToOne(mappedBy = "hobby2")//mappedBy指定由对方来进行维护关联关系,hobby2为User中的属性名
private User2 user;
...
}
单向一对一与双向一对一区别:双向中的被控放包含一个属性指向控制方,就是Hobby2中的user属性。但是hobby2表中并没有外键关联user,在查询Hobby时Hibernate使用连接查询。
表关系:
3、单向一对多
@Entity
public class User3 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
//FetchType.LAZY 懒加载
//FetchType.EAGER 即时加载
@OneToMany(targetEntity = Hobby3.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
//name值Hobby3外键列名,referencedColumnName值Hobby3表参考外键列名,这里指User3.id
@JoinColumn(name = "hobby3_id", referencedColumnName = "id")
private Set<Hobby3> hobby3Set;
...
}
@Entity
public class Hobby3 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
...
}
One拥有一个Set集合存放N,而N一方的表中拥有外键指向One一方,外键参考列由referencedColumnName 指定One中的一列。
表关系:
4、单向多对一
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToOne(targetEntity = School.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private School school;
...
}
@Entity
public class School {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
...
}
表结构:
5、双向一对多/多对一
@Entity
public class Student1 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToOne(targetEntity = Teacher.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Teacher teacher;
...
}
@Entity
public class Teacher {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToMany(targetEntity = Student1.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Student1> student1s;
...
}
测试:
@Test
public void test() {
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Student1 student11 = new Student1();
Student1 student12 = new Student1();
Student1 student13 = new Student1();
student11.setName("张三");
student12.setName("李四");
student13.setName("王五");
Set<Student1> t1 = new HashSet<Student1>();
t1.add(student11);
t1.add(student12);
Set<Student1> t2 = new HashSet<Student1>();
t2.add(student12);
t2.add(student13);
Teacher teacher1 = new Teacher();
Teacher teacher2 = new Teacher();
teacher1.setName("张老师");
teacher1.setStudent1s(t1);
teacher2.setName("李老师");
teacher2.setStudent1s(t2);
session.save(teacher1);
session.save(teacher2);
session.getTransaction().commit();
}
表结构(Hibernate创建了连接表):
6、单向多对多
关系由User4维护
@Entity
public class User4 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(
name = "user4_hobby4_jointable",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "hobby_id")
)
private Set<Hobby4> hobby4s;
...
}
@Entity
public class Hobby4 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
...
}
表结构:
测试:
Hobby4 hobby41 = new Hobby4();
Hobby4 hobby42 = new Hobby4();
hobby41.setName("coding");
hobby42.setName("gril");
Set<Hobby4> hobby4s = new HashSet<Hobby4>();
hobby4s.add(hobby41);
hobby4s.add(hobby42);
User4 user41 = new User4();
user41.setName("renhq");
user41.setHobby4s(hobby4s);
session.save(user41);
数据:
7、双向多对多
Hobby添加Set<User> 并将控制权交给User,此时还是会有连接表所以表结构并没有改变。
@Entity
public class User5 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(
name = "user5_hobby5_jointable",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "hobby_id")
)
private Set<Hobby5> hobby5s;
...
}
@Entity
public class Hobby5 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToMany(mappedBy = "hobby5s")
private Set<User5> user5s;
...
}
表结构:
测试以及结果同上。