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
实体,您可以创建仅包含 id
、firstName
和 lastName
字段的 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> and
OwnerRepositoryCustom` 接口扩展 OwnerRepository
接口。
public interface OwnerRepository extends OwnerRepositoryCustom, JpaRepository<Owner, Long> {
}
通过这些简单的步骤,您将能够 return 在您的存储库方法中进行投影。
希望对您有所帮助,
在这种情况下有使用@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
实体,您可以创建仅包含 id
、firstName
和 lastName
字段的 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> and
OwnerRepositoryCustom` 接口扩展 OwnerRepository
接口。
public interface OwnerRepository extends OwnerRepositoryCustom, JpaRepository<Owner, Long> {
}
通过这些简单的步骤,您将能够 return 在您的存储库方法中进行投影。
希望对您有所帮助,