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

时间:2017-01-31 20:57:38

标签: spring-boot projection

在此上下文中有一种简单的方法可以使用@Projection吗?

我的报告实体包含大字段(例如,带有完整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(...) ...如何使用它(最简单方式!)?

1 个答案:

答案 0 :(得分:5)

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

无论如何,如果您想要对获得的数据进行更多控制,可以使用QueryDSLSpringlets库从Spring数据库中返回投影。

以下是有关如何一起使用QueryDSLSpringlets的示例:

创建一个只包含您想要获取的具体字段的新类。例如,对于Owner实体,您可以创建仅包含OwnerInfoidfirstName字段的lastName投影。

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的新存储库接口,并定义将返回投影的查找程序。

public interface OwnerRepositoryCustom {

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

}

创建OwnerRepositoryCustom的实现。此类应该从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));
    }

}

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

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

}

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

希望它有所帮助,