JPA和Hibernate中@MapKey,@ MapKeyColumn和@MapKeyJoinColumn的区别

Cha*_*nya 21 java orm hibernate jpa hibernate-mapping

根据Hibernate文档,如果我们想将Map用作实体之间的关联,则可以使用多个注释.医生说:

或者,映射键映射到一个或多个专用列.要自定义映射,请使用以下注释之一:

@MapKeyColumn如果map键是基本类型.如果未指定列名,则使用属性的名称,后跟下划线,后跟KEY(例如orders_KEY).@MapKeyEnumerated/@MapKeyTemporal如果地图密钥类型分别是枚举或日期.@ MapKeyJoinColumn/@ MapKeyJoinColumns如果映射键类型是另一个实体.当地图键是可嵌入对象时,@ AttributeOverride/@ AttributeOverrides.使用密钥.作为可嵌入对象属性名称的前缀.如果不使用泛型,也可以使用@MapKeyClass来定义键的类型.

通过一些示例,我能够理解@MapKey仅用于将键映射到目标实体的属性,并且此键仅用于获取记录.@MapKeyColumn用于将键映射到目标实体的属性,该键用于保存和获取记录.如果这是正确的,请告诉我?

当我需要使用@ MapKeyJoinColumn/@ MapKeyJoinColumns和@MapKeyEnumerated/@MapKeyTemporal时,请告诉我

谢谢!

Vla*_*cea 36

当您使用a时,Map您始终需要关联至少两个实体.假设我们有一个与Owner实体相关的Car实体(Car有一个FK Owner).

所以,Owner就有了MapCar(s):

Map<X, Car>
Run Code Online (Sandbox Code Playgroud)
  1. @MapKey会给你@MapKey用来集团的物业Car'sCar.例如,如果我们有Owner(车辆识别号)属性vin,我们可以使用它作为Car关键:

    @Entity
    public class Owner {
        @Id
        private long id;
    
        @OneToMany(mappedBy="owner")
        @MapKey(name = "vin")
        private Map<String, Car> carMap;
    }
    
    @Entity
    public class Car {
        @Id
        private long id;
    
        @ManyToOne
        private Owner owner;
    
        private String vin;
    
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. carMap将使用Enum @MapKeyEnumerated,例如@MapKeyEnumerated:

    @Entity
    public class Owner {
        @Id
        private long id;
    
        @OneToMany(mappedBy="owner")
        @MapKeyEnumerated(EnumType.STRING)
        private Map<WheelDrive, Car> carMap;
    }
    
    @Entity
    public class Car {
        @Id
        private long id;
    
        @ManyToOne
        private Owner owner;
    
        @Column(name = "wheelDrive")
        @Enumerated(EnumType.STRING)
        private WheelDrive wheelDrive;
    
    }
    
    public enum WheelDrive {
        2WD, 
        4WD;             
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这将按照WheelDrive类型对汽车进行分组.

  3. Car将使用WheelDrive/ @MapKeyTemporal字段进行分组,例如@MapKeyTemporal

    @Entity
    public class Owner {
        @Id
        private long id;
    
        @OneToMany(mappedBy="owner")
        @MapKeyTemporal(TemporalType.TIMESTAMP)
        private Map<Date, Car> carMap;
    }
    
    @Entity
    public class Car {
        @Id
        private long id;
    
        @ManyToOne
        private Owner owner;
    
        @Temporal(TemporalType.TIMESTAMP)
        @Column(name="created_on")
        private Calendar createdOn;         
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. Date需要第三个实体,就像Calendar让你从这样一个联合体createdOn,以@MapKeyJoinColumn与汽车也已经关联到@MapKeyJoinColumn,让您可以将所有Manufacturer OwnerCar:

    @Entity
    public class Owner {
        @Id
        private long id;
    
        @OneToMany(mappedBy="owner")
        @MapKeyJoinColumn(name="manufacturer_id")
        private Map<Manufacturer, Car> carMap;
    }
    
    @Entity
    public class Car {
        @Id
        private long id;
    
        @ManyToOne
        private Owner owner;
    
        @ManyToOne
        @JoinColumn(name = "manufacturer_id")
        private Manufacturer manufacturer;          
    }
    
    @Entity
    public class Manufacturer {
        @Id
        private long id;
    
        private String name;
    }
    
    Run Code Online (Sandbox Code Playgroud)