Hibernate必知必会——持久化List

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010871004/article/details/81914629

简介

很多的需求中,可能会有一个对象中包含着另一个对象,而包含的这个对象又是一个List,在Java中,List可能是一个ArrayList或者是LinkedList。对于List的数据类型,hibernate又是如何做到持久化的?

泛型为简单类型的List

package com.hibernate.work_with_collections;

import java.util.List;

import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OrderColumn;
import javax.persistence.Table;

import org.hibernate.annotations.IndexColumn;

@Entity
@Table(name = "student")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private long id;

    @Column(name = "name")
    private String name;
    @ElementCollection(fetch = FetchType.LAZY)
    @CollectionTable(name = "email")
    @IndexColumn(name = "email_index")
    private List<String> emails;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<String> getEmails() {
        return emails;
    }

    public void setEmails(List<String> emails) {
        this.emails = emails;
    }

    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", emails=" + emails + "]";
    }

}

这边会说是简单类型的原因的是,List<String>,中的泛型是个String,不是我们自定义的一个类型。
@ElementCollection(fetch = FetchType.LAZY):表明在获取email的数据时候,会进行延迟加载,查询的时候,会分成两次查询语句,如果fetch = FetchType.EAGER,hibernate会使用左外连接进行查询。
@CollectionTable(name = “email”):将依赖的email创建email表。
@IndexColumn(name = “email_index”):email表中会增加一个email_index的列。

泛型为复杂类型的List

package com.hibernate.work_with_collections;

import java.util.List;

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.Table;

@Entity
@Table(name = "student")
public class ComplexStudent {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @Column(name = "name")
    private String name;
    @OneToMany(cascade = { CascadeType.ALL })
    @JoinColumn(name = "student_id")
    private List<Degree> degrees;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Degree> getDegrees() {
        return degrees;
    }

    public void setDegrees(List<Degree> degrees) {
        this.degrees = degrees;
    }

    @Override
    public String toString() {
        return "ComplexStudent [id=" + id + ", name=" + name + ", degrees=" + degrees + "]";
    }

}
package com.hibernate.work_with_collections;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "degree")
public class Degree {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @Column(name = "degreename")
    private String degreeName;
    @Column(name = "passingyear")
    private String passingYear;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getDegreeName() {
        return degreeName;
    }

    public void setDegreeName(String degreeName) {
        this.degreeName = degreeName;
    }

    public String getPassingYear() {
        return passingYear;
    }

    public void setPassingYear(String passingYear) {
        this.passingYear = passingYear;
    }

    @Override
    public String toString() {
        return "Degree [id=" + id + ", degreeName=" + degreeName + ", passingYear=" + passingYear + "]";
    }

}

上述代码会给degree创建一外键关联student的主键,主要重要的注解是@JoinColumn(name = “student_id”),degree表的外键是student_id。如果删除掉这个注解,hibernate会创建第三张表,来映射对student表数据和degree表数据的关联。
@OneToMany(cascade = { CascadeType.ALL }):

cascade属性: 指定级联操作的行为(可多选)
  1. CascadeType.PERSIST 级联新增(又称级联保存):
    获取A对象里也同时也重新获取最新的B时的对象。即会重新查询数据库里的最新数据,并且,只有A类新增时,会级联B对象新增。若B对象在数据库存(跟新)在则抛异常(让B变为持久态),对应EntityManager的presist方法,调用JPA规范中的persist(),不适用于Hibernate的save()方法
  2. CascadeType.MERGE 级联合并(又称级联更新) 指A类新增或者变化,会级联B对象(新增或者变化)
    ,对应EntityManager的merge方法,调用JPA规范中merge()时,不适用于Hibernate的update()方法
    CascadeType.REMOVE 级联删除
    只有A类删除时,会级联删除B类,即在设置的那一端进行删除时,另一端才会级联删除,对应EntityManager的remove方法,调用JPA规范中的remove()时,适用于Hibernate的delete()方法
  3. CascadeType.REFRESH 级联刷新
    获取order(一或多)对象里也同时也重新获取最新的items(多)的对象,对应EntityManager的refresh(object),调用JPA规范中的refresh()时,适用于Hibernate的flush()方法
  4. CascadeType.ALL 包含所有持久化方法

猜你喜欢

转载自blog.csdn.net/u010871004/article/details/81914629