多对一单向外键关联
所谓多对一,就说多方持有一方的引用,比如:多个学生对应一个班级
在多方需要添加如下注解:
@ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
两个常用属性,cascade依然指定级联关系,fetch指的是抓取策略,一般默认EAGER,表示积极的渴望的
@JoinColumn(name=”cid”,referencedColumnName=”COD”)
name是一方的外键,referencedColumnName表示对应的外键如果映射成数据库表里的内容可以起的名称
新建一个包,将学生类拷贝,这次不需要身份证类。把Students类中和IdCard类有关的内容删掉。
然后建一个班级实体类ClassRoom,既然是实体类,所以需要@Entity注解。
@Entity
public class ClassRoom {
@Id
@GeneratedValue(generator="cid")
@GenericGenerator(name="cid",strategy="assigned")
@Column(length=4)
private String cid;//班级号
private String cname;//班级名
public ClassRoom(){
}
public ClassRoom(String cid, String cname) {
super();
this.cid = cid;
this.cname = cname;
}
public String getCid() {
return cid;
}
public void setCid(String cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
}
在Students类中要加上ClassRoom,并封装,在get方法上加上对应注解。另外还要添加一个姓名的属性。
@Entity
public class Students {
private int sid;
private String sname;
private String gender;
private Date birthday;
private String major;
private ClassRoom classRoom;
public Students(){
}
public Students(String sname, String gender, Date birthday,
String major) {
//super();
//这里不传入sid,因为是自动增长的,不需要赋值
this.sname = sname;
this.gender = gender;
this.birthday = birthday;
this.major = major;
}
@Id
@GeneratedValue
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
@ManyToOne(cascade={CascadeType.ALL},fetch=FetchType.EAGER)
@JoinColumn(name="cid",referencedColumnName="CID")
public ClassRoom getClassRoom() {
return classRoom;
}
public void setClassRoom(ClassRoom classRoom) {
this.classRoom = classRoom;
}
}
这样两个实体类就建好了,在配置文档中将两个注解类配置进去。
<mapping class="mto_fk.Students"/>
<mapping class="mto_fk.ClassRoom"/>
在测试类中值保留创建表的测试方法,依然有效。然后写一下添加记录的方法:
public class TestStudents {
@Test
public void testSchemaExport() {
// 创建配置对象
Configuration config = new Configuration().configure();
// 创建服务注册对象
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(config.getProperties()).buildServiceRegistry();
// 创建会话工厂对象
SessionFactory sessionFactory = config
.buildSessionFactory(serviceRegistry);
SchemaExport export = new SchemaExport(config);
export.create(true, true);
}
@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(), "计算机");
s1.setClassRoom(c1);
s2.setClassRoom(c1);
s3.setClassRoom(c2);
s4.setClassRoom(c2);
//先保存班级
session.save(c1);
session.save(c2);
//再保存学生
session.save(s1);
session.save(s2);
session.save(s3);
session.save(s4);
tx.commit();
}
}