多对一单向外键
1,多方持有一方的引用,比如:多个学生对应一个班级(多对一)
2,@ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER) cascade表示一种级联关系,fetch表示抓取策略(eager表示渴望,积极)
@JoinColumn(name="cid", referencedColumnName="CID") 表示多方持有一方引用,一方的外键用name表示,referencedColumnName表示对应数据库里面字段。
第一步:创建外键类:班级类。
注意:1,别忘了加上实体类的注解:@Entity。2,给主键加上注解:因为主键是String类型,不能自动生成,所以加上主键生成器@GeneratedValue,并且指定主键生成
策略为手工赋值@GenericGenerator。为了控制String长度,加上@Column注解。
package mto_fk; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; 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;//班级的名字 public ClassRoom() { } 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,给教室类的属性,的get方法加上注解:@ManyToOne,
2,指定这个类的属性里面作为学生类的外键的属性cid,并且指定该外键在表中的字段为CID。@JoinColumn(name="cid", referencedColumnName="CID")。
(注意,教室类作为属性的在里面的作用就是指定学生类的外键,也就是指定cid,映射为表里面的字段为CID)
package mto_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 gender;//性别 private Date birthday; private String major;//专业 private ClassRoom classRoom;//教室 public Students() { } public Students( int sid,String gender, Date birthday, String major) { //super(); this.sid=sid; 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 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; } }
注册到配置:
添加测试:
package mto_fk; import java.util.EnumSet; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; 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); } }
运行成功后表:
测试添加记录:
1,因为sid自动生成,所以构造函数不要永sid的属性
package mto_fk; import java.util.Date; import java.util.EnumSet; 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(),"计算机专业"); //设置班级 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); transaction.commit(); } }
测试结果:可见sid是自动生成,自动叠加的。