GVKun编程网logo

对JP-QL(JPA 2.0)中的“ ElementCollection”映射字段执行“ MEMBER OF”查询(对象字段映射)

6

在本文中,我们将给您介绍关于对JP-QL的详细内容,并且为您解答JPA2.0中的“ElementCollection”映射字段执行“MEMBEROF”查询的相关问题,此外,我们还将为您提供关于@Ele

在本文中,我们将给您介绍关于对JP-QL的详细内容,并且为您解答JPA 2.0中的“ ElementCollection”映射字段执行“ MEMBER OF”查询的相关问题,此外,我们还将为您提供关于@ElementCollection @Embeddable、@ElementCollection 组件集合映射(一)、@ElementCollection 组件集合映射(三)、@ElementCollection 组件集合映射(二)的知识。

本文目录一览:

对JP-QL(JPA 2.0)中的“ ElementCollection”映射字段执行“ MEMBER OF”查询(对象字段映射)

对JP-QL(JPA 2.0)中的“ ElementCollection”映射字段执行“ MEMBER OF”查询(对象字段映射)

是否可以对关联数组运行“ MEMBER
OF”查询?如果是这样,语法是什么样的?显而易见的解决方法是本机查询,但是对于所有联接等,都变得很混乱。我想测试地图的键集,值集合或条目集中是否存在对象。也许像下面这样:

SELECT p FROM Person p WHERE ''home'' MEMBER OF p.phoneNumbers.keySetSELECT p FROM Person p WHERE ''867-5309'' MEMBER OF p.phoneNumbers.valuesSELECT p FROM Person p WHERE {''home'' -> ''867-5309''} MEMBER OF p.phoneNumbers

与提供者无关的代码可能要求太多。Eclipselink支持吗?

答案1

小编典典

JPQL有一个名为的函数index(),该函数对于在@OrderColumn列表中获取索引很有用。正如您自己说的那样,映射也称为关联数组,并且映射键对应于数组索引。因此,没有什么可以阻止index()返回映射条目的键。

此查询在休眠状态下可完美运行:

SELECT p FROM Person p, in (p.phoneNumbers) number WHERE number = ''867-5309'' AND index(number) = ''home''

@ElementCollection @Embeddable

@ElementCollection @Embeddable

直接上代码:

@Entity
@Data
public class TestA {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ElementCollection
    private List<TestB> testBList;
    @Data
    @Embeddable
    public static class TestB{
        private String address;
    }

    @ElementCollection
    private List<String> info;

    @Embedded
    private TestC testC;
    @Data
    @Embeddable
    public static class TestC{
        private String able;
    }
}

对应生成的表结构是:

CREATE TABLE IF NOT EXISTS testa (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  able VARCHAR(128)
);

CREATE TABLE IF NOT EXISTS testa_testblist (
  testa_id BIGINT,
  address VARCHAR(128)
);

CREATE TABLE IF NOT EXISTS testa_info (
  testa_id BIGINT,
  info VARCHAR(128)
);

看了一下源码:

@ElementCollection Defines a collection of instances of a basic type or embeddable class . Must be specified if the collection is to be mapped by means of a collection table.

@Embeddable Defines a class whose instances are stored as an intrinsic part of an owning entity and share the identity of the entity. Each of the persistent properties or fields of the embedded object is mapped to the database table for the entity.

@ Embedded Specifies a persistent field or property of an entity whose value is an instance of an embeddable class. The embeddable class must be annotated as {@Embeddable}.

@ElementCollection 组件集合映射(一)

@ElementCollection 组件集合映射(一)

问题描述:

一个人有家庭住址,也有单位地址;但是“地址”并不能失去人的存在而存在,所以是一个失去独立性的Pojo;

所以地址不能映射为一个实体,这时就需要映射为组件,及人的信息里边包含地址。是整体与部分的关系。

但由于这个地址可能有多个。比如公司地址、出生地址、家庭地址等。所以要使用Map,这样可以存储多个不同的

地址。key表明是什么地址;而value就是对应的这个地址。如何映射呢?

[java] view plaincopy

  1. package com.ccay;  

  2. import java.util.Map;  

  3. import javax.persistence.ElementCollection;  

  4. import javax.persistence.Embedded;  

  5. import javax.persistence.Entity;  

  6. import javax.persistence.GeneratedValue;  

  7. import javax.persistence.Id;  

  8. @Entity   

  9. public class Person {  

  10.     private int id;  

  11.     private String name;  

  12.     private Map<String,Address> address;  

  13.       

  14.     @ElementCollection  

  15.     public Map<String, Address> getAddress() {  

  16.         return address;  

  17.     }  

  18.     public void setAddress(Map<String, Address> address) {  

  19.         this.address = address;  

  20.     }  

  21.     @Id  

  22.     @GeneratedValue  

  23.     public int getId() {  

  24.         return id;  

  25.     }  

  26.     public void setId(int id) {  

  27.         this.id = id;  

  28.     }  

  29.     public String getName() {  

  30.         return name;  

  31.     }  

  32.     public void setName(String name) {  

  33.         this.name = name;  

  34.     }  

  35. }  

 

[java] view plaincopy

  1. package com.ccay;  

  2. import javax.persistence.Embeddable;  

  3.   

  4. @Embeddable  

  5. public class Address {  

  6.     /** 

  7.      * 省 

  8.      */  

  9.     private String a;  

  10.     /** 

  11.      * 市 

  12.      */  

  13.     private String b;  

  14.     /** 

  15.      * 县 

  16.      */  

  17.     private String c;  

  18.     public String getA() {  

  19.         return a;  

  20.     }  

  21.     public void setA(String a) {  

  22.         this.a = a;  

  23.     }  

  24.     public String getB() {  

  25.         return b;  

  26.     }  

  27.     public void setB(String b) {  

  28.         this.b = b;  

  29.     }  

  30.     public String getC() {  

  31.         return c;  

  32.     }  

  33.     public void setC(String c) {  

  34.         this.c = c;  

  35.     }  

  36. }  

 

[java] view plaincopy

  1. package com.ccay;  

  2. import java.util.HashMap;  

  3. import java.util.Map;  

  4. import org.hibernate.SessionFactory;  

  5. import org.hibernate.cfg.AnnotationConfiguration;  

  6. import org.hibernate.cfg.Configuration;  

  7. import org.hibernate.classic.Session;  

  8. import org.junit.Test;  

  9.   

  10. public class MyTest {  

  11.       

  12.     @Test  

  13.     public void test(){  

  14.         Configuration cfg = new AnnotationConfiguration().configure().configure();    

  15.         SessionFactory sessionFactory = cfg.buildSessionFactory();  

  16.         Person p = new Person();  

  17.         p.setName("lala");  

  18.         Address a= new Address();  

  19.         a.setA("陕西");  

  20.         a.setB("宝鸡");  

  21.         a.setC("渭滨");  

  22.           

  23.         Address b= new Address();  

  24.         b.setA("四川");  

  25.         b.setB("成都");  

  26.         b.setC("成都");  

  27.           

  28.         Map<String,Address> adds = new HashMap<String,Address>();  

  29.           

  30.         adds.put("family", a);  

  31.         adds.put("company", b);  

  32.       

  33.         p.setAddress(adds);  

  34.         Session session = sessionFactory.openSession();  

  35.         session.beginTransaction();  

  36.             session.save(p);  

  37.             session.getTransaction().commit();  

  38.         session.close();  

  39.         sessionFactory.close();  

  40.     }  

  41.       

  42. }  

 

hibernate生成的建表语句:

 

CREATE TABLE `person` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(255) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

 

 

 

CREATE TABLE `person_address` (

  `Person_id` int(11) NOT NULL,

  `a` varchar(255) DEFAULT NULL,

  `b` varchar(255) DEFAULT NULL,

  `c` varchar(255) DEFAULT NULL,

  `address_KEY` varchar(255) NOT NULL DEFAULT '''',

  PRIMARY KEY (`Person_id`,`address_KEY`),

  KEY `FKE83F852A356FEAE3` (`Person_id`),

  CONSTRAINT `FKE83F852A356FEAE3` FOREIGN KEY (`Person_id`) REFERENCES `person` (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

 

反向工程图例:

@ElementCollection 组件集合映射(三)

@ElementCollection 组件集合映射(三)

ObjectRelational-ElementCollection.jpg

JPA 2.0 defines an ElementCollection mapping. It is meant to handle several non-standard relationship mappings. An ElementCollection can be used to define a one-to-many relationship to an Embeddable object, or a Basic value (such as a collection of Strings). An ElementCollection can also be used in combination with a Map to define relationships where the key can be any type of object, and the value is an Embeddable object or a Basic value.

In JPA an ElementCollection relationship is defined through the @ElementCollection annotation or the <element-collection> element.

The ElementCollection values are always stored in a separate table. The table is defined through the @CollectionTable annotation or the <collection-table>element. The CollectionTable defines the table''s name and @JoinColumn or @JoinColumns if a composite primary key.

Embedded Collections[edit]

An ElementCollection mapping can be used to define a collection of Embeddable objects. This is not a typical usage of Embeddable objects as the objects are not embedded in the source object''s table, but stored in a separate collection table. This is similar to a OneToMany, except the target object is anEmbeddable instead of an Entity. This allows collections of simple objects to be easily defined, without requiring the simple objects to define an Id orManyToOne inverse mapping. ElementCollection can also override the mappings, or table for their collection, so you can have multiple entities reference the same Embeddable class, but have each store their dependent objects in a separate table.

The limitations of using an ElementCollection instead of a OneToMany is that the target objects cannot be queried, persisted, merged independently of their parent object. They are strictly privately-owned (dependent) objects, the same as an Embedded mapping. There is no cascade option on an ElementCollection, the target objects are always persisted, merged, removed with their parent. ElementCollection still can use a fetch type and defaults to LAZY the same as other collection mappings.

Example of an ElementCollection relationship database[edit]

Example of an ElementCollection relationship annotations[edit]

@Entitypublic class Employee {
  @Id
  @Column(name="EMP_ID")
  private long id;
  ...
  @ElementCollection
  @CollectionTable(
        name="PHONE",
        joinColumns=@JoinColumn(name="OWNER_ID")
  )
  private List<Phone> phones;
  ...}
@Embeddablepublic class Phone {
  private String type;
  private String areaCode;
  @Column(name="P_NUMBER")
  private String number;
  ...}

Example of an ElementCollection relationship XML[edit]

<entity name="Employee"  access="FIELD">
    <attributes>
        <id name="id">
            <column name="EMP_ID"/>
        </id>
        <element-collection name="phones">
            <collection-table name="PHONE">
                <join-column name="OWNER_ID"/>
            </collection-table>
        </element-collection>
    </attributes></entity><embeddable name="Phone"  access="FIELD">
    <attributes>
        <basic name="number">
            <column name="P_NUMBER"/>
        </basic>
    </attributes></embeddable>

Basic Collections[edit]

An ElementCollection mapping can be used to define a collection of Basic objects. The Basic values are stored in a separate collection table. This is similar to a OneToMany, except the target is a Basic value instead of an Entity. This allows collections of simple values to be easily defined, without requiring defining a class for the value.

There is no cascade option on an ElementCollection, the target objects are always persisted, merged, removed with their parent. ElementCollection still can use a fetch type and defaults to LAZY the same as other collection mappings.

Example of an ElementCollection relationship to a basic value database[edit]

Example of a ElementCollection relationship to a basic value annotations[edit]

@Entitypublic class Employee {
  @Id
  @Column(name="EMP_ID")
  private long id;
  ...
  @ElementCollection
  @CollectionTable(
        name="PHONE",
        joinColumns=@JoinColumn(name="OWNER_ID")
  )
  @Column(name="PHONE_NUMBER")
  private List<String> phones;
  ...}

Example of a ElementCollection relationship to a basic value XML[edit]

<entity name="Employee"  access="FIELD">
    <attributes>
        <id name="id">
            <column name="EMP_ID"/>
        </id>
        <element-collection nam
            <column name="PHONE_NUMBER"/>
            <collection-table name="PHONE">
                <join-column name="OWNER_ID"/>
            </collection-table>
        </element-collection>
    </attributes></entity>

See Also[edit]

  • Relationships

    • Lazy Fetching

    • Target Entity

    • Collections

    • Maps

    • Join Fetching

    • Batch Reading

    • Common Problems

  • OneToMany

  • ManyToMany

  • Embeddables

Common Problems[edit]

Primary keys in CollectionTable[edit]
  • The JPA 2.0 specification does not provide a way to define the Id in the Embeddable. However, to delete or update a element of the ElementCollectionmapping, some unique key is normally required. Otherwise, on every update the JPA provider would need to delete everything from the CollectionTable for theEntity, and then insert the values back. So, the JPA provider will most likely assume that the combination of all of the fields in the Embeddable are unique, in combination with the foreign key (JoinColumn(s)). This however could be inefficient, or just not feasible if the Embeddable is big, or complex.

  • Some JPA providers may allow the Id to be specified in the Embeddable, to resolve this issue. Note in this case the Id only needs to be unique for the collection, not the table, as the foreign key is included. Some may also allow the unique option on the CollectionTable to be used for this. Otherwise, if your Embeddable is complex, you may consider making it an Entity and use a OneToMany instead.


@ElementCollection 组件集合映射(二)

@ElementCollection 组件集合映射(二)

级联关系:

package com.bbg.fms.model;


import java.util.Date;

import java.util.List;


import javax.persistence.CollectionTable;

import javax.persistence.Column;

import javax.persistence.ElementCollection;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.OrderBy;

import javax.persistence.Table;

import javax.persistence.Transient;


import org.hibernate.annotations.GenericGenerator;


import com.bbg.framework.AbstractEntity;


/**

* @author  Rangey

*/

@Entity

@Table(name="BBG_FMS_FILE_INFO")

public class FileInfoPo extends AbstractEntity<String> {

@Transient

private static final long serialVersionUID = -7497235305117364771L;


@Id

@Column(name = "ID", length=36)

@GeneratedValue(generator = "system-uuid")

@GenericGenerator(name = "system-uuid", strategy = "uuid")

private String id;

@Column(length=50)

private String fileName;

@Column

private Long fileSize;

@Column(length=50)

private String moduleName;

@Column(length=10)

private String version;

@Column

private Date createTime;

@Column(length=10)

private String fileType;

@Column

private String remark;

@ElementCollection

@CollectionTable(name = "BBG_FMS_FILE_SLICE", joinColumns = @JoinColumn(name = "FILE_ID"))

@OrderBy("pos")

private List<FileSlice> slices;

@ElementCollection

@CollectionTable(name = "BBG_FMS_FILE_PROP", joinColumns = @JoinColumn(name = "FILE_ID"))

private List<FileProp> props;

public String getId() {

return id;

}


public void setId(String id) {

this.id = id;

}


public String getFileName() {

return fileName;

}


public void setFileName(String fileName) {

this.fileName = fileName;

}


public Long getFileSize() {

return fileSize;

}


public void setFileSize(Long fileSize) {

this.fileSize = fileSize;

}


public String getModuleName() {

return moduleName;

}


public void setModuleName(String moduleName) {

this.moduleName = moduleName;

}


public String getVersion() {

return version;

}


public void setVersion(String version) {

this.version = version;

}


public Date getCreateTime() {

return createTime;

}


public void setCreateTime(Date createTime) {

this.createTime = createTime;

}


public String getFileType() {

return fileType;

}


public void setFileType(String fileType) {

this.fileType = fileType;

}


public String getRemark() {

return remark;

}


public void setRemark(String remark) {

this.remark = remark;

}


public List<FileSlice> getSlices() {

return slices;

}


public void setSlices(List<FileSlice> slices) {

this.slices = slices;

}


public List<FileProp> getProps() {

return props;

}


public void setProps(List<FileProp> props) {

this.props = props;

}


@Override

public String getObjectId() {

return id;

}


}


package com.bbg.fms.model;


import javax.persistence.Column;

import javax.persistence.Embeddable;


/**

 *

 * @author Rangey

 * @version 1.0

 * 

 */

@Embeddable

public class FileSlice {

@Column(length=21800)

private String data;

@Column

private int seqNo;


public String getData() {

return data;

}


public void setData(String data) {

this.data = data;

}


public int getSeqNo() {

return seqNo;

}


public void setSeqNo(int seqNo) {

this.seqNo = seqNo;

}

}



package com.bbg.fms.model;


import javax.persistence.Column;

import javax.persistence.Embeddable;


/**

 *

 * @author Rangey

 * @version 1.0

 * 

 */

@Embeddable

public class FileProp {

@Column

private String keyword;


public String getKeyword() {

return keyword;

}


public void setKeyword(String keyword) {

this.keyword = keyword;

}

}


今天的关于对JP-QLJPA 2.0中的“ ElementCollection”映射字段执行“ MEMBER OF”查询的分享已经结束,谢谢您的关注,如果想了解更多关于@ElementCollection @Embeddable、@ElementCollection 组件集合映射(一)、@ElementCollection 组件集合映射(三)、@ElementCollection 组件集合映射(二)的相关知识,请在本站进行查询。

本文标签: