spring-data-jpa 手动将@Entity转换为投影界面

eanckbw9  于 2022-11-10  发布在  Spring
关注(0)|答案(3)|浏览(174)

所以我一直在使用Spring Data 仓库。但是我遇到了一个用例,我不能使用Spring仓库来检索我需要返回给客户端的实体。所以我有一个类ResourceEntity,它是一个Spring Data 实体。我想把这个实体作为一个ResourceProjection接口返回。

@Getter
@Setter
@NoArgsConstructor
@Entity
public class ResourceEntity{
    private Long id;
    private String name;
    private String anotherFieldThatIsNotInTheProjection;
}

public interface ResourceProjection {
    Long getId();
    String getName();
}

通常对于Spring存储库,我会定义如下内容:

public interface ResourceRepository extends PagingAndSortingRepository<ResourceEntity, Long> {
    Optional<ResourceProjection> getById(Long id);
}

在这种情况下,我不能使用SpringData生成的“自动代理”来自动实现对实体数据的投影。
所以我的问题是:是否有方法“手动”将实体转换为投影?
我想到的另一个解决方案是返回实体,并使用@JsonIgnore之类的Jackson注解来防止返回我的一些数据,但这与我编写代码的方式并不相符。
否则,我总是可以创建一个DTO类,它将填充来自实体的数据。但是,由于我已经为其他目的创建了我的投影,我希望避免创建第二个“DTO”。

iyr7buue

iyr7buue1#

您可以通过以下方式以编程方式进行投影:

import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;

 //... 
  resourceEntity = //find resource
  ProjectionFactory pf = new SpelAwareProxyProjectionFactory();
  ResourceProjection rp = pf.createProjection(ResourceProjection.class, resourceEntity)
kupeojn6

kupeojn62#

这是Blaze-Persistence实体视图的完美用例。
我创建了这个库,以允许在JPA模型和自定义接口定义的模型之间进行轻松的Map,就像SpringDataProjections一样。(getters)通过JPQL表达式Map到实体模型.由于属性名被用作默认Map,因为80%的用例都需要作为实体模型子集的DTO。
模型的Map可能看起来像下面这样简单

@EntityView(ResourceEntity.class)
interface ResourceProjection {
  @IdMapping
  Long getId();
  String getName();
}

查询是将实体视图应用于查询的问题,最简单的是按id查询。
ResourceProjection dto = entityViewManager.find(entityManager, ResourceProjection.class, id);
但是Spring Data 集成允许您像Spring Data 投影一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

k0pti3hp

k0pti3hp3#

使用原生SQL查询实作界面投影

1.我们的ResourceEntity.java

@Getter
@Setter
@NoArgsConstructor
@Entity
public class ResourceEntity{
    private Long id;
    private String name;
}

2.创建投影接口名称ProjectedResource.java,该接口Map通过存储库层方法中的SQL查询收集的数据

public interface ProjectedResource {
  Long getId();
  String getName();
  String getAnotherProperty();
}

3.创建Repository层的方法:getProjectedResources()

  • 我们考虑的数据库表名是resource
  • 这里我们只取idname,但是使用接口Map,我们可以根据需要更改属性名称。
@Query(name="select id, name, anotherProperty from resource", nativeQuery=true)
List<ProjectedResource> getProjectedResources();

希望问题能得到解决!

相关问题