通常情况下,我们在定义实体类时会遇到类的属性有集合类型的,比如数组,列表等等,在这种情况下,我们对这个属性的操作是和之前对待整数型,大数据型的都不一样.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();
}
}
因此,对于上面的几种数组和对象的操作我们不难发现,处理的过程都差不多,只是针对不同的集合或对象处理的细节有点不一样。其实这些对集合的操作都是比较简单的,只要记住了这些注解以及这些注解的属性值就行了