Hibernate详解HQL_QBL查询

本文详细介绍了Hibernate的查询方式,包括OID查询、对象导航查询、HQL检索(基本查询、排序、条件、投影及多表查询)、QBC查询(简单、排序、分页和条件查询)以及SQL检索。重点讨论了HQL的特点和用法,如投影查询、分页查询和多表连接。同时,文章还提及了Hibernate的抓取策略,如延迟加载和不同级别的延迟加载配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hibernate的查询方式

Hibernate提供了5种查询方式:

1.OID查询

根据对象OID(主键)进行检索,使用get方法;使用load方法。

2.对象导航查询

根据一个已查询到的对象,获得关联对象。

LinkMan linkMan = session.get(LinkMan.class, 1l);
Customer customer = linkMan.getCustomer();//根据查询对象获得关联对象

3.HQL检索

HIbernate Query Language ,Hibernate的查询语言,是一种面向对象的查询方式语言,语法类似SQL。通过session.createQuery(),用于接收一个HQL进行查询的方式。

HQL查询所有使用:from 表名;  而不使用select * from 表名;  应为HQL不能直接查询* 但是可以查询COUNT(*)查询到的是Long类型的值。

我们首先创建一张一对多的表:

基本查询

	@Test//HQL的简单查询
	public void test2(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		Query query = session.createQuery("from Customer");
		//也可取别名查询,别名查询可以select c.cust_name from Customer c
//		Query query2 = session.createQuery("select c from Customer c");//第二个c是别名
		List<Customer> list = query.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		transaction.commit();
	}

排序查询

	@Test//排序查询
	public void test3(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
//		Query query = session.createQuery("from Customer order by cust_id asc");//asc是升序,默认值可不写
		Query query2 = session.createQuery("from Customer order by cust_id desc");//desc是降序
		List<Customer> list = query2.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		transaction.commit();
	}

条件查询

一、按位置绑定:根据参数位置进行绑定

		//查询姓名以杨开头,来源是网络的对象customer
		Query query = session.createQuery("from Customer where cust_name like ? and cust_source=?");
		query.setParameter(0, "杨%");
		query.setParameter(1, "网络");
		List<Customer> list = query.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}

二、按名称绑定

	//按名称绑定,查询姓名以杨开头,来源是网络的对象customer
		Query query = session.createQuery("from Customer where cust_name like :suibianqi and cust_source= :suibianjiao");
		query.setParameter("suibianqi", "杨%");
		query.setParameter("suibianjiao", "网络");
		List<Customer> list = query.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}

投影查询:查询对象的某个或某些属性

		//查询出数组
		List<Object[]> list = session.createQuery("select c.cust_name,c.cust_source from Customer c").list();
		for (Object[] objects : list) {
			System.out.println(Arrays.toString(objects));
		}
		//查询出并封装对象:需要在实体只提供对应的有参构造
		List<Customer> list2 = session.createQuery("select new Customer(cust_name,cust_source) from Customer").list();
		for (Customer customer : list2) {
			System.out.println(customer);
		}

查出的数组:

查出的对象:

分页查询

		//从第20个记录开始,查询10条记录
		Query query = session.createQuery("from LinkMan");
		query.setFirstResult(20);
		query.setMaxResults(10);
		List<LinkMan> list = query.list();
		for (LinkMan linkMan : list) {
			System.out.println(linkMan);
		}

聚合函数&分组统计

		//聚合函数:COUNT(),MAX(),MIN(),AVG(),SUM()
		Object object = session.createQuery("select count(*) from Customer").uniqueResult();
		System.out.println(object);
		//分组统计:按照来源分组,筛选出总数大于等于1的来源
		List<Object[]> list = session.createQuery("select cust_source,count(*) from Customer group by cust_source having count(*)>=1").list();
		for (Object[] objects : list) {
			System.out.println(Arrays.toString(objects));
		}

HQL多表查询

分为内连接、迫切内连接、左外连接、右外连接、迫切左外连接。

迫切连接时给普通连接的join后面加上fetch,作用是:普通连接查询结果是一个对象数组,迫切连接查询结果将附表封装成到主表,将查询结果封装成一个对象。关于内连接和外连接的概念:https://blog.youkuaiyun.com/weixin_38930706/article/details/81157775#t36

//普通内连接:封装成数组
		List<Object[]> list = session.createQuery("from Customer c inner join c.linkMans").list();
		for (Object[] objects : list) {
			System.out.println(Arrays.toString(objects));
		}
List<Customer> list = session.createQuery("select distinct c from Customer c inner join fetch c.linkMans").list();
		for (Customer customer : list) {//toString方法加上linkMans
			System.out.println(customer);
		}

select distinct c 可以把重复的查询结果删除。

4.QBC检索

Query By Criteria 标准查询。是一种更加面向对象化的查询方式,连查询语句都不用写。直接调用对象中的方法进行设置。

简单查询

	@Test//简单查询
	public void test1(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		Criteria criteria = session.createCriteria(Customer.class);
		List<Customer> list = criteria.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		transaction.commit();
	}

排序查询

	@Test //排序查询
	public void test2(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		Criteria criteria = session.createCriteria(Customer.class);
//		criteria.addOrder(Order.asc("cust_id"));//升序(默认)
		criteria.addOrder(Order.desc("cust_id"));//降序
		List<Customer> list = criteria.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		transaction.commit();
	}

分页查询

	@Test//分页查询
	public void test3(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		Criteria criteria = session.createCriteria(LinkMan.class);
		criteria.setFirstResult(20);
		criteria.setMaxResults(10);
		List<LinkMan> list = criteria.list();
		for (LinkMan linkMan : list) {
			System.out.println(linkMan);
		}
		transaction.commit();
	}

条件查询

条件查询设置条件:

=>>=<<=<>likeorandin
eqgtgeltlenelikeorandin

 

条件查询多多条criteria.add()之间是and关系。

	@Test//条件查询
	public void test4(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		Criteria criteria = session.createCriteria(Customer.class);
		criteria.add(Restrictions.eq("cust_source", "小广告"));
		criteria.add(Restrictions.like("cust_name", "李%"));
		List<Customer> list = criteria.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		
		transaction.commit();
	}

统计查询

	@Test//统计查询
	public void test5(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		Criteria criteria = session.createCriteria(Customer.class);
		criteria.setProjection(Projections.rowCount());//这种查询可以查询:聚合函数  和   group by  having
		Object num = criteria.uniqueResult();
		System.out.println(num);
		
		transaction.commit();
	}

离线条件查询(SSH)

离线条件查询的对象是DetachedCriteria,它更适合做综合条件查询。

	@Test//离线条件查询
	public void test6(){
		DetachedCriteria detachedCriteria =DetachedCriteria.forClass(Customer.class);
		detachedCriteria.add(Restrictions.like("cust_name", "李%"));
		
		Session session = HibernateUtils.getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		Criteria criteria = detachedCriteria.getExecutableCriteria(session);
		List<Customer> list = criteria.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		
		transaction.commit();
	}

 

5.SQL检索

	@Test//SQL查询
	public void test1(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		SQLQuery sqlQuery = session.createSQLQuery("select * from cst_customer");
/*		//查询结果封装到Object[]中
		List<Object[]> list = sqlQuery.list();*/
		//查询结果封装到Customer对象中
		sqlQuery.addEntity(Customer.class);
		List<Customer> list = sqlQuery.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		
		transaction.commit();
	}

SQL查询已经不常用了,但是调优还是方便的。

Hibernate抓取策略

抓取策略是对hibernate进行性能调优的手段。

首先了解延迟加载:延迟加载分为 类延迟加载    和      关联级别的延迟加载

类延迟加载的开启和关闭可以在类对应的hibernate映射配置文件中的<class>标签中加入属性lazy="true" 和 lazy="false"。关闭延迟加载的话load()方法和get()方法的作用一样了,会立即发送查询语句。

类级别加载如何让lazy失效?

   1.lazy="false"

   2.将持久化类用final修饰

   3.Hibernate.initialize(obj)

关联级别的延迟加载在一对多的关系中还需要添加标签属性lazy="true" 和 lazy="false"到:一的一方到<set>;多的一方到<many-to-one>。<class>中的lazy只会对<property>中的属性起作用。

抓取策略往往会和关联级别的延迟加载一起使用来优化语句。

抓取策略的概述

  1. 通过一个对象抓取到关联对象需要发送SQL语句,SQL语句如何发送,发送成什么样格式通过策略进行配置。
    1. 通过<set>或者<many-to-one>上通过fetch属性进行设置
    2. fetch和这些标签上的lazy如何设置优化发送的SQL语句
      1. <set>上的fetch和lazy
  2. fetch:抓取策略,控制SQL语句格式
    1. select                :默认值,发送普通的select语句,查询关联对象
    2. join                    :发送一条迫切左外连接查询关联对象
    3. subselect         :发送一条子查询查询其关联对象
  3. lazy:延迟加载,控制查询关联对象的时候是否采用延迟
    1. true                   :默认值,查询关联对象的时候,采用延迟加载
    2. false                          :查询关联对象的时候,不采用延迟加载
    3. extra                 :及其懒惰。
  4. 在实际开发中,一般都采用默认值。如果有特殊的需求,可能需要配置join
        1. <many-to-one>上的fetch和lazy
  5. fetch :抓取策略,控制SQL语句格式。
    1. select       :默认值,发送普通的select语句,查询关联对象。
    2. join           :发送一条迫切左外连接。
  6. lazy   :延迟加载,控制查询关联对象的时候是否采用延迟。
    1. proxy       :默认值,proxy具体的取值,取决于另一端的<class>上的lazy的值。
    2. false                  :查询关联对象,不采用延迟。
    3. no-proxy :(不会使用)
  7. 在实际开发中,一般都采用默认值。如果有特殊的需求,可能需要配置join
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值