06-hibernate注解-一对多单向外键关联

一对多单向外键

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();
    }
}

 最后结果:

 

 

posted @ 2017-11-13 23:02  美好的明天  阅读(5365)  评论(0编辑  收藏  举报