继承了 PagingAndSortingRepository
, 这个接口提供了 Page<T> findAll(Pageable var1);
方法
我需要自定义 sql 然后返回字段是从两个表中挑选出来的. sql 类似这样的:
select a.name ax , a.cd cd , b.name ax from a
left join b on b.id = d.bid
我需要在上面 sql 返回结果的基础上分页和排序, 请问大家怎么处理这个问题?
谢谢大家!!!
最终查询出来啦! 但是很不方便,实现步骤如下: 关联查询表如下:
TA
字段:
TB
字段:
然后查询sql这样:
select a.name as name, a.time as time, b.name as bname from TA a left join TB b on b.id = a.bid
首先需要在TA实体类上注解SqlResultSetMapping,手动映射返回字段描述,像这样:
@SqlResultSetMapping(
name = "view",
classes = {
@ConstructorResult(
targetClass = TA.class,
columns={
@ColumnResult(name = "name",type = String.class),
@ColumnResult(name = "time",type = Date.class),
@ColumnResult(name = "bname",type = String.class)
}
)
}
)
这段映射对象必须是一个entity
否则启动jpa扫描报错,异常信息大概这样:
Unknown SqlResultSetMapping [foo]
然后调用 createNativeQuery
方法执行sql
同时指定映射对象名[字符串名]
类似这样:
//需要手动注入 `EntityManager`
Query query = em.createNativeQuery(sql, "view");
//然后获取结果集
query.getResultList();
这样就可以得到指定对象的结果集了. 业务功能确实实现了,但是这种实现好难受, 声明的 SoccerGuessingRepository
在这里成了摆设, 而且分页也需要自己写了, 太别扭了!!!!!
请问大家还有别的解决方案吗?
而且需要提供返回列对应的对象的包含全部返回咧的构造方法.
1
sdandroid 2017-01-11 16:55:35 +08:00
做视图
|
3
Powered 2017-01-11 17:09:28 +08:00 via iPhone
我没看懂需求。。。
|
4
mercurylanded 2017-01-11 17:10:26 +08:00 1
换 mybatis
|
5
Charkey 2017-01-11 17:11:26 +08:00
@mercurylanded 同意。 23333333333333333
|
6
palmers OP @Powered 我的需求是这样的, 使用 spring data jpa 分页查询, 然后返回的数据是两个表部分字段的组合对象
|
7
palmers OP @mercurylanded 是啊 如果能换, 我肯定换了 绝对没这么麻烦
|
8
tedzhou1221 2017-01-11 17:34:41 +08:00
虽然我明白你的意思,但想了半小时办法,还是没想到~~
其实楼上的兄弟说,用视图搞也是可以的。 |
9
tedzhou1221 2017-01-11 17:36:58 +08:00
唉,说换 mybatis 的兄弟,不知道是怎么想的。
像我这种公司打杂的,公司项目架构,能说换就换? |
10
Sharuru 2017-01-11 18:12:11 +08:00
架构里有其他辅助方法么?比如常见的命名像什么 builder , executor 之类的,可以快速生成 SQL 。
如果没有类似的 helper ,直接手写 JPQL 也是可以的。 |
11
AlisaDestiny 2017-01-11 18:30:41 +08:00
我现在做的项目是用 springboot ,现在刚开始,估计以后也会遇到你这个问题,先收藏了。(之前用的 mybatis 很好解决)
|
12
palmers OP @AlisaDestiny ......................
|
14
mercurylanded 2017-01-11 18:50:55 +08:00
模型重新写做字段冗余,或者多查几次结果合并起来。
|
15
RadishWind 2017-01-11 18:57:06 +08:00
1.视图 create view 名字 as + 你的 sql 语句
2.子查询 3.直接 limit |
16
caixiexin 2017-01-11 19:04:29 +08:00 via Android
就是因为这个,我不喜欢用 hibernate 这类 orm😌
|
17
srx1982 2017-01-11 19:34:05 +08:00
|
18
Cbdy 2017-01-11 19:46:17 +08:00 via Android
注入实体管理器,直接执行 SQL 。参考 Spring in action
|
19
palmers OP |
21
Miy4mori 2017-01-11 19:55:25 +08:00 via Android
spring data jpa 也可以自定义 mapper ,请仔细阅读文档
|
22
incompatible 2017-01-11 19:55:48 +08:00
分两次查询咯
1. ARepository.findAll(Pagable),从取到的结果中 collect 出 bids 2. BRespository.find(Iterator of bids),然后手工跟步骤 1 的结果组合起来。 还有,从你的场景看来, b 可能是类似“分类”这样的基础数据? 这样的话针对 bid->bname 做一个缓存,步骤 2 的中直接查缓存,性能会更好。 |
25
BruceLi 2017-01-11 20:28:56 +08:00
google 一下 jpa namednativequery resultsetmapping 就能找到答案了。
|
30
Miy4mori 2017-01-12 12:20:35 +08:00 via Android
@palmers 是的 另外 spring data jpa reference 里就有 native 查询加分页的例子
|
31
teemoer 2017-01-12 13:09:31 +08:00
返回 @query 注解下面的 方法 返回 类型 定义为
list<你定义的临时类> findByQueryAnnon(); 下面是你临时类的定义 class 临时类{ ax ; cd ; ax; // 三个字段 生成 get set 方法 我就是这样处理的 } |
33
palmers OP @Miy4mori 我尝试了,但是报错, 一直提示 No property guessView found for type socgu!
@SqlResultSetMapping( name="view", classes={ @ConstructorResult( targetClass=TView.class, columns={ @ColumnResult(name = "sumber",type = String.class), @ColumnResult(name = "lname",type = String.class), @ColumnResult(name = "mnumber",type = String.class), @ColumnResult(name = "mtime",type = Date.class), @ColumnResult(name = "hname",type = String.class), @ColumnResult(name = "vname",type = String.class) } ) } ) @NamedNativeQuery(name="getView", query="select sg.sumber as sumber,sl.lname as lname, sg.mnumber as mnumber,sg.mtime as mtime,sg.hname as hname,sg.vname as vname from socgu sg left join soccle sl on sl.cguid = sg.leId", resultSetMapping="view") |
34
BruceLi 2017-01-12 16:07:43 +08:00
@palmers query 不是有 setFirstResult(), setMaxResults() 这两个 api 吗。
|
36
q397064399 2017-01-13 10:13:37 +08:00
Spring in Action EntityManager 注入就好了 然后用 sql 查询,查询完了 之后组装实体
|
37
ebony0319 2019-06-25 23:37:50 +08:00
老哥,有新的解决方案么。
|