Spring-boot 最简单的投影表达方式

Spring-boot simplest way to express projections

在这种情况下有使用@Projection的简单方法吗?

我的 Report 实体有很大的字段(例如 content 字段有完整的 HTML 文本),我没有需要在终点交付。

@Repository
public interface IReportRepository extends BaseRepository<Report, Long> {

    List<Report> findAll();  // working fine... BUT with fields that not need

    @Query(nativeQuery = true, value= "SELECT id, acronym FROM report")
    List<Object[]> findSomeFields1();  // BAD JSON, no field name!

    @Query(nativeQuery = true, value= "SELECT id, acronym FROM report")
    List<Map> findSomeFields2();  // ERROR! Failed to convert
         // there are something as JSON Row Mapper?

}

(他们 ReportController 在端点将其作为 JSON 交付,只有它)

代替@Query我需要用@Projection(...)...怎么用(最简单 方式!)?

作为 Spring 项目存储库中的示例,您可以查看此项目 https://github.com/spring-projects/spring-data-examples/tree/master/rest/projections

无论如何,如果您想更好地控制您获得的数据,您可以使用 QueryDSL and Springlets 库来 return 来自您的 Spring 数据存储库的投影。

这里有一个关于如何一起使用 QueryDSL and Springlets 的例子:

创建一个新的 class,其中只包含您要获取的具体字段。例如,对于 Owner 实体,您可以创建仅包含 idfirstNamelastName 字段的 OwnerInfo 投影。

public class OwnerInfo {

  private Long id;

  @Size(min = 3, max = 30)
  private String firstName;

  @NotNull
  @Size(min = 3, max = 30)
  private String lastName;

}

按照 Owner 示例,创建一个名为 OwnerRepositoryCustom 的新存储库接口,并定义将 return 投影的查找器。

public interface OwnerRepositoryCustom {

  public Page<OwnerInfo> findByFirstNameLike(String firstName, Pageable pageable);

}

创建我们的 OwnerRepositoryCustom 的实现。 class 应该从 Springlets 项目扩展 QueryDslRepositorySupportExt

public class OwnerRepositoryImpl extends QueryDslRepositorySupportExt<Owner> implements OwnerRepositoryCustom {

    OwnerRepositoryImpl() {
        super(Owner.class);
    }

    public Page<OwnerInfo> findByFirstNameLike(String firstName, Pageable pageable) {

        QOwner owner = QOwner.owner;

        JPQLQuery<Owner> query = from(owner);

        if (StringUtils.isNotEmpty(firstName)) {
           BooleanBuilder searchCondition = new BooleanBuilder();                         

           searchCondition.and(owner.firstName.eq(firstName));

           if (searchCondition.hasValue()) {
            query.where(searchCondition);
           }
        }

        Path<?>[] paths = new Path<?>[] {owner.id,owner.firstName,owner.lastName};        

        AttributeMappingBuilder mapping = buildMapper()
            .map(ID, owner.id)
            .map(FIRST_NAME, owner.firstName)
            .map(LAST_NAME, owner.lastName);

        return loadPage(query, pageable, Projections.constructor(OwnerInfo.class, owner.id, owner.firstName, owner.lastName));
    }

}

现在,从 JpaRepository<Owner, Long> andOwnerRepositoryCustom` 接口扩展 OwnerRepository 接口。

public interface OwnerRepository extends OwnerRepositoryCustom, JpaRepository<Owner, Long> {

}

通过这些简单的步骤,您将能够 return 在您的存储库方法中进行投影。

希望对您有所帮助,