package com.yuqiyu.querydsl.sample.chapter6.controller
import com.querydsl.jpa.impl.JPAQueryFactory
import com.yuqiyu.querydsl.sample.chapter6.bean.UserBean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import javax.annotation.PostConstruct
import javax.persistence.EntityManager
import java.util.List
* ========================
* Created with IntelliJ IDEA.
* User:恒宇少年
* Date:2017/7/12
* Time:10:59
* 码云:http://git.oschina.net/jnyqy
* ========================
@RestController
public class UserController
//实体管理对象
@Autowired
private EntityManager entityManager
//queryDSL,JPA查询工厂
private JPAQueryFactory queryFactory
//实例化查询工厂
@PostConstruct
public void init()
queryFactory = new JPAQueryFactory(entityManager)
下面我们开始编写聚合函数代码。
Count函数
我们现在的需求是查询用户表内的总条数,控制器方法代码如下所示:
* count聚合函数
* @return
@RequestMapping(value = "/countExample")
public long countExample()
QUserBean _Q_user = QUserBean.userBean;
return queryFactory
.select(_Q_user.id.count())
.from(_Q_user)
.fetchOne();
可以看到我们根据id这个字段进行了count聚合,当然我们也可以根据实体内任意字段进行count聚合,我们一般会根据主键来进行聚合,因为主键默认有索引,效率会更高。
这里要注意一点,我们使用的fetchOne方法返回的类型完全是根据select方法内单个参数的类型对应的。
下面我们来启动项目测试下我们这个count聚合是否有效,项目启动完成后我们访问地址http://127.0.0.1:8080/countExample,界面输入内容如下图2所示:
我们再来看下控制台输出的生成SQL是否为我们预期的效果,SQL如下所示:
Hibernate:
select
count(userbean0_.u_id) as col_0_0_
users userbean0_
可以看到QueryDSL自动生成的SQL跟我们预期的是一样的,我又被QueryDSL的方便深深的折服了。
Sum函数
接下来我们需要查询所有用户分数总和,代码如下所示:
* sum聚合函数
* @return
@RequestMapping(value = "/sumExample")
public double sumExample()
QUserBean _Q_user = QUserBean.userBean;
return queryFactory
.select(_Q_user.socre.sum())
.from(_Q_user)
.fetchOne();
我们重启项目测试我们的sum聚合函数是否能够查询出总分数,访问地址http://127.0.0.1:8080/sumExample界面输出内容如下图3所示:
我们再来查看下控制台输出的生成SQL,如下所示:
Hibernate:
select
sum(userbean0_.u_score) as col_0_0_
users userbean0_
也是没问题的,很智能,可谓是指哪打哪。
Avg函数
下面我们又有新的需求了,需要查询下积分的平均值,代码如下所示:
* avg聚合函数
* @return
@RequestMapping(value = "/avgExample")
public double avgExample()
QUserBean _Q_user = QUserBean.userBean;
return queryFactory
.select(_Q_user.socre.avg())
.from(_Q_user)
.fetchOne();
访问映射地址界面输出内容如下图4所示:
我们再来看下控制台输出的SQL,如下所示:
Hibernate:
select
avg(userbean0_.u_score) as col_0_0_
users userbean0_
可以看到QueryDSL自动根据积分字段进行了avg聚合实现。
Max函数
接下来我们来查询用户最大积分值,代码如下所示:
* max聚合函数
* @return
@RequestMapping(value = "/maxExample")
public double maxExample()
QUserBean _Q_user = QUserBean.userBean;
return queryFactory
.select(_Q_user.socre.max())
.from(_Q_user)
.fetchOne();
我们根据积分字段调用max方法即可获取最大积分,然后调用fetchOne方法就能够返回double类型的最大积分值。我们重启下项目访问路径http://127.0.0.1:8080/maxExample界面输出内容如下图5所示:
下面再来看下控制台输出的SQL,如下所示:
Hibernate:
select
max(userbean0_.u_score) as col_0_0_
users userbean0_
到现在为止我们得出来了一个结论,如果原生SQL内聚合函数是作用在字段上,在QueryDSL内使用方法则是查询属性.xxx函数,那么接下来的聚合函数作用域就不是字段了而变成了表。
Group By函数
我们的分组函数该如何使用呢?下面我们根据积分进行分组并且仅查询年龄大于22岁的数据,控制器代码如下所示:
* group by & having聚合函数
* @return
@RequestMapping(value = "/groupByExample")
public List<UserBean> groupByExample()
QUserBean _Q_user = QUserBean.userBean;
return queryFactory
.select(_Q_user)
.from(_Q_user)
.groupBy(_Q_user.socre)
.having(_Q_user.age.gt(22))
.fetch();
因为Group By函数作用域不是字段而是表,所以会与select、from方法同级,跟原生SQL一样使用Group By进行查询时查询条件不能使用where,而是having!在QueryDSL内也是一样,因为QueryDSL完全遵循了SQL标准。
下面我们重启下项目访问地址http://127.0.0.1:8080/groupByExample看下效果,如下图6所示:
可以看到我们读取到数据是正确的,仅仅查询出了大于22岁的数据。下面我们再来看下控制台输出的SQL如下所示:
Hibernate:
select
userbean0_.u_id as u_id1_0_,
userbean0_.u_age as u_age2_0_,
userbean0_.u_username as u_userna3_0_,
userbean0_.u_score as u_score4_0_
users userbean0_
group by
userbean0_.u_score
having
userbean0_.u_age>?
可以看到SQL是根据积分字段进行分组并且查询年龄大于22岁的列表。
以上内容就是本章的全部讲解,我们不管是从上面的代码还是之前章节的代码可以得到一个QueryDSL的设计主导方向,QueryDSL完全遵循SQL标准进行设计,SQL内的作用域的关键字在QueryDSL内也是通过,不过展现形式不同罢了。
上面函数不是全部的聚合函数,项目中如果需要其他函数可按照本章的思路去写。
本章代码已经上传码云:
SpringBoot配套源码地址:https://gitee.com/hengboy/spring-boot-chapter
SpringCloud配套源码地址:https://gitee.com/hengboy/spring-cloud-chapter
SpringBoot相关系列文章请访问:目录:SpringBoot学习目录
QueryDSL相关系列文章请访问:QueryDSL通用查询框架学习目录
SpringDataJPA相关系列文章请访问:目录:SpringDataJPA学习目录
感谢阅读!
更多干货文章扫码关注微信公众号
加入知识星球,恒宇少年带你走以后的技术道路!!!
在企业级项目开发过程中,往往会经常用到数据库内的聚合函数,一般ORM框架应对这种逻辑问题时都会采用编写原生的SQL来处理,而QueryDSL完美的解决了这个问题,它内置了SQL所有的聚合函数下面我们简单介绍我们常用的几个聚合函数。本章目标基于SpringBoot平台整合QueryDSL完成常用聚合函数使用。构建项目我们使用idea来创建一个SpringBoot项目,pom....
querydsl使用groupby的一个不记录
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: expecting CLOSE, found ','
最近发现在使用Querydsl fetchCount()的时候使用groupBy()会报错,经过多次测试后发现,如果使用fetchCount()之前使用了groupBy()并且有多个字段分组,如groupBy(qUser.name,
使用Querydsl和Spring Data制作“ REST查询语言”的示例
借助和Spring Data扩展,我们可以轻松实现“ REST查询语言”来过滤特定实体的数据。
为此,我们可以从QuerydslPredicateExecutor扩展QuerydslPredicateExecutor ,将带有注释@QuerydslPredicate Predicate添加为REST控制器方法的参数,并在存储库的findAll方法中使用它。
然后,我们可以请求具有基本过滤,分页和排序支持的实体数据,例如,如下所示:
GET /people?name=John&size=10&page=2,sort=name,desc
其中name是我们实体Person的属性, size是页面大小, page是当前页面的数量, sort是一个参数,该参数告诉您按name对数据进行降序排序。
publi
在使用group by分组后展示其他字段
需要加any_value(字段名)
例如: select time from student group by time 还想获取其他字段信息
如下: select time,any_value(id),any_value(name),any_value(sex),any_value(grade) from student group by time,即可实现对其他字段信息的获取.
JPA或MongoDB的Spring数据;
所有项目都很简单,专为学习目的而开发。
每个项目都设置数据,并利用来自各种过滤器,排序和分页的灵活搜索/查询功能。 每个项目都展示了一种持久性方法,探索了前面提到的技术。 看:
querydsl-jpa:使用Spring MVC和Spring Boot开发的Java Web应用程序,演示了如何使用QueryDSL和JPA / Hibernate。 使用的数据库是HSQLDB。 前端是使用JQuery和Foundation开发的。
querydsl-spring-data:使用Spring MVC和Spring Boot开发的Java Web应用程序演示了Spring Data JPA如何与QueryDSL和JPA一起使用。 前端是
spring-boot-querydsl-bug
说明 querydsl 集合和 spring boot 的 javac 调用类路径问题
如果作为 spring boot 应用程序运行,它将调用 javac 来编译 QueryDSL 生成的代码,但它找不到任何类。 都有最新的稳定版和最新的 Spring Boot 快照。
就我调试它而言,似乎 Spring Boot 的类加载器将其类路径公开为 URL 列表,但尝试将其传递给 javac 调用的 QueryDSL 代码以错误的方式解析它,因为它期望路径列表。
尚不确定这是否是 QueryDSL 或 Spring Boot 中的错误...
关于 QueryDSL
最近写项目,使用到了 Jpa 这个 ORM 规范支持,使用注解的方式实现 Sql ,但是用过 Jpa 的同学都知道 Jpa 对于单表操作很灵活,但是对于复杂一些的 SQL 就是很不友好了,所以这个地方我们就用到了 QueryDSL 来实现复杂的 Sql(另外强行安利一波 Tk-MyBatis)
什么是 QueryDSL ?
QueryDSL仅仅是一...
querydsl-jpa 是一个基于 Java 语言的开源 ORM 查询框架,它提供了一种类型安全、流畅的 API 接口,使得查询 JPA 实体变得更加容易和简单。通过使用 querydsl-jpa,开发人员可以避免常见的 JPA 查询繁琐和容易出错的情况,同时,也可以享受到类型安全、易于维护和更加高效的查询体验。
querydsl-jpa 的主要特点包括:
1. 类型安全的查询:querydsl-jpa 提供了一种类型安全的查询 API 接口,完全避免了使用字符串拼接的方式来生成 SQL 语句的情况。
2. 支持 JPA 实体:querydsl-jpa 能够直接与 JPA 实体进行交互,从而使得在查询中使用的实体更加类型化和直观。
3. 支持复杂查询操作:querydsl-jpa 支持诸如嵌套子查询、联合查询、分页查询、排序查询等常见的查询操作,从而满足了更加复杂的查询需求。
4. 提供完整的类型支持:querydsl-jpa 支持传统的 SQL 数据类型,例如 INTEGER、VARCHAR 等,也支持 JPA 支持的所有类型,例如 Date、Time、Timestamp、Boolean 等。
5. 可维护性强:querydsl-jpa 生成的查询语句易于阅读和维护,从而减少了因为 SQL 语句难以阅读和理解而带来的错误和困难。
综上所述,querydsl-jpa 是一种高效、易用、类型安全、并且具有完整类型支持的 ORM 查询框架,它极大地方便了 Java 开发人员进行 JPA 实体查询操作,提高了项目的开发效率和质量。
将OpenStreetMap导出的OSM数据导入MySQL数据库
刚上路DE小白:
Grace:优雅高效的的记录业务操作日志
fizzlx:
Grace:优雅高效的的记录业务操作日志
恒宇少年: