我想查询表中的某些字段,但是我这样子写没有报错,但是把自身表中和关联表中的所有字段都查出来了,如何做到动态查询且只查询表中的某些字段和关联表中的某些字段?
public Page<OrderEntity> findAllAuto(final String sysno){
Sort sort = new Sort(Sort.Direction.DESC, "orderId");
Pageable pageable = new PageRequest(0,5,sort);
return orderRepository.findAll(new Specification<OrderEntity>() {
public Predicate toPredicate(Root<OrderEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Path<String> sys_no = root.get("sysno");
CompoundSelection<OrderEntity> cSelect = criteriaBuilder.construct(OrderEntity.class, root.get("orderId"), root.get("sysno"));
criteriaQuery.multiselect(cSelect);
criteriaQuery.where(criteriaBuilder.like(sys_no, sysno));
return null;
}
}, pageable);
}
1
Lpl 2016-12-17 20:38:57 +08:00 via Android
你这样写太复杂了,你试试 querydsl 。嗯..在外边,回去了补一段代码
|
2
MasterMonkey 2016-12-17 21:01:18 +08:00
表示曾经非常迷恋 jpa , 但是从来都没有在项目中实战过!
|
3
zhengxin1993 OP @Lpl 谢谢!
|
4
Lpl 2016-12-17 23:10:01 +08:00 2
@zhengxin1993
``` import javax.persistence.EntityManager; public class Test { @Autowired private EntityManager entityManager; public void testQueryDsl(Integer categoryId) { JPAQuery query = new JPAQuery(entityManager); // QAaaa 是 Querydsl 根据 Aaaa 这个 Bean 生成的一个对象, test1 相当于你使用多表 JOIN 的时候每个表的别名 // 假定 aaa 是分类, bbb 是文章 QAaaa qAaaa = new QAaaa("test1"); QBbbb qBbbb = new QBbbb("test2"); JPAQuery result = query.from(qAaaa, qBbbb) .where( qAaaa.categoryId.eq(qBbbb.id), qAaaa.id.eq(categoryId), qBbbb.categoryId.eq(categoryId) ).orderBy(qAaaa.createTime.desc()); // 关键点来了, 我们查找出来的数据, 每行都包含了 aaa 和 bbb 字段, // 那么, 我们 list 的时候只 list 了 aaa List<Aaaa> aaaaList = result.list(qAaaa); } } ``` JPA 底层用的是 Hibernate 的实现, JAR : hibernate-jpa-xxx-api JPAQuery 是 Querydsl 关于 JPA 接口的实现: ``` JPAQuery is the default implementation of the JPQLQuery interface for JPA ``` QAaaa/QBbbb 是 Querydsl 根据你的 JavaBean 生成的类: ``` QAaaa is a Querydsl query type for Aaaa ``` 大概是这些。。说的不怎么清楚,你再看看 Querydsl 文档: https://github.com/querydsl/querydsl |
5
Lpl 2016-12-17 23:19:11 +08:00
@Lpl v 站回复不友好,贴个图
![图片]( https://dn-coding-net-production-pp.qbox.me/df945ae8-59bd-4179-94ba-e961ef991b34.png) |
6
q397064399 2016-12-18 06:53:16 +08:00
讲道理 JPA 上手 确实有点繁琐,我不知道公司用的多不多,
如果可以的话,一些复杂的查询,用 Mybatis 配合手动 SQL 比较好, 相对而言, JPA 封装之后,你都不知道怎么改,而且上手非常繁琐, Mybatis 只是解决了数据与 POJO 的绑定, 而查询与结果集优化 却完全交给了用户, |
7
0915240 2016-12-18 11:21:28 +08:00 via iPhone
讲真 jpa 的愿景真的很好 但是总感觉真好以至于被框住🙊
|
8
zhengxin1993 OP |
9
hantsy 2016-12-19 12:13:12 +08:00
这只是 Spring Data JPA 扩展中的 Specification 。
某些关联,某些字段,和这个 API 一点关系。 参考我的例子: https://github.com/hantsy/angularjs-springmvc-sample/blob/master/src/main/java/com/hantsylabs/restexample/springmvc/repository/PostSpecifications.java 参考, 包括 Spring Data JPA 中 Specficcation 和 QueryDSL ( JPA )的例子。 @Lpl Spring Data JPA 包含对 QueryDSL 扩展。 https://github.com/hantsy/spring4-sandbox/tree/master/data-jpa/src/main/java/com/hantsylabs/example/spring/jpa/spec @zhengxin1993 说实话,先去看看 JPA 吧。 |
10
zhengxin1993 OP @hantsy 谢谢,你的例子里面并没有取表中某些字段的方法,虽然没能很好的解决,我找到了原因,框架中下面这段代码才使得 toPredicate 方法无法只取某些字段字段。
``` protected <S extends T> TypedQuery<S> getQuery(Specification<S> spec, Class<S> domainClass, Sort sort) { CriteriaBuilder builder = this.em.getCriteriaBuilder(); CriteriaQuery query = builder.createQuery(domainClass); Root root = this.applySpecificationToCriteria(spec, domainClass, query); query.select(root); ``` 框架中实现 findAll 方法中调用了此方法,它又 query.select(root),把所有字段都加回进去了,才导致重写的方法中的 select()无效。 虽然我是菜鸟,我也不是一有问题就上来问。 |
11
zhengxin1993 OP @hantsy 在 org.springframework.data.jpa.repository.support 里的 SimpleJpaRepository 的类中,大概第 370 行。包的版本是 1.10.4
|
12
hantsy 2016-12-19 22:57:36 +08:00
@zhengxin1993 呵呵,。。好像不是很难。
http://stackoverflow.com/questions/18300465/spring-data-jpa-and-querydsl-to-fetch-subset-of-columns-using-bean-constructor-p 如果你不在乎 Typesafe ,直接用 JPQL , select new ObjectXXXX(field1, field2, ...) 就行了。 |