今天要实现一个功能,去数据库查询一个字段,查出该字段有几个不同的值,以及每个值有多少条记录。我想到的是group by分组查询功能,以前虽然学习过,但是没具体去实践,没想到今天实现过程中纠结了很久,我把遇见的问题记录下来供参考
这里引用一篇博客:https://www.cnblogs.com/snsdzjlz320/p/5738226.html 讲解 group by 的一些功能
1.创建一个VO类,用于封装查询到的信息
public class MainPage {
private String zczt; //保存数据表 字段 中的值
private Long count; //保存每个 值 有多少条记录
/** * 定义默认构造器 * * 初始化 {@link MainPage} 类的新实例。 */
public MainPage() {}
/** * 重载构造器 * * 初始化 {@link MainPage} 类的新实例。 * @param zczt * @param count */
public MainPage(String zczt, Long count) {
super();
this.zczt = zczt;
this.count = count;
}
public String getZczt() {
return zczt;
}
public void setZczt(String zczt) {
this.zczt = zczt;
}
public Long getCount() {
return count;
}
public void setCount(Long count) {
this.count = count;
}
}
2.在Dao层写查询语句,获取数据
@SuppressWarnings("unchecked")
public void countData() {
StringBuilder jpql = new StringBuilder("select new assets.main.management.entity.MainPage(list.zczt,count(list.zczt)) from ZC_LIST_INFO list group by list.zczt");
Query query = entityManager.createQuery(jpql.toString());
List list = query.getResultList();
for (int i=0; i < list.size(); i++) {
MainPage mainPage = list.get(i);
System.out.println("------数值----"+mainPage.getZczt());
System.out.println("------每个数值的记录条数----"+mainPage.getCount());
}
}
成功取出数据
1.如何写 SQL 语句?
在实现过程中,这个是最纠结的一个问题,sql语句整么写。最开始我是这样写的:
select list.zczt,count(list.zczt) from ZC_LIST_INFO list group by list.zczt
那么,要整么去获取到查询的结果?
打印了下 query.getResultList( ),返回的结果到底是什么东西,好吧,其实就是五个对象,那么肯定要有东西去接收这些对象,再把数据取出来
假设一:用自定义的VO类去接收
List< MainPage > list = query.getResultList();
for (int i=0; i < list.size(); i++) {
MainPage mainPage = list.get(i);
System.out.println("------数值----"+mainPage.getZczt());
System.out.println("------每个数值的记录条数----"+mainPage.getCount());
}
分别读取出来,但是最后发现,控制台打印异常,如下:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to assets.main.management.entity.MainPage
不能封装到该类中去,这种假设失败
假设二:既然不能用 VO类,那么用 数据表映射的 entity去接收?好吧,这种想想就可以了,数据表中都没有count这个字段
假设三:List 不规定类型呢?直接 List list = query.getResultList(); 试了下,还是不行,取不出 zczt 和 count 两个属性的值呀
假设N:假设已用光
好吧,只有从sql语句那里做文章了,直接在查询时通过构造器初始化
StringBuilder jpql = new StringBuilder("select new assets.main.management.entity.MainPage(list.zczt,count(list.zczt)) from ZC_LIST_INFO list group by list.zczt");
这样写我其实有很大的怀疑的,因为 count(list.zczt)这东西,到底能不能初始化成功,之前直接一个 count就完事儿了,现在还要加个小括号,带一点小尾巴,很是让人觉得有错。好吧,最后发现,带点小尾巴其实也挺可爱的,能成功解析。最后用 VO 去接收,perfect,可以的!
2.count这属性,是什么类型?
之前使用 int count 去声明count,结果在查询时初始化报错:
无法写入构造器,在位置没有写错的情况下,那么就是类型的错误了。根据前辈的解释,select count(*)返回的类型一般是 Long 型,但是我没找到具体的api,在 mysql的api中也没有提出(难道我遇见了一个假的mysql???严重怀疑)
最后还是改为 Long,测试一下,可以了。
文章中有错有不妥之处,还请各位前辈留下珍贵的建议,小编在此五体跪谢!!!