一对多单向外键关联
一对多就是一方持有多方的集合,一个班级有多个学生
需要在一方添加注解:
@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY)
抓取策略一般采用的是懒加载
@JoinColumn(name=”cid”)
用来表示对应的外键的名称
总结:多对一是,多方设置EAGER,一方设置LAZY
在前一个例子中,把Students类中的ClassRoom删掉,在ClassRoom(一方)中持有Students(多方)的集合。可以写为private Set<Students> stus;
,然后将字段封装。在属性上方加上注解。
@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY)
@JoinColumn(name="cid")
private Set<Students> stus;
这样配置就完成了。
然后在配置文件里配置一下两个类。
测试类在之前的例子中修改,创建数据表的方法不变。在添加记录的方法中,因为是一对多,一方持有多方的集合,所以在先创建好了班级和学生对象之后,先创建两个集合。保存的时候顺序反过来,先保存学生,再保存班级。
@Test
public void addStudents() {
// 创建配置对象
Configuration config = new Configuration().configure();
// 创建服务注册对象
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(config.getProperties()).buildServiceRegistry();
// 创建会话工厂对象
SessionFactory sessionFactory = config
.buildSessionFactory(serviceRegistry);
//创建会话对象
Session session = sessionFactory.getCurrentSession();
//创建事务对象
Transaction tx = session.beginTransaction();
//先创建班级对象
ClassRoom c1 = new ClassRoom("C001","计算机科学");
ClassRoom c2 = new ClassRoom("C002","物联网工程");
//然后创建四个学生对象
Students s1 = new Students("张三", "男", new Date(), "计算机");
Students s2 = new Students("李四", "女", new Date(), "计算机");
Students s3 = new Students("王五", "女", new Date(), "计算机");
Students s4 = new Students("赵六", "男", new Date(), "计算机");
//创建两个集合对象
Set<Students> set1 = new HashSet<Students>();
set1.add(s1);
set1.add(s2);
Set<Students> set2 = new HashSet<Students>();
set1.add(s3);
set1.add(s4);
c1.setStus(set1);
c2.setStus(set2);
//先保存学生
session.save(s1);
session.save(s2);
session.save(s3);
session.save(s4);
//再保存班级
session.save(c1);
session.save(c2);
tx.commit();
}
一对多(多对一)双向外键关联
多方:多方持有一方的引用
配置的注解有:
@ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
@JoinColumn(name=”cid”)
一方:一方持有多方的集合
配置的注解有:
@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY)
@JoinColumn(name=”cid”)
在前一个例子中,一方已经添加了多方的集合,只需要在多方添加一方的引用。private ClassRoom classRoom;
,然后对字段进行封装。在get方法上加上注解。
@ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
@JoinColumn(name="cid")
public ClassRoom getClassRoom() {
return classRoom;
}
public void setClassRoom(ClassRoom classRoom) {
this.classRoom = classRoom;
}
修改配置文档
<mapping class="otm_bfk.Students"/>
<mapping class="otm_bfk.ClassRoom"/>
在测试类中,由于是双向的,所以无论先保存学生还是先保存班级都是可以的,所以之前的测试方法不需要修改。直接执行可以创建表和添加记录。