我正在使用一个外部服务,该服务POST到我的应用程序中的端点,我有一个@RequestBody CalloutRequest calloutRequest
,我将请求正文映射到类CalloutRequest
。
作为CalloutRequest的一部分,一个名为userAttributes
的字段在我的班级中看起来像这样:
@Lob
private HashMap<String, List<String>> userAttributes;
我有一个带注释的机智@Lob
,因为我没有可以映射它的课程,因为它相当复杂。因此这个HashMap。以JSON格式表示userAttributes的示例:
"userAttributes": {
"lastName": [
"Guy"
],
"ExternalId": [
"d9a59407-2bca-46aa-8641-3350fd95bcd1"
],
"distinguishedName": [
"CN=t2-contractor9,DC=company,DC=com"
],
"employeeID": [],
"userName": [
"t2-contractor9@company.com"
],
"groupNames": [
"ALL USERS",
"T2-Contractor@company.com"
],
"firstName": [
"T2-Contractor"
],
"UserStore": [],
"phone": [],
"domain": [
"company.com"
],
"disabled": [
"false"
],
"email": [
"t2-contractor9@company.com"
]
}
我的挑战是我想建立一个特定用户名的查询 - userAttributes.userName
- 但鉴于这个存储为BLOB的事实我无法弄清楚如何 - 或者如果可能 - 写这样的询问
现在我只是简单地使用Spring Data JPA和它的存储库实现,但是我想知道这是否可以通过自定义@Query
或者使用querydsl来实现?
我是否正确理解如果我能想出一种方法将上面的HashMap映射到一个实际的类我可以用来序列化/反序列化并在CalloutRequest和这个新类之间有一个映射我可以构建一个JPQL查询将使用连接来实现我所追求的目标?
答案 0 :(得分:0)
如何在此处利用AttributeConverter
实施:
public class YourEntity {
// ...
@ElementCollection
@Convert(name = "value", converter = StringListToStringConverter.class)
private Map<String, List<String>> userAttributes;
}
StringListToStringConverter
的简单实现可能是:
public class StringListToStringConverter
implements AttributeConverter<List<String>, String> {
private static final String DELIMITER = "|";
@Override
public String converToDatabaseColumn(List<String> attributes) {
if ( attributes == null || attributes.isEmpty() ) {
return null;
}
StringBuilder sb = new StringBuilder();
for ( Iterator<String> i = attribtues.iterator(); i.hasNext(); ) {
sb.append( i.next() );
if ( i.hasNext() ) {
sb.append( DELIMITER );
}
}
return sb.toString();
}
@Override
public List<String> convertToEntityAttribute(String data) {
if ( data == null ) {
return new ArrayList<String>();
}
List<String> values = Arrays.asList( StringHelper.split( DELIMITER, data ) );
return new ArrayList<String>( values );
}
}
您显然必须处理输入流包含DELIMITER
排序值的情况,但根据您的使用情况,它可能会有效。
我相信您可以使用HQL编写您的查询,如:
SELECT e FROM YourEntity e JOIN e.userAttributes a
WHERE VALUE(a) = :mapValue
答案 1 :(得分:0)
如果你使用Hibernate作为JPA实现而PostgreSQL作为DB看看hibernate-native-json项目:
示例强>
您可以序列化类或地图(在任何情况下都需要更动态的字段)。
@Entity
public class MyClass {
@Type(type = "com.marvinformatics.hibernate.json.JsonListUserType")
@Target(Label.class)
private List<Label> labels = new ArrayList<Label>();
@Type(type = "com.marvinformatics.hibernate.json.JsonUserType")
private Map<String, String> extra;
}
这允许像这样的HQL查询:
select
json_text(i.label, 'value')
from
Item i
where
json_text(i.label, 'lang') = :lang
祝你好运!