Hibernate 注解 (Annotations 三)多對一雙向注解


注解(Annotation),也叫元數據。一種代碼級別的說明。它是JDK1.5及以后版本引入的一個特性,與類、接口、枚舉是在同一個層次。它可以聲明在包、類、字段、方法、局部變量、方法參數等的前面,用來對這些元素進行說明,注釋。

接下來我們講解一下多對一雙向注解:

我以部門表和員工表作為示例講解。

第一步:創建實體類

Dept(部門表)

 

package cn.onetomanydouble.entity;


import org.hibernate.annotations.*;
import org.hibernate.annotations.Cache;



import javax.persistence.*;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

/**
 * Created by accp on 2017/2/8.
 */
@Entity

@Table(name = "DEPT1")

public class Dept implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO,generator="PROMOTION_SEQ")
    @SequenceGenerator(name="PROMOTION_SEQ",sequenceName="PROMOTION_SEQ",initialValue = 1,allocationSize = 10)
    /*
       對於oracle想使用各自的Sequence,設置如下:
       @GeneratedValue(strategy = GenerationType.AUTO,generator="PROMOTION_SEQ")
       @SequenceGenerator(name="PROMOTION_SEQ",sequenceName="PROMOTION_SEQ")
       另外:
        對於自動增長后,在數據表中的相應字段,要設置字段為auto_increment.
    */
    private Integer deptno;
    @Column
    private String deptname;
    @OneToMany(mappedBy ="dept",cascade = {CascadeType.ALL},fetch = FetchType.LAZY)
    //mappedBy 屬性主要針對外鍵而言,與之對應的是.xml中的inverse屬性
    //mappedBy="dept" 是把維護權交給多的一方
    @LazyCollection(LazyCollectionOption.FALSE)
    private Set<Emp> emps=new HashSet<Emp>();
    @Column
    private  String location;

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

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

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

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


}

Emp(員工表)

 

package cn.onetomanydouble.entity;

import org.hibernate.annotations.*;
import org.hibernate.annotations.Cache;

import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.io.Serializable;

/**
 * Created by accp on 2017/2/8.
 */
@Entity
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Table(name = "EMP1")
public class Emp implements Serializable {
    @Id
    @GeneratedValue
    private Integer empno;
    @Column
    private String ename;
    @ManyToOne
    @JoinColumn(name = "deptno")
    private Dept dept;
   /* @Column
    private Double salary;
    @Column
    private String job;*/

    /*public Double getSalary() {
        return salary;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }*/

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public Dept getDept() {
        return dept;
    }

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


}

在配置一對多雙向的時候一定要搞清楚主外鍵關系。

第二步:在hibernate.cfg.xml文件中配置<mapping>節點

 <mapping class="cn.onetomanydouble.entity.Dept"/>
 <mapping class="cn.onetomanydouble.entity.Emp"/>

第三步:書寫測試類

package cn.onetomanydouble.test;

import cn.onetomanydouble.entity.Dept;
import cn.onetomanydouble.entity.Emp;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * Created by accp on 2017/2/8.
 */
public class ManyToOneTest {

    Configuration cfg;
    Session session;
    Transaction tx;
    SessionFactory factory;
    @Before
    public void mybefore(){
        cfg=new Configuration().configure();
        factory=cfg.buildSessionFactory();
        session=factory.openSession();
         tx=session.beginTransaction();
    }

    @After
    public void myafter(){
       tx.commit();
        session.close();
    }

    @Test
    public void demo(){
        System.out.println(123);
    }

     @Test
   public void select(){


         /**
          * load()方法
          * fetch = FetchType.EAGER(立即加載)    fetch = FetchType.LAZY(懶加載)
          * 情況一:當在一的一方設置是否加載時
          *   fetch = FetchType.EAGER (立即加載)
          *   不查詢不發送sql語句
          *   左外連接  兩表查詢
          *   查詢關聯表的屬性時 不在重新發送sql
          *
          *
          *   fetch = FetchType.LAZY(懶加載)
          *   不查詢不發送sql語句
          *   查詢單一屬性時   只查詢當前表的   當查詢關聯屬性時
          *   重新向數據庫發送sql
          *
          *   get()方法
          *   fetch = FetchType.EAGER (立即加載) fetch = FetchType.LAZY(懶加載)
          *  (1) 情況一:當在多的一方設置
          *   fetch = FetchType.EAGER (立即加載)
          *   先向數據庫查詢一次
          *   左外連接   兩表查詢
          *   當用到屬性時  直接打印對應的屬性值
          *
          *   fetch = FetchType.LAZY(懶加載)
          *   只加載當前類的語句
          *   當查詢當前表的屬性時  只向數據庫發送查詢當前表的sql
          *
          *   當查詢關聯表的屬性時  發送關聯表的sql語句
          *
          */


         /*Transaction tx = factory.getCurrentSession().beginTransaction();
         Dept dept = factory.getCurrentSession().get(Dept.class, 1);
         for (Emp emp:dept.getEmps()) {
             System.out.println(emp.getEname());
         }

         tx.commit();
         factory.getCurrentSession().close();

         System.out.println("=====================");
         Transaction tx2 = factory.getCurrentSession().beginTransaction();
         Dept dept2 = factory.getCurrentSession().get(Dept.class, 1);
         for (Emp emp:dept2.getEmps()) {
             System.out.println(emp.getEname());
         }
         tx2.commit();
*/
         Dept dept = session.get(Dept.class, 1);
         System.out.println("=============");
         System.out.println(dept.getClass());
         System.out.println(dept.getDeptname());
         System.out.println(dept.getEmps().iterator().next().getEname());

       /*  Emp emp = session.get(Emp.class, 2);
        System.out.println("===========");*/
       /* System.out.println(emp.getEname());
        System.out.println(emp.getDept().getDeptname());*/

    }


    @Test
    public void add(){
        /*//創建部門
        Dept dept=new Dept();
        dept.setDeptname("產品部");

        //創建員工
        Emp emp=new Emp();
        emp.setEname("劉二雄");
        emp.setDept(dept);
        dept.getEmps().add(emp);
        //因為cascade級聯只需保存部門即可保存員工
        session.save(dept);*/

        Dept dept=new Dept();
        dept.setDeptname("清潔部");

        //創建員工
        Emp emp=new Emp();
        emp.setEname("飄哥");
        emp.setDept(dept);
        dept.getEmps().add(emp);
        session.save(dept);
    }
}

執行完代碼后一定要看看生成的sql語句,加深印象。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM