一对多单向外键
1,一方持有多方的集合,一个班级有多个学生(一对多)。
2,@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY ) //级联关系,抓取策略:懒加载。
@JoinColumn(name="cid") //指定name为被控方中被作为外键的属性。
总结抓取策略:多对一时候,多方设置EAGER,一方设置LAZY。
此时因为一个班级拥有多个学生的集合,因此需要用班级添加学生对象集合,所以要在班级里面增加添加学生的方法。
步骤:
第一步:新增学生类:
注意:1,此时因为要用班级类添加学生,所以在学生类里面用不到班级类属性。
package otm_fk;import java.util.Date;import javax.persistence.CascadeType; import javax.persistence.Entity;/*JPA主键*/ import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table;/*学生实体类*/ @Entity @Table(name="Students",schema="sys") public class Students {private int sid;private String name;private String gender;//性别private Date birthday;private String major;//专业public Students(){}public Students( String name,String gender, Date birthday, String major) {//super();this.name=name;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 getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getName() {return name;}public void setName(String name) {this.name = name;}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;} }
第二步:新建班级类:
1,因为要用班级类新增学生类,这里使用集合保存学生类对象。
2,给学生类集合添加注解:@OneToMany,获取方式为懒加载 FetchType.LAZY。
3,此时虽然在班级类里面注解,但是依然是cid在学生类里面做外键,所以,依然是@JoinColumn(name="cid")。
package otm_fk; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import org.hibernate.annotations.GenericGenerator;//班级实体类 @Entity public class ClassRoom {@Id@GeneratedValue(generator="cid") //因为主键是String类型,不是int,不能自动生成,所以必须使用主键生成器@GenericGenerator(name="cid", strategy="assigned")//指定生成策略为手工赋值@Column(length=4) //指定主键长度private String cid;//班级的编号private String cname;//班级的名字 @OneToMany(cascade= {CascadeType.ALL},fetch=FetchType.LAZY)@JoinColumn(name="cid") private Set<Students> stus; //一方持有多方的集合public ClassRoom(){}public ClassRoom(String cid, String cname) {//super();this.cid = cid;this.cname = cname;}public Set<Students> getStus() {return stus;}public void setStus(Set<Students> stus) {this.stus = stus;}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;} }
测试新增:
注意:1,因为班级类新增学生类,所以建立两个学生集合,用班级对象set方法添加,来关联起学生类和班级类。
2,因为是班级类添加学生类对象。所以先保存学生类对象,然后保存班级对象。
package otm_fk; import java.util.Date; import java.util.EnumSet; import java.util.HashSet; import java.util.Set;import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.hibernate.tool.schema.TargetType; import org.junit.Test;public class testStudents {@Testpublic void testSchemaExport(){//创建服务注册对象ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();//创建Metadata对象Metadata metadata =new MetadataSources(serviceRegistry).buildMetadata();//创建SchemaExport对象SchemaExport export = new SchemaExport(); export.create(EnumSet.of(TargetType.DATABASE),metadata);}@Testpublic void addStudetns(){Configuration config=new Configuration().configure();//创建服务注册对象。ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();//创建会话工厂对象SessionFactory sessionFactory=config.buildSessionFactory(serviceRegistry);//创建会话对象Session session=sessionFactory.openSession();//开启事务Transaction transaction=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>();set2.add(s3);set2.add(s3);//如果缺少这句话,就会因为学生类和班级类没有关联起来,导致学生类里面的外键值为空。c1.setStus(set1);c2.setStus(set2);//保存学生 session.save(s1);session.save(s2);session.save(s3);session.save(s4);//保存班级 session.save(c1);session.save(c2);transaction.commit();} }
最后结果: