Spring 数据存储库按列分组,对象列表与其他列
Spring data repository group by column, list of object with other columns
如何获取 Spring 存储库 return 自定义 DTS,它按 table 中的列 businessValue1 分组,并具有 DTO 对象列表以及其他列table
table,我要从中returnDTS
id | businessValue1 | businessValue2 | businessValue3
1 | "x" | "uigaiun" | "guthgi"
2 | "x" | "rktjuhngit" | "ujgthniuertn"
3 | "x" | "nguitren" | "ikljugnbe"
4 | "y" | "iughnuitn" | "eiubgnuie"
5 | "q" | "rtiluhn" | "iljughbl"
6 | "q" | "tkiruln" | "jutgnhet"
代表table
的Java实体class
@Data
@AllArgsConstructor
@Entity
public class SomeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@NotNull
private long id;
@NotNull
private String businessValue1;
@NotNull
private String businessValue2;
@NotNull
private String businessValue3;
}
目标类:
table
中其他列的DTO表示
@Data
@AllArgsConstructor
public class SomeDTO {
private String businessValue2;
private String businessValue3;
}
DTS 表示列 businessValue1 的分组依据,其他列作为 DTO 列表
@Data
@AllArgsConstructor
public class SomeDTS {
private String businessValue1;
private List<SomeDTO> dtos;
}
我的预期结果将具有如下结构
├── "x"
| ├── "uigaiun", "guthgi"
| ├── "rktjuhngit", "ujgthniuertn"
| └── "nguitren", "ikljugnbe"
|
├── "y"
| └── "iughnuitn", "eiubgnuie"
|
└── "q"
├── "rtiluhn", "iljughbl"
└── "tkiruln", "jutgnhet"
我认为 Spring 数据存储库界面应该如下所示
@Repository
public interface SomeEntityRepository extends JpaRepository<SomeEntity, Long> {
@Query(
"SELECT "
+ "new SomeDTS "
+"FROM "
+ "SomeEntity s "
+"GROUP BY "
+ "s.businessValue1")
public List<SomeDTS> SomeEntityGroupByBusinessValue1();
}
我正在努力进行 JPQL 查询,有人可以帮助我吗?
更新 1 - 2020 年 11 月 19 日:
@Zorglube
的评论让我更接近了
@Repository
public interface SomeEntityRepository extends JpaRepository<SomeEntity, Long> {
@Query(value =
"SELECT "+
" DISTINCT SomeDTS.businessValue1, SomeDTO" +
" FROM SomeEntity AS SomeDTS" +
" JOIN SomeEntity AS SomeDTO ON SomeDTS.businessValue1 = SomeDTO.businessValue1")
Stream<SomeDTS> SomeEntityGroupByBusinessValue1();
}
这仍然给我带来映射问题
No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [SomeDts]
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [SomeDts]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:194)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:174)
at org.springframework.data.repository.query.ResultProcessor$ProjectingConverter.convert(ResultProcessor.java:297)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and[=18=](ResultProcessor.java:217)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:228)
at org.springframework.data.repository.query.ResultProcessor.lambda$processResult[=18=](ResultProcessor.java:163)
at java.base/java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:195)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at org.hibernate.query.spi.StreamDecorator.collect(StreamDecorator.java:211)
.
.
.
那么如何做映射呢?
更新 2
改用接口
@Repository
public interface SomeEntityRepository extends JpaRepository<SomeEntity, Long> {
@Query(value =
"SELECT "+
" DISTINCT SomeDTSIF.businessValue1 as businessValue1, SomeDTOIF" +
" FROM SomeEntity AS SomeDTSIF" +
" JOIN SomeEntity AS SomeDTOIF ON SomeDTSIF.businessValue1 = SomeDTO.businessValue1")
Stream<SomeDTSIF> SomeEntityGroupByBusinessValue1();
}
解决了“找不到能够转换的转换器”的问题,但我得到了 6 个对象:
├── "x"
| └── NULL
|
├── "x"
| └── NULL
|
├── "x"
| └── NULL
|
├── "y"
| └── NULL
|
├── "q"
| └── NULL
|
└── "q"
└── NULL
并且 SomeDTSIF 中的 SomeDTOIF 列表没有被映射。
我最终制作了一个“虚拟”父实体,它的行为有点像视图
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Entity
@EqualsAndHashCode
@Immutable
@Subselect(
"SELECT"
+ " DISTINCT SomeEntityParent.currency_source "
+ " FROM some_entity SomeEntityParent"
+ " JOIN some_entity SomeEntity"
+ " ON SomeEntityParent.businessValue1 = SomeEntityParent.businessValue1"
)
public class SomeEntityParent {
private String businessValue1;
private List<SomeEntity> someEntity;
}
然后是基于那个的 Repository 接口
@Repository
public interface SomeEntityParentRepository extends JpaRepository<SomeEntityParent, Long> {
}
然后可以在服务中使用
@Autowired
private SomeEntityParentRepository repository;
List<SomeEntityParent> results = repository.findAll();
平面结构现在是分层对象。
如何获取 Spring 存储库 return 自定义 DTS,它按 table 中的列 businessValue1 分组,并具有 DTO 对象列表以及其他列table
table,我要从中returnDTS
id | businessValue1 | businessValue2 | businessValue3
1 | "x" | "uigaiun" | "guthgi"
2 | "x" | "rktjuhngit" | "ujgthniuertn"
3 | "x" | "nguitren" | "ikljugnbe"
4 | "y" | "iughnuitn" | "eiubgnuie"
5 | "q" | "rtiluhn" | "iljughbl"
6 | "q" | "tkiruln" | "jutgnhet"
代表table
的Java实体class@Data
@AllArgsConstructor
@Entity
public class SomeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@NotNull
private long id;
@NotNull
private String businessValue1;
@NotNull
private String businessValue2;
@NotNull
private String businessValue3;
}
目标类:
table
中其他列的DTO表示@Data
@AllArgsConstructor
public class SomeDTO {
private String businessValue2;
private String businessValue3;
}
DTS 表示列 businessValue1 的分组依据,其他列作为 DTO 列表
@Data
@AllArgsConstructor
public class SomeDTS {
private String businessValue1;
private List<SomeDTO> dtos;
}
我的预期结果将具有如下结构
├── "x"
| ├── "uigaiun", "guthgi"
| ├── "rktjuhngit", "ujgthniuertn"
| └── "nguitren", "ikljugnbe"
|
├── "y"
| └── "iughnuitn", "eiubgnuie"
|
└── "q"
├── "rtiluhn", "iljughbl"
└── "tkiruln", "jutgnhet"
我认为 Spring 数据存储库界面应该如下所示
@Repository
public interface SomeEntityRepository extends JpaRepository<SomeEntity, Long> {
@Query(
"SELECT "
+ "new SomeDTS "
+"FROM "
+ "SomeEntity s "
+"GROUP BY "
+ "s.businessValue1")
public List<SomeDTS> SomeEntityGroupByBusinessValue1();
}
我正在努力进行 JPQL 查询,有人可以帮助我吗?
更新 1 - 2020 年 11 月 19 日:
@Zorglube
的评论让我更接近了@Repository
public interface SomeEntityRepository extends JpaRepository<SomeEntity, Long> {
@Query(value =
"SELECT "+
" DISTINCT SomeDTS.businessValue1, SomeDTO" +
" FROM SomeEntity AS SomeDTS" +
" JOIN SomeEntity AS SomeDTO ON SomeDTS.businessValue1 = SomeDTO.businessValue1")
Stream<SomeDTS> SomeEntityGroupByBusinessValue1();
}
这仍然给我带来映射问题
No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [SomeDts]
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [SomeDts]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:194)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:174)
at org.springframework.data.repository.query.ResultProcessor$ProjectingConverter.convert(ResultProcessor.java:297)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and[=18=](ResultProcessor.java:217)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:228)
at org.springframework.data.repository.query.ResultProcessor.lambda$processResult[=18=](ResultProcessor.java:163)
at java.base/java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:195)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at org.hibernate.query.spi.StreamDecorator.collect(StreamDecorator.java:211)
.
.
.
那么如何做映射呢?
更新 2 改用接口
@Repository
public interface SomeEntityRepository extends JpaRepository<SomeEntity, Long> {
@Query(value =
"SELECT "+
" DISTINCT SomeDTSIF.businessValue1 as businessValue1, SomeDTOIF" +
" FROM SomeEntity AS SomeDTSIF" +
" JOIN SomeEntity AS SomeDTOIF ON SomeDTSIF.businessValue1 = SomeDTO.businessValue1")
Stream<SomeDTSIF> SomeEntityGroupByBusinessValue1();
}
解决了“找不到能够转换的转换器”的问题,但我得到了 6 个对象:
├── "x"
| └── NULL
|
├── "x"
| └── NULL
|
├── "x"
| └── NULL
|
├── "y"
| └── NULL
|
├── "q"
| └── NULL
|
└── "q"
└── NULL
并且 SomeDTSIF 中的 SomeDTOIF 列表没有被映射。
我最终制作了一个“虚拟”父实体,它的行为有点像视图
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Entity
@EqualsAndHashCode
@Immutable
@Subselect(
"SELECT"
+ " DISTINCT SomeEntityParent.currency_source "
+ " FROM some_entity SomeEntityParent"
+ " JOIN some_entity SomeEntity"
+ " ON SomeEntityParent.businessValue1 = SomeEntityParent.businessValue1"
)
public class SomeEntityParent {
private String businessValue1;
private List<SomeEntity> someEntity;
}
然后是基于那个的 Repository 接口
@Repository
public interface SomeEntityParentRepository extends JpaRepository<SomeEntityParent, Long> {
}
然后可以在服务中使用
@Autowired
private SomeEntityParentRepository repository;
List<SomeEntityParent> results = repository.findAll();
平面结构现在是分层对象。