一對多單向外鍵
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 { @Test public 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); } @Test public 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(); } }
最后結果: