在本文中,我们将给您介绍关于对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”查询(对象字段映射)
- @ElementCollection @Embeddable
- @ElementCollection 组件集合映射(一)
- @ElementCollection 组件集合映射(三)
- @ElementCollection 组件集合映射(二)
对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
直接上代码:
@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 组件集合映射(一)
问题描述:
一个人有家庭住址,也有单位地址;但是“地址”并不能失去人的存在而存在,所以是一个失去独立性的Pojo;
所以地址不能映射为一个实体,这时就需要映射为组件,及人的信息里边包含地址。是整体与部分的关系。
但由于这个地址可能有多个。比如公司地址、出生地址、家庭地址等。所以要使用Map,这样可以存储多个不同的
地址。key表明是什么地址;而value就是对应的这个地址。如何映射呢?
[java] view plaincopy
package com.ccay;
import java.util.Map;
import javax.persistence.ElementCollection;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
private int id;
private String name;
private Map<String,Address> address;
@ElementCollection
public Map<String, Address> getAddress() {
return address;
}
public void setAddress(Map<String, Address> address) {
this.address = address;
}
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
[java] view plaincopy
package com.ccay;
import javax.persistence.Embeddable;
@Embeddable
public class Address {
/**
* 省
*/
private String a;
/**
* 市
*/
private String b;
/**
* 县
*/
private String c;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
}
[java] view plaincopy
package com.ccay;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;
public class MyTest {
@Test
public void test(){
Configuration cfg = new AnnotationConfiguration().configure().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Person p = new Person();
p.setName("lala");
Address a= new Address();
a.setA("陕西");
a.setB("宝鸡");
a.setC("渭滨");
Address b= new Address();
b.setA("四川");
b.setB("成都");
b.setC("成都");
Map<String,Address> adds = new HashMap<String,Address>();
adds.put("family", a);
adds.put("company", b);
p.setAddress(adds);
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(p);
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
}
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 组件集合映射(三)
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 String
s). 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 theEmbeddable
. However, to delete or update a element of theElementCollection
mapping, some unique key is normally required. Otherwise, on every update the JPA provider would need to delete everything from theCollectionTable
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 theEmbeddable
are unique, in combination with the foreign key (JoinColumn
(s)). This however could be inefficient, or just not feasible if theEmbeddable
is big, or complex.
Some JPA providers may allow the
Id
to be specified in theEmbeddable
, to resolve this issue. Note in this case theId
only needs to be unique for the collection, not the table, as the foreign key is included. Some may also allow theunique
option on theCollectionTable
to be used for this. Otherwise, if yourEmbeddable
is complex, you may consider making it anEntity
and use aOneToMany
instead.
@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-QL和JPA 2.0中的“ ElementCollection”映射字段执行“ MEMBER OF”查询的分享已经结束,谢谢您的关注,如果想了解更多关于@ElementCollection @Embeddable、@ElementCollection 组件集合映射(一)、@ElementCollection 组件集合映射(三)、@ElementCollection 组件集合映射(二)的相关知识,请在本站进行查询。
本文标签: