Hibernate之集合属性映射

通常情况下,我们在定义实体类时会遇到类的属性有集合类型的,比如数组,列表等等,在这种情况下,我们对这个属性的操作是和之前对待整数型,大数据型的都不一样.Hibernate要求持久化一个集合值字段必须声明接口,这样做是为了在持久化一个实例时,Hibernate的会自动把程序中的集合实现类替换成Hibernate自己的集合实现类。在这种情况下,休眠提供了一个注解应对所有类型的属性:@ElementCollection这个注解也有两个属性:

(1)fetch:不是必须的,指定该实体对集合的抓取策略,即当程序初始化一个实体的时候,是否要立即抓取该实体的集合属性中的所有元素,其值可以为:FetchType. EAGER(立即抓取)和FetchType.LAZY(延迟抓取,也是默认值)

(2)targetClass:不是必须的,该属性指定集合属性中元素的类型。

我们可以这样想,一个集合中包含着很多的元素,就相当于一个集合中有着很多的属性,这在数据库中就相当于一个表中包含着一个表,这样肯定是不行的,因此,一般是针对这个集合重新创建一个表来保存这个集合,那么这里就必须包含一个外键列,用于参照到主键列,这个时候这个外键列就使用@JoinColumn来进行映射。

在Hibernate中使用@CollectionTable注解映射保存的集合属性的表,其有以下几个属性(都不是必需加上的):

(1)name:指定保存集合属性的数据表的表名

(2)catalog:指定将保存集合属性的数据表放入指定的目录中,没有则保存至默认的目录中

(3)schema:指定将保存集合属性的数据表放入指定的模式中,没有则保存至默认的模式中

(4)indexes:为持久化类所映射的表设置索引

(5)joinColumns:该属性值为@JoinColumn数组,每个@JoinColumn映射一个外键列

(6)uniqueConstraints:为持久化类所映射的表设置唯一约束。

在这里,@ JoinColumn注解是专门用来定义外键列的,其属性有以下:

(1)columnDefinition:指定休眠使用该属性值指定的SQL片段来创建外键列

(2)name:指定该外键列的列名

(3)insertable:指定该列是否包含在Hibernate生成的插入语句的列列表中,默认为真

(4)updatale:指定该列是否包含在Hibernate生成的更新语句的列列表中,默认为真

(5)nullable:指定该列是否允许为空,默认为真

(6)table:指定该列所在数据表的表名

(7)unique:指定是否为该列增加唯一约束

(8)referencedColumnName:指定该列所参照的主键列的列名

在集合中,有的集合是有序的,即有着显示的索引值,即所谓的主键,因此针对不同的集合处理的方式也是不一样,下面依次介绍几种不同的集合属性映射方法。

 

(一)名单集合属性

下面直接上代码:

package cn.test.Collection;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.*;



@Entity
@Table(name="person_inf")
public class Person {

	@Id 
	@Column(name="person_id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	public int getId() {
		return id;
	}

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

	private String name;
	private int age;
	
	//集合属性,保留该对象关联的学校
	//设置数组表的数据类型,为String类型
	@ElementCollection(targetClass=String.class)
	//设置数组表的表名以及表的外键
	@CollectionTable(name="school_inf",joinColumns=@JoinColumn(name="person_id",nullable=false))
	//设置数组表的列名
	@Column(name="school_name")
	//设置映射集合元素的索引列
	@OrderColumn(name="array_order")
	private List <String>schools=new ArrayList<>();
	//private String [] schools;

	public List<String> getSchools() {
		return schools;
	}

	public void setSchools(List<String> schools) {
		this.schools = schools;
	}
	public String getName() {
		return name;
	}

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

	public int getAge() {

		return age;
	}

	public void setAge(int age) {

		this.age = age;
	}

}


操作类:

package cn.test.Collection;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class PersonManager {

	public static void main(String[]args)
	{
		Configuration configuration=new Configuration().configure();
		SessionFactory sessionFactory=configuration.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		Person person=new Person();
		person.setId(1);
		person.setAge(18);
		person.setName("王二麻子");
		
		
		
		person.getSchools().add("中学");
		person.getSchools().add("大学");
		session.save(person);
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
}

注意,在这里的实体类中要加上一个id属性,这个是在数组表中充当主键的,在实体类中充当外键,所以不加上这个的话就无法建实体表。

运行结果:

(二)数组集合属性

实体类:

package cn.test.Collection;

import java.util.ArrayList;

import java.util.List;

import javax.persistence.*;



@Entity
@Table(name="person_inf")
public class Person {

	@Id 
	@Column(name="person_id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	public int getId() {
		return id;
	}

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

	private String name;
	private int age;
	
	//集合属性,保留该对象关联的学校
	//设置数组表的数据类型,为String类型
	@ElementCollection(targetClass=String.class)
	//设置数组表的表名以及表的外键
	@CollectionTable(name="school_inf",joinColumns=@JoinColumn(name="person_id",nullable=false))
	//设置数组表的列名
	@Column(name="school_name")
	//设置映射集合元素的索引列
	@OrderColumn(name="array_order")
	//private List <String>schools=new ArrayList<>();
	private String [] schools;

	public String getName() {
		return name;
	}

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

	public int getAge() {

		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String[] getSchools() {
		return schools;
	}

	public void setSchools(String[] schools) {
		this.schools = schools;
	}
}

操作类:

package cn.test.Collection;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class PersonManager {

	public static void main(String[]args)
	{
		Configuration configuration=new Configuration().configure();
		SessionFactory sessionFactory=configuration.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		Person person=new Person();
		//person.setId(1);
		person.setAge(18);
		person.setName("王二麻子");
		String []aStrings= {"一中","二中","三中"};
		person.setSchools(aStrings);
		session.save(person);
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
}

执行结果:

(三)设置Set集合属性映射

实体类:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.*;



@Entity
@Table(name="person_inf")
public class Person {

	@Id 
	@Column(name="person_id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	public int getId() {
		return id;
	}

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

	private String name;
	private int age;
	
	@ElementCollection(targetClass=String.class)
	
	@CollectionTable(name="school_inf",joinColumns=@JoinColumn(name="person_inf",nullable=false))
	
	@Column(name="school_name",nullable=false)
	private Set<String> schools=new HashSet<>();
    public Set<String> getSchools() {
		return schools;
	}

	public void setSchools(Set<String> schools) {
		this.schools = schools;
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {

		return age;
	}

	public void setAge(int age) {

		this.age = age;
	}

	
}

操作类:

package cn.test.Collection;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class PersonManager {

	public static void main(String[]args)
	{
		Configuration configuration=new Configuration().configure();
		SessionFactory sessionFactory=configuration.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		Person person=new Person();
		person.setId(1);
		person.setAge(18);
		person.setName("王二麻子");
		person.getSchools().add("中学");
		person.getSchools().add("大学");

		session.save(person);
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
}

运行结果:

(4)设置对象属性的映射

实体类:

package cn.test.Collection;

import java.util.ArrayList;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.*;



@Entity
@Table(name="person_inf")
public class Person {

	@Id 
	@Column(name="person_id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	public int getId() {
		return id;
	}

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

	private String name;
	private int age;
	private Name name2;
	public Name getName2() {
		return name2;
	}

	public void setName2(Name name2) {
		this.name2 = name2;
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {

		return age;
	}

	public void setAge(int age) {

		this.age = age;
	}
}

内部类,即实体类中的属性类:


package cn.test.Collection;

import javax.persistence.*;


import org.hibernate.annotations.Parent;
@Embeddable
public class Name {
	@Column (name="person_firstname")
	private String first;
	@Column (name="person_lastname")
	private String last;
	
	@Parent
	private Person owner;
	
	public Name()
	{
		
	}

	public Name(String first, String last) {
		//注意,此处的super()一定得加上,不加上是无法运行成功的
		super();
		this.first = first;
		this.last = last;
	}

	public String getFirst() {
		return first;
	}

	public void setFirst(String first) {
		this.first = first;
	}

	public String getLast() {
		return last;
	}

	public void setLast(String last) {
		this.last = last;
	}

	public Person getOwner() {
		return owner;
	}

	public void setOwner(Person owner) {
		this.owner = owner;
	}
}

操作类:


package cn.test.Collection;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class PersonManager {

	public static void main(String[]args)
	{
		Configuration configuration=new Configuration().configure();
		SessionFactory sessionFactory=configuration.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		Person person=new Person();
		person.setId(1);
		person.setAge(18);
		person.setName("王二麻子");
		
		person.setName2(new Name("zhangsan","lisi"));		
		
		session.save(person);
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
}

运行结果:

当然,这里可以通过另外一种注解方式,只需要对实体类进行注解,然后在内部类中不需要进行什么注解,代码中主需要在实体类定义的内部类前面添加如下代码:


@Embedded
	@AttributeOverride(column = @Column(name="person_firstName"), name = "first")
	@AttributeOverride(column = @Column(name="person_lastName"), name = "last")	
	private Name name2;

通过AttributeOverride注解来指定该类的属性以及在表中的列名。

(5)设置Map集合映射

实体类:


import java.util.ArrayList;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.*;



@Entity
@Table(name="person_inf")
public class Person {

	@Id 
	@Column(name="person_id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	public int getId() {
		return id;
	}

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

	private String name;
	private int age;
    @ElementCollection(targetClass=Float.class)
	//定义Map集合映射的表的名称以及外键
	@CollectionTable(name="score_inf",joinColumns=@JoinColumn(name="person_id",nulla    ble=false))
	//定义Map集合表中key键对应的列名
	@MapKeyColumn(name="subject_name")
	//key对应的数据类型,这里的key是指的科目,例如数学英语等,属于String类型
	@MapKeyClass(String.class)
	//指定Map集合中值的名称,这里代表的是分数
	@Column(name="mark")
	private Map<String, Float> score=new HashMap<>();
    //省略get方法和set方法
}

操作类:


import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class PersonManager {

	public static void main(String[]args)
	{
		Configuration configuration=new Configuration().configure();
		SessionFactory sessionFactory=configuration.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		Person person=new Person();
		person.setId(1);
		person.setAge(18);
		person.setName("王二麻子");
        
        person.getSchools().add("中学");
		person.getSchools().add("大学");
		session.save(person);
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
}

因此,对于上面的几种数组和对象的操作我们不难发现,处理的过程都差不多,只是针对不同的集合或对象处理的细节有点不一样。其实这些对集合的操作都是比较简单的,只要记住了这些注解以及这些注解的属性值就行了

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值