1. 程式人生 > >8、JPA-映射-雙向一對一

8、JPA-映射-雙向一對一

manage ini ack toon 雙向 外連接 factor int 圖片

一個管理對應一個部門,一個部門對應一個管理,例中由部門維護關聯關系

實體類

Department

package com.jpa.yingshe;

import javax.persistence.*;

@Table(name = "JPA_DEPARTMENTS")
@Entity
public class Department {

    private Integer id;
    private String deptName;

    private Manager mgr;

    @GeneratedValue
    @Id
    public Integer getId() {
        
return id; } public void setId(Integer id) { this.id = id; } @Column(name = "DEPT_NAME") public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } // 使用 @OneToOne 來映射 1-1 關聯關系
// 若需要在當前數據表中添加主鍵則需要使用 @JoinColumn 來進行映射 // 1-1 關聯關系, 需要添加 unique=true @JoinColumn(name = "MGR_ID", unique = true) @OneToOne() public Manager getMgr() { return mgr; } public void setMgr(Manager mgr) { this.mgr = mgr; } }

Manager

package com.jpa.yingshe;

import
javax.persistence.*; @Table(name = "JPA_MANAGERS") @Entity public class Manager { private Integer id; private String mgrName; private Department dept; @GeneratedValue @Id public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Column(name = "MGR_NAME") public String getMgrName() { return mgrName; } public void setMgrName(String mgrName) { this.mgrName = mgrName; } // 對於不維護關聯關系, 沒有外鍵的一方, 使用 @OneToOne 來進行映射, 建議設置 mappedBy,減少update語句 @OneToOne(mappedBy = "mgr") public Department getDept() { return dept; } public void setDept(Department dept) { this.dept = dept; } }

測試

添加

package jpa.test;

import com.jpa.yingshe.Department;
import com.jpa.yingshe.Manager;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class JPAyingshe {
    private EntityManagerFactory entityManagerFactory;
    private EntityManager entityManager;
    private EntityTransaction transaction;

    @Before
    public void init() {
        entityManagerFactory = Persistence.createEntityManagerFactory("jpaname");
        entityManager = entityManagerFactory.createEntityManager();
        transaction = entityManager.getTransaction();
        transaction.begin();
    }

    @After
    public void destroy() {
        transaction.commit();
        entityManager.close();
        entityManagerFactory.close();
    }

    // 雙向 1-1 的關聯關系, 建議先保存不維護關聯關系的一方, 即沒有外鍵的一方, 這樣不會多出 UPDATE 語句
    @Test
    public void testOneToOnePersistence() {
        Manager mgr = new Manager();
        mgr.setMgrName("M-BB");

        Department dept = new Department();
        dept.setDeptName("D-BB");

        //設置關聯關系
        mgr.setDept(dept);
        dept.setMgr(mgr);

        //執行保存操作
        entityManager.persist(mgr);
        entityManager.persist(dept);
    }
}

技術分享圖片

查詢

獲取維護關聯關系的一方

// 默認情況下, 獲取維護關聯關系的一方, 會通過左外連接獲取其關聯的對象,非懶加載模式
// 可以通過 @OntToOne 的 fetch 屬性來修改加載策略
@Test
public void testOneToOneFind() {
    Department dept = entityManager.find(Department.class, 33);
    System.out.println(dept.getDeptName());
    System.out.println(dept.getMgr().getClass().getName());
}

技術分享圖片

修改加載策略

@JoinColumn(name = "MGR_ID", unique = true)
@OneToOne(fetch = FetchType.LAZY)
public Manager getMgr() {
    return mgr;
}

技術分享圖片

獲取不維護關聯關系的一方

// 默認情況下, 獲取不維護關聯關系的一方, 是通過左外連接獲取其關聯的對象
// 可以通過 @OneToOne 的 fetch 屬性來修改加載策略. 但依然會再發送 SQL 語句來初始化其關聯的對象
// 這說明在不維護關聯關系的一方, 不建議修改 fetch 屬性
@Test
public void testOneToOneFind2() {
    Manager mgr = entityManager.find(Manager.class, 34);
    System.out.println(mgr.getMgrName());

    System.out.println(mgr.getDept().getClass().getName());
}

技術分享圖片

修改加載策略

// 對於不維護關聯關系, 沒有外鍵的一方, 使用 @OneToOne 來進行映射, 建議設置 mappedBy,減少update語句
@OneToOne(mappedBy = "mgr",fetch = FetchType.LAZY)
public Department getDept() {
    return dept;
}

技術分享圖片

8、JPA-映射-雙向一對一