Hibernate学习总结(5)——HQL

7.HQL

Hibernate 支持两种主要的查询方式
(1)HQL(Hibernate Query Languge,Hibernate 查询语言)查询,,是一种面向对象的查询语言,其中没有表和字段的概念,只有类、对象和属性的概念;
HQL 是应用较为广泛的方式。
(2)Criteria 查询又称为“对象查询”,它用面向对象的方式将构造查询的过程做了封装。

7.1使用HQL需要四步

(1)得到Session;
(2)编写HQL语句;
(3)创建Query对象:Query接口是HQL 查询接口。它提供了各种的查询功能;
(4)执行查询,得到结果。

7.2HQL基本语法

HQL看上去很像SQL,但是我们不要被语法结构上的相似所迷惑,HQL是非常有意识的被设计为完全面向对象的查询。
HQL中没有表和字段的概念,只有类、对象和属性的概念,这点需要大家好好体会。

(1)选择where

where 子句指定限定条件
通过与SQL 相同的比较操作符指定条件
如:
=、<>、<、>、>=、<=
between、not between
in、not in
is、like
通过and、or 等逻辑连接符组合各个逻辑表达式

例如:

@Test
	// 选择的测试
	public void whereTest() {
		String hqlString = "from Book b where lower(b.name) like '%spring%'";
		Session session = HibernateUtil.currentSession();
		Query query = session.createQuery(hqlString);
		List<Book> books = query.list();
		System.out.println(books);
	}

(2)投影

选择出现在结果集中的字段
默认情况下结果为对象数组组成的集合
可使用结果转换器

@SuppressWarnings("rawtypes")
	@Test
	// 投影的测试
	public void projectionTest() {
		Session s = HibernateUtil.currentSession();
		String queryString = "select b.name,b.count from Book b";
		Query query = s.createQuery(queryString);
		List l = query.list();
		// 投影的结果:对象数组的集合——集合中的元素是对象数组
		// System.out.println(l.get(0).getClass());
		for (Object object : l) {
			Object[] data = (Object[]) object;
			System.out.println("name==" + data[0] + ",count==" + data[1]);
		}
	}

	@SuppressWarnings({ "unchecked" })
	@Test
	// 使用结果转换器
	public void projectionTest2() {
		Session s = HibernateUtil.currentSession();
		String queryString = "select b.name as name,b.count as count from Book b";
		Query query = s.createQuery(queryString);
		// 根据别名 装配Book类对象
		query.setResultTransformer(new AliasToBeanResultTransformer(Book.class));

		List<Book> l = query.list();
		for (Book book : l) {
			System.out.println("name==" + book.getName() + ",count=="
					+ book.getCount());
			System.out.println(book.getPress());
		}
	}


 (3)参数绑定有两种方法,分别是利用定位参数和利用命名参数。

 通用查询参数绑定方法:

Query接口提供多个设置参数的方法,用来绑定大多数Hibernate内建类型的参数,例如setInteger()、setTimestamp()、setLocale() 等。
还有一种允许绑定任何hibernate类型实参的一般方法setParameter(),该方法可以自动找出正确的类型

	@Test
	// 参数绑定测试:占位符
	public void paramTest1() {
		String hqlString = "from Book b where b.name like ?";
		Session session = HibernateUtil.currentSession();
		Query query = session.createQuery(hqlString);
		String name = "Spring";
		query.setString(0, "'%" + name + "%'");// 定位参数从0开始计数
		List<Book> books = query.list();
	}

	@Test
	//  参数绑定测试:命名参数按参数名字来进行匹配
	public void paramTest2() {
		String hqlString = "from Book b where b.name like :name";
		Session session = HibernateUtil.currentSession();
		Query query = session.createQuery(hqlString);
		String name = "Spring";
		query.setString("name", name);// 命名参数按参数名字来进行匹配
		List<Book> books = query.list();
	}

	@Test
	//  参数绑定测试: 通用的传参方法
	public void paramTest3() {
		String hqlString = "from Book b where b.name like :name or b.price > :price";
		Session session = HibernateUtil.currentSession();
		Query query = session.createQuery(hqlString);
		String name = "Spring";
		// query.setDouble("price", 30f);
		// query.setString("name", name);
		// 通用的传参方法
		query.setParameter("price", 30f);
		query.setParameter("name", name);
		List<Book> books = query.list();
		System.out.println(books);
	}


我们也可以在Hibernate中使用定位参数,代码如下:

String hql = "from Position where name like ? and createDay> ?";
Query query = sf.openSession().createQuery(hql). setParameter(0,aName).setParameter(1,aDate);

请记住Hibernate定位参数是从0开始计数的

(4)分页

Query接口支持对查询结果进行分页处理,例如:
query.setFirstResult(40);
query.setMaxResults(20);
这两行代码意味着从第41个对象(setFirstResult方法的参数是开始获取对象的行数,从0开始编号)开始,获取接下来的20个对象(setMaxResults方法的参数是获取对象的数目)。

@Test
	// 测试分页
	public void pagerTest() {
		String hqlString = "from Student";
		Session session = HibernateUtil.currentSession();
		Query query = session.createQuery(hqlString);
		query.setFirstResult(10);
		query.setMaxResults(10);
		List<Student> students = query.list();
		System.out.println(students);
	}


(5)分组函数

组函数有count()、min()、max()、sum()和avg(),其含义和SQL中定义的一样。

@Test
	// 分组与统计
	public void groupTest() {
		Session s = HibernateUtil.currentSession();
		String queryString = "select count(*) from Book b";
		Query query = s.createQuery(queryString);
		long i = (Long) query.uniqueResult();// 获得单个值
		System.out.println("书籍数目:" + i);
	}

(6)连接查询

 

@Test
	public void joinTest2() {
		Session s = HibernateUtil.currentSession();
		String queryString = "select b,t from Book b join b.type t";// 按属性来做连接查询
		Query query = s.createQuery(queryString);
		List list = query.list();
		for (Object obj : list) {
			Object[] pair = (Object[]) obj;
			Book book = (Book) pair[0];
			Type type = (Type) pair[1];
			System.out.println(book.getName() + ",类型是:" + type.getName());
		}
	}

 

查询中的延迟加载

默认的Hibernate采用延迟加载策略:主对象的关联对象或集合并不是立即抓取的,加载主对象时,关联对象或集合为代理对象(假设为对象,却没有源对象的值),只有到使用这些关联对象的时候,才会被初始化(加载)。

可使用强制热抓取关联数据: fetch

@Test
	// fetch join 强制热抓取关联数据,改变默认加载策略(延迟的)
	public void joinTest3() {
		Session s = HibernateUtil.currentSession();
		String queryString = "select b from Book b  join fetch b.type ";// 按属性来做连接查询
		Query query = s.createQuery(queryString);
		List<Book> list = query.list();
		for (Book book : list) {
			System.out.println(book.getName() + ",类型是:"
					+ book.getType().getName());
		}
	}


(7)子查询

 @Test
// 查询借阅次数最多的学生
 public void subSelectTest() {
  //按借书的多少查找出学生的排名
  String hql  = " select rc.stu.id  from Record rc group by rc.stu order by count(rc.stu) desc";
  Query query = HibernateUtil.currentSession().createQuery(hql);
  
  query.setMaxResults(1);
  int stu_id = (Integer) query.uniqueResult();
  Student student = (Student) HibernateUtil.currentSession().get(Student.class, stu_id);
  System.out.println(student);
 }


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值