Jam*_*ron 5 spring spring-data spring-data-jpa spring-boot
使用spring-data-jpa并从表中获取数据,其中有大约十二列用于查询以查找特定行,然后是一个clob类型的有效负载列,其中包含编组到java对象中的实际数据被退回.
实体对象非常粗略
@Entity
@Table(name = "Person")
public class Person {
@Column(name="PERSON_ID", length=45) @Id private String personId;
@Column(name="NAME", length=45) private String name;
@Column(name="ADDRESS", length=45) private String address;
@Column(name="PAYLOAD") @Lob private String payload;
//Bunch of other stuff
}
Run Code Online (Sandbox Code Playgroud)
(这种方法是否合理是一个不同讨论的主题)
clob列会导致性能受到大量查询的影响......
为了改善一些事情,我创建了一个单独的实体对象...没有负载......
@Entity
@Table(name = "Person")
public class NotQuiteAWholePerson {
@Column(name="PERSON_ID", length=45) @Id private String personId;
@Column(name="NAME", length=45) private String name;
@Column(name="ADDRESS", length=45) private String address;
//Bunch of other stuff
}
Run Code Online (Sandbox Code Playgroud)
这让我得到一个NotQuiteAPerson页面......然后我通过personIds查询完整人物对象的页面.
希望是在原始查询中不使用有效负载,这可能会在支持表的一小部分上过滤数据,当我正在检索要查看的对象的当前页面时,我只关心自己的有效负载...一个小得多的块.
所以我想要将原始返回的NotQuiteAWholePerson页面的内容映射到我的人员列表,同时保持所有的分页信息不变,但是map方法只需要一个将迭代NotQuiteAWholePerson对象的Converter ......这不太适合我想做的事情.
有没有明智的方法来实现这一目标?
关于为什么现有的map()不够用@itsallas的补充说明..
PageImpl :: map有
@Override
public <S> Page<S> map(Converter<? super T, ? extends S> converter) {
return new PageImpl<S>(getConvertedContent(converter), pageable, total);
}
Run Code Online (Sandbox Code Playgroud)
Chunk :: getConvertedContent有
protected <S> List<S> getConvertedContent(Converter<? super T, ? extends S> converter) {
Assert.notNull(converter, "Converter must not be null!");
List<S> result = new ArrayList<S>(content.size());
for (T element : this) {
result.add(converter.convert(element));
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
因此,原始的内容列表将通过...和应用提供的转换方法进行迭代,以构建要插入到现有Pageable中的新内容列表.
但是我不能单独将NotQuiteAWholePerson转换为Person,因为我不能简单地构造有效载荷......我可以,如果我在转换中通过Id向每个Person调用数据库...但是单独调用是不理想的从表现的角度来看......
获得我的NotQuiteAWholePerson页面之后,我正在查询整个人员列表...通过Id ...在一个电话中...现在我正在寻找一种方法来替换整个内容列表...而不是间断地,如同现有的map()确实如此,但只是简单的替换.
这个特殊的用例也可以帮助将有效负载(json)更适当地保存在像Mongo这样的NoSql数据存储中...而不是sql数据存储clob ......
希望能更好地澄清一下.
小智 3
您可以使用 Spring Data JPA 功能完全避免该问题。
最明智的方法是使用 Spring Data JPA投影,它有很好的广泛文档。
例如,您首先需要确保属性的延迟获取,这可以通过属性本身的注释来实现。
IE :
@Basic(fetch = FetchType.LAZY) @Column(name="PAYLOAD") @Lob private String payload;
Run Code Online (Sandbox Code Playgroud)
或者通过获取/加载图表,这在存储库级别得到了很好的支持。
您需要以一种或另一种方式定义它,因为从文档中逐字获取:
查询执行引擎在运行时为返回的每个元素创建该接口的代理实例,并将对公开方法的调用转发给目标对象。
然后您可以像这样定义投影:
interface NotQuiteAWholePerson {
String getPersonId();
String getName();
String getAddress();
//Bunch of other stuff
}
Run Code Online (Sandbox Code Playgroud)
并将查询方法添加到您的存储库:
interface PersonRepository extends Repository<Person, String> {
Page<NotQuiteAWholePerson> findAll(Pageable pageable);
// or its dynamic equivalent
<T> Page<T> findAll(Pageable pageable, Class<T>);
}
Run Code Online (Sandbox Code Playgroud)
给定相同的可分页,一页投影将引用同一会话中的相同实体。
如果您出于某种原因无法使用投影(即,如果您使用 JPA < 2.1 或投影之前的 Spring Data JPA 版本),您可以使用所需的列和关系定义显式 JPQL 查询,或者保留 2-entity设置。然后,您可以手动或(最好)使用您选择的对象映射框架将Persons 和NotQuiteAWholePersons 映射到类。PersonDTO
注意。:有多种方法可以使用和设置惰性/渴望关系。这涵盖了更多细节。
| 归档时间: |
|
| 查看次数: |
226 次 |
| 最近记录: |