【Hibernate】Hibernate的聚类查询、分组查询、排序与时间之差

在Hibernate中的HQL语句其实能够基本能够实现SQL语句所做的事情,正如jQuery至于javascript一样。虽然HQL语句是对类的查询,但是HQL在实行聚类查询、分组查询、排序与时间之差等查询,也无须把查询结果查询出来,再通过对List的处理才得到结果。

比如有一张如下的Testtable表:

要像《【Mysql】求出离最近相差X天的项,sql语句关于日期的比对》(点击打开链接)一样,查询date字段离现在具有30年的项有多少,SQL语句则这样写:

select count(*) from testtable
where
timestampdiff(year,date,now())<30;

其查询结果如下图:

在Hibernate中的Java语句则如下实现,同时这样输出:

String hql="select count(*) from Testtable t where timestampdiff(year,t.date,now())<30"
String result=session.createQuery(hql).uniqueResult().toString();
System.out.println(result);

这里利用了纯粹的HQL查询,同时返回结果唯一。省略Hibernate的初始化与配置等。

直接利用uniqueResult()的方法即可。

如果,查询结果是多行的情况,比如还是对刚才的Testtable表进行查询,

这次查询的是在《【Mysql】利用group by附带having进行聚类查询》(点击打开链接)查询过的,在username出现次数多于1次,不含1次的项,并且降序排列,那么sql语句则这样写:

select username,count(*) from testtable
group by username
having coutn(*)>1
order by count(*) desc

其查询结果如下图:

在Hibernate中的Java程序则如下写,关键是把查询结果的每一行转化成Object数组,则对Object数组的每一项进行强制类型的转化,则可以完成处理:

String hql="SELECT t.username,count(*) FROM Testtable t group by t.username having count(*)>1 order by count(*) desc"
List<Object> resultList = session.createQuery(hql).list();
for (int i = 0; i < resultList.size(); i++) {
	Object[] obj = (Object[])resultList.get(i);
	System.out.println(obj[0]+","+obj[1]);
}

这里利用了纯粹的HQL查询,也省略Hibernate的初始化与配置等。如果你要利用到查询结果做后续工作,

则可以,这样处理:

String username=(String)obj[0];

可以看出,HQL语句其实与SQL没有什么差别,SQL的所有关键字在HQL里面都是存在的,只是有少许改变,

关键是,在要查询的类中,后面补一个替换名称,比如Testtable就替换为t,就可以顺利操作了。

上述省略整个HQL初始化与布置的过程,具体请看《【Hibernate】Hibernate的层次划分,Hibernate4.3的初始化的新写法》(点击打开链接),不再赘述。

其中,这里的目录结构是这样的:

其中,

dbDAO.java,数据库业务类,一字未改,多次复用:

import org.hibernate.*;
import org.hibernate.cfg.*;
import org.hibernate.service.*;
import org.hibernate.boot.registry.*;

public class dbDAO {
	private Session session;

	// 构造函数,初始化Session,相当于连接数据库
	public dbDAO() {
		//这里使用了Hibernate4.3.8的写法,这里Hibernate又把初始化的方法修改了,非常蛋疼
		Configuration cfg = new Configuration().configure();
		ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
				.applySettings(cfg.getProperties()).build();
		SessionFactory sessionFactory = cfg
				.buildSessionFactory(serviceRegistry);
		this.session = sessionFactory.openSession();
	}

	// 执行查询
	public Query query(String hql){
		return session.createQuery(hql);
	}

	// 执行插入、修改
	public void save(Object object){
		Transaction transaction=session.beginTransaction();
		session.save(object);
		transaction.commit();
	}

	// 执行删除
	public void delete(Object object){
		Transaction transaction=session.beginTransaction();
		session.delete(object);
		transaction.commit();
	}

	// 析构函数,中断Session,相当于中断数据库的连接
	protected void finalize() throws Exception {
		if (session.isConnected() || session != null) {
			session.close();
		}
	}

}

hibernate.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!--所用的数据库驱动  -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<!--所用的数据库登陆密码  -->
		<property name="hibernate.connection.password">admin</property>
		<!--所用的数据库名称为test,根据实际更改 -->
		<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
		<!--所用的数据库用户名  -->
		<property name="hibernate.connection.username">pc</property>
		<!--所用的数据库方言,与所用数据库驱动一样,可以在网上查到,这里是mysql -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
		<property name="hibernate.format_sql">true</property>
		<!--如果是update表明Hibernate将保留原来的数据记录,插入时把新记录添加到已有的表,-->
		<!--如果是create,则总是创建新的表,如果原来数据库已有的这个表,则这个表的记录会被全部清洗  -->
		<property name="hibernate.hbm2ddl.auto">update</property>
		<!--罗列Testtable表与Java文件的映射,这里就Testtable.java的一张表,所以就写一个Testtable.java  -->
		<mapping class="Testtable" />
	</session-factory>
</hibernate-configuration>

Testtable.java,数据库持久化类的内容如下,只是把数据库中的testtable表的所有东西映射过来:

import javax.persistence.*;

@Entity
@Table(name = "testtable")
public class Testtable {
	private int id;
	private String username;
	private String number;
	private String date;
	// 表示主键与自动生成项
	@Id
	@GeneratedValue
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@Column(name = "username")
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	@Column(name = "number")
	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	@Column(name = "date")
	public String getDate() {
		return date;
	}

	public void setDate(String date) {
		this.date = date;
	}

	@Override
	public String toString() {
		return id + "," + username + "," + number + "," + date;
	}

}

最关键的是控制层方法实现类,HQL.java,就是把上面所介绍的Hibernate的聚类查询、分组查询、排序与时间之差查询利用dbDAO.java的封装,一一实现:

import java.util.*;

@SuppressWarnings("unchecked")
public class HQL {
	public static void main(String[] args) {
		// 建立DAO类
		dbDAO db = new dbDAO();
		// 如果返回值是唯一的,则用uniqueResult()方法
		String result = db
				.query("select count(*) from Testtable t where timestampdiff(year,t.date,now())<30")
				.uniqueResult().toString();
		System.out.println(result);
		System.out.println();
		// 排序与聚类查询(分组查询)
		List<Object> resultList = db
				.query("SELECT t.username,count(*) FROM Testtable t group by t.username having count(*)>1 order by count(*) desc")
				.list();
		for (int i = 0; i < resultList.size(); i++) {
			Object[] obj = (Object[]) resultList.get(i);
			System.out.println(obj[0] + "," + obj[1]);
		}

	}

}

运行结果如下图:

时间: 2024-08-25 11:21:42

【Hibernate】Hibernate的聚类查询、分组查询、排序与时间之差的相关文章

2016/3/13 七种查询 (普通查询 条件查询 排序查询 模糊查询 统计查询 分组查询 分页查询 )

一句话概括的话,SQL作为结构化查询语言,是标准的关系型数据库通用的标准语言: T-SQL 是在SQL基础上扩展的SQL Server中使用的语言 1,普通查询 #查询Info表中的所有列 select * from Info #查询Info表中的Name和Code列 select Name,Code from Info 2,条件查询 关键字where #查询Info表的左右列 限定范围 列名为p001 select * from Info where 列名="p001" #查询条件之

Hibernate5-投影查询,分组查询,Query的List和Iterate

1.创建项目,项目名称hibernatedemo9,目录结构如图所示 2.在项目中创建lib目录存储jar文件,目录结构如图所示 3.在src目录中创建实体Bean Forum,包名(com.mycompany.demo.bean),如图所示 4.实体Bean Forum的内容如下 package com.mycompany.demo.bean; public class Forum { private int fid; private String name; private int issh

Oracle 高级查询1 关联查询 分组查询

高级查询 1.关联查询作用:可以跨越多表查询 --查询出员工的名字和他所在部门的的名字 语法:select 列,列,列 from 表1 join 表2on 表1外键=表2主键 2.外联接 左外联[left outer join] 以关联的左边为准,即使右边没有与之匹配的记录,则左边的记录也要 出现在结果集中,右边全部以NULL值显示. 右外联[right outer join] 以关联的右边为准,即使左边没有与之匹配的记录,则右边的记录也要 出现在结果集中,左边全部以NULL值显示. 3分组查询

Oracle的查询-分组查询

--查询出每个部门的平均工资 select e.deptno,avg(e.sal) from emp e group by e.deptno; 分组查询中,出现在 group by 后面的原始列,才能出现在 select 后面 没有出现在 group by 后面的原始列 ,想在 select 后边出现必须加上聚合函数 --查询出平均工资高于2000的部门 select e.deptno,avg(e.sal) from emp e group by e.deptno having avg(e.sa

关系数据库SQL之基本数据查询:子查询、分组查询、模糊查询

http://www.jianshu.com/p/eeb6a898d4ec 前言 上一篇关系数据库常用SQL语句语法大全主要是关系型数据库大体结构,本文细说一下关系型数据库查询的SQL语法. SQL数据查询 语法回顾 SELECT [ALL|DISTINCT] <目标列表达式>[,<目标列表达式>]- FROM <表名或视图名>[,<表名或视图名>]- [WHERE <条件表达式>] [GROUP BY <列名> [HAVING &l

Hibernate 笔记 HQL查询 条件查询,聚集函数,子查询,导航查询

本笔记继续使用dept部门表,emp员工表,一对多多对一双向映射. 1 条件查询 1.1    查询 员工表emp中 年龄eage小于30,月薪esal大于20000的员工姓名ename sql:select ename from emp where eage<? and esal >?; hql: select ename from Emp where eage<? and esal >? 1.2 问号的设置与别名 问号(?)的设置使用.setParameter(位置, 属性值)

hibernate条件查询 Criteria查询

criteria查询 的方法详解 1.获取 criteria对象 Criteria criteria = this.getSession().createCriteria(Record.class); 红色部分为实体类,此处的Record代表信息记录类 2.追加条件 criteria = criteria.add(Expression.eq("level", 1)); 红色部分 Expression.eq("",""),两个参数第一个是 实体类中

Hibernate笔记3--多表操作-导航查询

一.一对多操作 1.构造实体类及编写配置文件:     一方: 1 // 一个Customer对应多个linkman 2 private Set<Linkman> linkmans = new HashSet<>(0); 配置: 1 <!-- inverse="true"代表放弃外键维护权 --> 2 <set name="linkmans" inverse="true"> 3 <!-- 配置

Hibernate的几种查询方式-HQL,QBC,QBE,离线查询,复合查询,分页查询

HQL查询方式 这一种我最常用,也是最喜欢用的,因为它写起来灵活直观,而且与所熟悉的SQL的语法差不太多.条件查询.分页查询.连接查询.嵌套查询,写起来与SQL语法基本一致,唯一不同的就是把表名换成了类或者对象.其它的,包括一些查询函数(count(),sum()等).查询条件的设定等,全都跟SQL语法一样. 示例: Session session = SessionFactory.getCurrentSession(); User user = null; Transaction ts = s