欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JPA一对多映射案例

程序员文章站 2022-04-23 15:45:38
...

班级表和学员资料表就是一对多的关系。一个班级有多个学员,一个学员属于某个班级。

班级学员映射后的表结构如下:

班级表结构:

JPA一对多映射案例

学员资料表结构:

JPA一对多映射案例

需要的jar包和数据库连接配置不再说了,双向一对一案例已经说了

班级类BasClass.java

package com.jason.bean;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * one端
 * 
 * 碰到many为末端的加载就是延迟加载,若one为末端则为立即加载,除了one-to-one。
 * 
 * @author jason
 * 
 */
@Entity
@Table(name = "bas_class")
public class BasClass implements Serializable {
	private static final long serialVersionUID = -4398577825279584033L;
	private String claId;
    private String claName;
    private Set<StuInfo> items = new HashSet<StuInfo>();

    public BasClass() {}
    
    public BasClass(String claName) {
		this.claName = claName;
	}

	// String类型不能用uuid,需要人为指定
    @Id
    @Column(length = 12)
    public String getClaId() {
		return claId;
	}
	public void setClaId(String claId) {
		this.claId = claId;
	}
    
    @Column(nullable = false)
	public String getClaName() {
		return claName;
	}
	public void setClaName(String claName) {
		this.claName = claName;
	}

	// @OneToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE})
    // mappedBy="basClass": 指明BasClass类为双向关系维护端,负责外键的更新
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "basClass")
    public Set<StuInfo> getItems() {
        return items;
    }

    public void setItems(Set<StuInfo> items) {
        this.items = items;
    }

    /**
     * 添加学员资料
     * 
     * @param student
     */
    public void addStuInfo(StuInfo item) {
        if (!this.items.contains(item)) {
            this.items.add(item);
            item.setBasClass(this);
        }
    }

    /**
     * 删除学员资料
     * 
     * @param student
     */
    public void removeStuInfo(StuInfo item) {
        if (this.items.contains(item)) {
            item.setBasClass(null);
            this.items.remove(item);
        }
    }

}

学员类StuInfo.java

package com.jason.bean;

import java.io.Serializable;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

/**
 * many端
 * 
 * 在one-to-many双向关联中,多的一方为关系维护端,关系维护端负责外键记录的更新 
 * 关系被维护端是没有权力更新外键记录的
 * 
 * @author jason
 * 
 */

@Entity
@Table(name = "stu_info")
public class StuInfo implements Serializable {
	private static final long serialVersionUID = 1505762337775729449L;
	private Integer stuId;
    private String stuName;
    private Integer age;
    private BasClass basClass;

    public StuInfo() {
        super();
    }
    
    public StuInfo(String stuName, Integer age) {
		super();
		this.stuName = stuName;
		this.age = age;
	}

    @Id
    @GeneratedValue
    public Integer getStuId() {
		return stuId;
	}

	public void setStuId(Integer stuId) {
		this.stuId = stuId;
	}
    
    @Column(length = 20, nullable = false)
    public String getStuName() {
		return stuName;
	}

	public void setStuName(String stuName) {
		this.stuName = stuName;
	}
    
    @Column(nullable = false)
    public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}
	
    // optional=true:可选,表示此对象可以没有,可以为null;false表示必须存在
    @ManyToOne(cascade = { CascadeType.REFRESH, CascadeType.MERGE }, optional = true)
    @JoinColumn(name = "cla_stu_id")
    public BasClass getBasClass() {
        return basClass;
    }

	public void setBasClass(BasClass basClass) {
        this.basClass = basClass;
    }

}

BasClassTest测试类

package junit.test;

import java.io.Serializable;
import java.util.List;
import java.util.Set;

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

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import com.jason.bean.BasClass;
import com.jason.bean.StuInfo;

@SuppressWarnings("unchecked")
public class BasClassTest {
	private static EntityManagerFactory factory;
	private static EntityManager em;
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		 factory = Persistence.createEntityManagerFactory("jason");
		 em = factory.createEntityManager();
	     em.getTransaction().begin();
	}
    /**
     * 添加班级BasClass时同时添加两个学员StuInfo,因为班级BasClass为双向关系维护者,起着主导作用
     */
    @Test
    public void save() {
    	BasClass bc = new BasClass();
    	bc.setClaName("A班");
        //UUID.randomUUID().toString()
    	bc.setClaId("a1");
    	bc.addStuInfo(new StuInfo("jason1",23));
    	bc.addStuInfo(new StuInfo("jason2",28));
        em.persist(bc);

    }
    
    /**
     * 删除BasClass对象时,会自动删除StuInfo对象(即:父对象删除时子对象跟着删除)
     */
    @Test
    public void detele1(){
    	BasClass bc=em.getReference(BasClass.class, "A班");
        em.remove(bc);
    }
    
    /**
     * 删除子对象时,父对象没影响
     */
    @Test
    public void detele2(){
        StuInfo item=em.getReference(StuInfo.class, (Serializable)3);
        em.remove(item);
    }

    @Test
    public void find1(){
        List<BasClass> bas=em.createQuery("select o from bas_class o").getResultList();
        for(BasClass bc : bas){
            System.out.println("班级ID:--"+bc.getClaId()+"/t"+"班级名称:--"+bc.getClaName());
            Set<StuInfo> stuinfos=bc.getItems();
            for(StuInfo stu : stuinfos){
                System.out.println("学员姓名:--"+stu.getStuName()+"年龄:--"+stu.getAge());
            }
            System.out.println("===============");
        }
    }
    
    //运行结果为
    
	@Test
    public void find2(){
        List<StuInfo> items=em.createQuery("select o from stu_info o").getResultList();
        for(StuInfo item : items){ 
            System.out.println("学员姓名:"+item.getStuName()+"年龄:"+item.getAge());
            BasClass bas=item.getBasClass();
            System.out.println("班级ID:"+bas.getClaId()+", "+"班级名称:"+bas.getClaName());
            System.out.println("============");
        }
    }
    
    
    /**
     * 测试jpa环境是否搭建成功
     * 
     */
    @Test
    public void test() {
        Persistence.createEntityManagerFactory("jason");
    }
    
    @AfterClass
	public static void tearDownAfterClass() throws Exception {
    	em.getTransaction().commit();
        em.close();
        factory.close();
	}
}