我正在构建一个通用属性系统,其中不同的实体可能具有分配的属性(表示为“PropertyEntity”)。这样的属性实体具有键,值并且知道它所附着的实体的id。考虑一个'UserEntity',其中的属性映射如下所示:
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
@JoinTable(name = "UserProperties",
joinColumns = @JoinColumn(name = "parentId"),
inverseJoinColumns = @JoinColumn(name = "id"))
private Map<String, PropertyEntity> properties;
可能还有更多具有属性的实体,每个实体都有自己的连接表。
我现在想知道查询具有某些属性的用户(或具有属性的不同实体)的最有效方法是什么。比如'给我所有用户,其中属性A具有值B,属性X具有值Y'。
请记住,查询代码必须是通用的,因为它不知道是否应该检索用户或具有属性连接表的其他实体。要搜索的类型可以作为Class对象给出。
我目前正在运行朴素的方法,其中PropertyEntity也知道它所属的类型的名称。然后,我按其键和父类型查询属性,并通过手动查找相应的父实体来对结果进行后处理。
SELECT p FROM PropertyEntity p WHERE p.propertyKey in(?1) AND p.parentType = ?2
其中参数1是一组键,参数2是父类型的名称,如'com.domain.UserEntity'。这种方法显然很糟糕,因为它完全颠覆了每个实体使用额外连接表的需要,并且需要通过它们的值对结果进行后期过滤。