Hibernate中用注解配置一对多双向关联和多对一单向关联

Hibernate提供了Hibernate Annotations扩展包,使用注解完成映射。Hibernate3.3之前,需单独下载注解开发包

 

配置持久化类

配置关联关系

 下面我们先从多对一单向关联关系讲起,多对一单向关联就是在多的一方植入一的一方的主键作为外键,下面我们先进行初始配置,

 

在配置的过程中我们会遇到一个问题  就是无论用load还是get都不会出现延迟加载,那么我们应该如何设置为要延迟加载,这样做的好处是可以在用的时候才加载对应的信息,节约内存

 

hibernate中,延迟加载大致可以分为两类,一类是延迟属性加载,另一类是延迟关联实体加载。

 

普通属性:分两种情况,一种是集合属性,一种是非集合属性(如String、Integer......)

集合属性的延迟加载通过PersistentSet、 PersistentList、PersistentBag、PersistentMap、PersistentSortedMap、 PersistentSortedSet作为代理类来实现,代理类中保存了session以及owner属性,owner属性表示了集合属性所属的one 侧的实体。

 

非集合类属性的延迟加载相对比较复杂。仅通过@Basic(fetch = FetchType.LAZY)注解是无法实现延迟加载的。需要让实体实现FieldHandled接口,声明FieldHandler属性,通过拦截器 原理注入对应的FieldHandler属性,起到类似于上述代理类的作用,FieldHandler同样也保持了session,以及需要延迟加载的属 性。

 

我们发现对非集合属性即时设置了@Basic(fetch = FetchType.LAZY)仍无法实现延迟加载,可以看生成的sql语句

 

接下来 我们会对一对多单向关联进行测试,验证对集合类属性,是否可以起到延迟加载的功能

 

注意:不可以对有关联关系的属性设置@Transient

配置多对一的单向关联关系  示例

package cn.happy.entity;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name = "EMP")
public class Emp {
    @Id
    @Column(name = "EMPNO")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "emp_num")
    @SequenceGenerator(name = "emp_num", sequenceName = "emp_num_id", allocationSize = 1, initialValue = 1)
    private Integer empNo;

    @Column(name = "EMPNAME")
    private String empName;
    
    @ManyToOne()
    @JoinColumn(name = "DEPTNO")
    /*@Basic(fetch=FetchType.LAZY)*/
    private Dept dept;

    
    public Emp() {
        super();
    }

    public Emp(Integer empNo, String empName) {
        super();
        this.empNo = empNo;
        this.empName = empName;
    }

    public Integer getEmpNo() {
        return empNo;
    }

    public void setEmpNo(Integer empNo) {
        this.empNo = empNo;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }
}
package cn.happy.entity;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.Cascade;

@Entity
@Table(name = "DEPT")
public class Dept {
    @Id
    @Column(name = "DEPTNO")
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")
    @SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=1,initialValue=1)
    private Integer deptNo;

    @Column(name = "DEPTNAME")
    private String deptName;


    public Integer getDeptNo() {
        return deptNo;
    }

    public void setDeptNo(Integer deptNo) {
        this.deptNo = deptNo;
    }

    public String getDeptName() {
        return deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }
}
/**
     * 注解测试多对一映射   员工表(多)对应部门表(一)的映射,即只在员工表中植入部门表的信息
     * */
    @Test
    public void manytooneSingle(){
        
        /**
         * 查询操作
         * **/
        /*SessionFactory sf=new AnnotationConfiguration().configure().buildSessionFactory();
        Session session = sf.openSession();
        
        Emp emp=(Emp)session.load(Emp.class, 4);
        
        System.out.println(emp.getEmpName()+"\t"+emp.getDept().getDeptName());*/
        
        /**
         * 添加操作
         * **/
        SessionFactory sf=new AnnotationConfiguration().configure().buildSessionFactory();
        Session session = sf.openSession();
        Transaction tx = session.beginTransaction();
        Dept dept = (Dept)session.load(Dept.class, 3);
        
        Emp emp=new Emp();
        emp.setEmpName("户梦艳");
        emp.setEmpNo(001);
        emp.setDept(dept);
        
        Emp emp2=new Emp();
        emp2.setEmpName("户梦艳2");
        emp2.setEmpNo(002);
        emp2.setDept(dept);
        
        session.save(emp);
        session.save(emp2);
        tx.commit();
        session.close();
        
        
    }

一对多双单向配置

package cn.happy.entity;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;


@Entity
@Table(name="Dept")
public class Dept {
    @Id    
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")
    @SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=1,initialValue=1)
    private Integer deptNo;
    @Column
    private String deptName;
    
    
    @OneToMany(cascade={CascadeType.ALL})
    @JoinColumn(name="deptno")
    private Set<Emp> emps=new HashSet<Emp>();

    public Set<Emp> getEmps() {
        return emps;
    }

    public void setEmps(Set<Emp> emps) {
        this.emps = emps;
    }

    public Integer getDeptNo() {
        return deptNo;
    }

    public void setDeptNo(Integer deptNo) {
        this.deptNo = deptNo;
    }

    public String getDeptName() {
        return deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }
}
package cn.happy.entity;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.bytecode.javassist.FieldHandled;
import org.hibernate.bytecode.javassist.FieldHandler;


@Entity
@Table(name = "EMP")
public class Emp {
    
    
    
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="emp_num")
    @SequenceGenerator(name="emp_num",sequenceName="emp_num_no",allocationSize=1,initialValue=9)
    private Integer empNo;

    @Column
    private String empName;
    
   
//    @ManyToOne
//    @JoinColumn(name="deptno")
//    @Basic(fetch=FetchType.LAZY)
//    private Dept dept;
//    
//    public Dept getDept() {
//        return dept;
//    }
//
//    public void setDept(Dept dept) {
//        this.dept = dept;
//    }

    public Emp() {
        super();
    }

    public Emp(Integer empNo, String empName) {
        super();
        this.empNo = empNo;
        this.empName = empName;
    }

    public Integer getEmpNo() {
        return empNo;
    }

    public void setEmpNo(Integer empNo) {
        this.empNo = empNo;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }
    

}
/**
     * 测试一对多单向添加操作
     * */
    @Test
    public void insertOneToManySingle(){
        Emp emp=new Emp();
        emp.setEmpName("李小鹏");
        
        Emp emp2=new Emp();
        emp2.setEmpName("王想想");
        
        Dept dept=new Dept();
        dept.setDeptName("教务部");
        //设置级联操作
        dept.getEmps().add(emp);
        dept.getEmps().add(emp2);
        
        session.save(dept);
        tx.commit();
        System.out.println("insert ok");
        
    }
/**
     * 测试一对多单向查询操作
     * */
    @Test
    public void selectOneToManySingle(){
        Dept dept = (Dept)session.load(Dept.class, 1);
        System.out.println("======================");
        System.out.println("部门名称:"+dept.getDeptName());
        System.out.println("=======================");
        //体现了延迟加载
        for (Emp emp : dept.getEmps()) {
            System.out.println("雇员名称:"+emp.getEmpName());
        }
        //Emp emp = (Emp)session.load(Emp.class, 1);
        
        
    }

一对多双向配置

package cn.happy.entity;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;


@Entity
@Table(name="Dept")
public class Dept {
    @Id    
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")
    @SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=1,initialValue=1)
    private Integer deptNo;
    @Column
    private String deptName;
    
    
    @OneToMany(mappedBy="dept",cascade={CascadeType.ALL})
   
    private Set<Emp> emps=new HashSet<Emp>();

    public Set<Emp> getEmps() {
        return emps;
    }

    public void setEmps(Set<Emp> emps) {
        this.emps = emps;
    }

    public Integer getDeptNo() {
        return deptNo;
    }

    public void setDeptNo(Integer deptNo) {
        this.deptNo = deptNo;
    }

    public String getDeptName() {
        return deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }
}
package cn.happy.entity;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.bytecode.javassist.FieldHandled;
import org.hibernate.bytecode.javassist.FieldHandler;


@Entity
@Table(name = "EMP")
public class Emp {
    
    
    
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="emp_num")
    @SequenceGenerator(name="emp_num",sequenceName="emp_num_no",allocationSize=1,initialValue=9)
    private Integer empNo;

    @Column
    private String empName;
    
   
    @ManyToOne
    @JoinColumn(name="deptno")
    @Basic(fetch=FetchType.LAZY)
    private Dept dept;
    
    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    public Emp() {
        super();
    }

    public Emp(Integer empNo, String empName) {
        super();
        this.empNo = empNo;
        this.empName = empName;
    }

    public Integer getEmpNo() {
        return empNo;
    }

    public void setEmpNo(Integer empNo) {
        this.empNo = empNo;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }
    

}
/**
     * 双向一对多的添加操作
     * */
    @Test 
    public void oneToManyDouble(){
        Dept dept=new Dept();
        dept.setDeptName("财务部");
        
        Emp emp=new Emp();
        emp.setEmpName("邹乐");
        emp.setDept(dept);
        
        Emp emp2=new Emp();
        emp2.setEmpName("范子阳");
        emp2.setDept(dept);
        
        
        dept.getEmps().add(emp);
        dept.getEmps().add(emp2);
        
        session.save(dept);
        tx.commit();
    }
/**
     * 双向一对多的查询操作
     * */
    @Test 
    public void selectOneToManyDouble(){
        
        Dept dept = (Dept)session.load(Dept.class, 1);
        System.out.println("部门名称:"+dept.getDeptName());
        for (Emp emp : dept.getEmps()) {
            System.out.println("职工姓名:"+emp.getEmpName());
        }
        
        System.out.println("==================================================");
        
        Emp emp = (Emp)session.load(Emp.class, 1);
        System.out.println("职工姓名:"+emp.getEmpName()+"\t部门名称:"+emp.getDept().getDeptName());
    }







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值