hibernate5(15)注解映射[7]集合关联

集合注解映射

集合关系映射可以看成是一对多关系映射的一种简化,在一个电商系统里,出售的产品可能会有多张展示图片,如果我们使用一对多来建立关联映射时,需要创建一个实体类Images,里面可能有属性:图片在服务器的访问路径url和图片所属产品productId。但如果我们使用集合关系映射,则无需新建一个实体类,只需在Product中定义一个集合成员属性即可。

Set集合

在产品中,我们的图片路径一般是不会相同的,我们可以使用Set集合来建立映射

我们下面来看这一需求的配置示例:

@Entity
@Table(name = "t_product")
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private String name;
    @ElementCollection(fetch = FetchType.LAZY)//使用此注解配置集合映射关联
    private Set<String> images ;
    //忽略get和set方法
}

下面是我们的测试方法:

Product product = new Product();
product.setName("product");
Set<String> imagesUrl = new HashSet<String>();
for(int i = 0 ; i < 5; i ++){
    imagesUrl.add("imageUrl"+ i);
}
product.setImages(imagesUrl);
session.save(product);

执行上述测试方法,我们查询数据库:

即集合映射的内部实现是hibernate会为我们单独创建一张表来存储这些信息。

如果我们想要自定义这张表的表明,属性名,我们可以通过以下配置:

@ElementCollection(fetch = FetchType.LAZY)
@JoinTable(name = "t_product_images",joinColumns = @JoinColumn(name = "proId"))
@Column(name = "imagesUrl")
private Set<String> images ;

重新执行测试方法,查询数据库:

表名和属性名都被成功修改了。

List集合

使用Set集合能确保元素属性不重复,但我们无法确定元素的插入顺序,与Set集合不同,List集合在数据库中多了一个索引属性,我们根据索引属性来获取记录,同时也可以根据索引属性得知元素的插入先后顺序。

下面我们使用list来模拟一个数据库级别的排队系统:在一个医院有很多个医生,每个医生都有很多病人排队就诊。下面是我们的医生类:

@Entity
@Table(name = "t_doctor")
public class Doctor {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private String name;
    @ElementCollection(fetch = FetchType.LAZY)
    @JoinTable(name = "t_patient",joinColumns = @JoinColumn(name = "doctor_id"))
    @Column(name = "patient_name")
    //@IndexColumn(name = "orders",base = 100)在新版本中,此注解已被废弃,推荐使用下面两个注解取代
    @OrderColumn(name = "orders")//表示索引列名为patient_name
    @ListIndexBase(100)//表示索引从100开始
}

下面是我们的添加测试代码:

Doctor doctor = new Doctor();
doctor.setName("doctor");
List<String> patients = new ArrayList<String>();
for(int i = 0 ; i < 5; i ++){
    patients.add("patient" + i);
}
doctor.setPatientName(patients);
session.save(doctor);

运行代码,查看数据库:

数据被成功插入,并且细心对比前面set集合图片,我们发现这里是有序的,执行下列查询操作:

Doctor doctor = session.get(Doctor.class, 1);
System.out.println(doctor);
for(String string : doctor.getPatientName()){
    System.out.println(string);
}

控制台打印:

说明我们获得的数据是有序的,这样就可以动态删除第一个,而新纪录从尾部加入,实现一个队列的效果。

事实上,我们使用List来配置一对多映射中的多方,也能完成同样的效果

Map集合

在产品中,可能会有不同的规格对象不同的价格,这种需求我们可以通过Map集合映射来实现:

package com.zeng4.model;

import java.util.Map;
import java.util.Set;

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.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.MapKey;
import javax.persistence.MapKeyColumn;
import javax.persistence.Table;

import org.hibernate.annotations.Type;
@Entity
@Table(name = "t_product")
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private String name;
    @ElementCollection
    @JoinTable(name = "t_specs_prize",joinColumns = @JoinColumn(name = "product_id"))
    @Column(name = "prize")//对应规格的价格
    @MapKeyColumn(name = "specs")//对应键值列名称
    private Map<String, Double> prize;

}

下面是我们的测试方法:

Product product = new Product();
product.setName("prodcut_with_many_prize");
HashMap prizes= new HashMap();
for(int i = 0 ; i < 5 ; i ++){
prizes.put("specs"+i,1.2* i);
}
product.setPrize(prizes);
session.save(product);

执行测试方法,查询数据库:

我们的Product类中的Map集合属性key是规格,对应与specs,值是价格,对应于peize。

Map集合关联操作,我们可以通过类似下面代码进行:

Product product = session.get(Product.class, 1);
for(Entry<String, Double> entry : product.getPrize().entrySet()){
    System.out.println("specs = " + entry.getKey() + "————prize = " + entry.getValue());
}

运行方法,控制台打印:

源码下载

本节内容测试代码可到https://github.com/jeanhao/hibernate/tree/master/collection下载

时间: 2024-11-10 17:08:54

hibernate5(15)注解映射[7]集合关联的相关文章

hibernate5(13)注解映射[5]一对一共享主键关联

一对一共享主键 下面我们直接通过实例来讲解共享主键配置: 主键主控方:Article package com.zeng2.model; @Table(name = "t_article2") @Entity public class Article { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String title; @OneToOne(cascade = Casc

hibernate5(10)注解映射[2]一对多单向关联

在上一篇文章里.我们从端方向一端建立关联关系,完毕了从文章到作者的关联关系建立.但在实际的博客站点中,用户肯定还须要获取自己所写的文章,这时能够建立用户(一)对文章(多)的单向关联映射. 先来看我们的一方配置实例 package com.zeng.model; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.F

hibernate5(9)注解映射[1]一对多单向关联

一对多单向关联映射 在实际的博客网站中,用户肯定需要获取自己所写的文章,这时可以建立用户(一)对文章(多)的单向关联映射. 先来看我们的一方配置实例 package com.zeng.model; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persisten

hibernate5(12)注解映射[4]一对一外键关联

在实际博客站点中,文章内容的数据量非常多,它会影响我们检索文章其他数据的时间,如查询公布时间.标题.类别的等. 这个时候,我们能够尝试将文章内容存在还有一张表中,然后建立起文章--文章内容的一对一映射 一对一关联有两种方式,一种是外键关联.还有一种是复合主键关联. 外键关联 以下我们先看一个一对一单向关联的实例 /*************关联关系维护方************/ @Table(name = "t_article") @Entity public class Artic

hibernate5(14)注解映射[6]多对多中间表关联

在我们的角色管理系统中,一个用户可以有多种角色,一种角色可以赋予多个用户,显然用户和角色就是典型的多对多关系.又或者博客网站上,用户与文章点赞记录也是一个多对多关系,即一个用户可以点赞多篇文章,一篇文章可以给多个用户点赞等,这时候,我们往往需要附加一些信息,比如授权时间.点赞时间等.在上面两个实例中,都可对应于hibernate多对多映射关系的两种方式,在多对多映射中,我们往往使用中间表来建立关联关系,而且会是双向关联,确保任意一方添加或删除,都可以对中间表进行操作来维护关联关系. 下面我们来看

Java注解应用,自定义注解映射实现方案说明.

插件结构如图: 注册模块定义了三个:用于实体与表映射的注解,用于属性到表字段的映射,用于映射时过滤掉的注解. 1.用于实体与表映射的注解 package com.dobby.plugins.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.a

hibernate注解映射属性

https://blog.csdn.net/dada678/article/details/51786201 1.普通属性 @Entity:修饰的持久化类的所有属性都会被映射到底层数据库. @Column:修饰属性 @Transient:修饰不想持久化保存的属性. @Lob:修饰大数据属性. 当属性为byte[].Byte[]时数据库对应Blob 当属性为char[].character[].String时,对应为Clob. @Temporal修饰日期类型 支持TemporalType.DATE

【SSH进阶之路】Hibernate映射——多对多关联映射(八)

上篇博文[SSH进阶之路]Hibernate映射--一对多关联映射(七),我们介绍了一对多关联映射,它是多对多关联映射的基础. 多对多映射是现实生活中最常见的映射,也是最容易理解的映射.废话少说,直接开始. 映射原理 不论是单向关联还是双向关联都是通过第三张表,将两个表中的主键放到第三张做一个关联.用第三张表来解决可能会造成数据冗余的问题. 举例 一个用户(User)对多个角色(Role),一个角色对多个用户. 分类 单向的多对多关联映射(单向User--->Role) 对象模型 关系模型 实例

【SSH进阶之路】Hibernate映射——一对多关联映射(七)

上上篇博文[SSH进阶之路]Hibernate映射--一对一单向关联映射(五),我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息. 上篇博文[SSH进阶之路]Hibernate映射--一对一双向关联映射(六),双向关联映射解决了单向关联映射只能从一端加载信息的缺陷,当然,双向关联映射并不影响存储,只影响加载.下面我们开始今天的内容: 一对多关联映射 映射原理 一对多关联映射和多对一关联映射的映射原理是一致的,