Hibernate框架笔记04HQL

mac2022-06-30  31

目录

1. Hibernate的查询方式 1.1 方式一:OID查询1.2 方式二:对象导航查询1.3 方式三:HQL方式1.4 方式四:QBC查询1.5 方式五:SQL查询2. 环境搭建3. HQL查询 3.1 简单查询3.2 别名查询3.3 排序查询3.4 条件查询3.4 投影查询3.5 分页查询3.6 分组统计查询3.7 HQL的多表查询 3.7.1 SQL的多表查询3.7.2 HQL的多表查询4. QBC查询 4.1 简单查询4.2 排序查询4.3 分页查询4.4 条件查询4.5 统计查询4.6 离线条件查询(***)DetachedCriteria5. SQL查询6. Hibernate的抓取策略 6.1 延迟加载的概述 6.1.1 什么是延迟加载6.1.2 延迟加载的分类6.2 抓取策略 6.2.1 抓取策略概述6.2.2 set上的fetch和lazy6.2.3 many-to-one上的fetch和lazy6.2.4 批量抓取

1. Hibernate的查询方式

在Hibernate中提供了5种查询方式。

1.1 方式一:OID查询

OID查询:Hibernate根据对象的OID(主键)进行检索。使用get()方法 Customer customer = session.get(Customer.class,1L);使用load()方法 Customer customer = session.load(Custoemr.class,1L);

1.2 方式二:对象导航查询

对象导航检索:Hibernate根据一个已经查询到的对象,获得其关联的对象的一种查询方式。

LinkMan linkMan = session.get(LinkMan.class,1L); Customer customer = linkMan.getCustomer(); Customer customer = session.get(Customer.class,2L); Set<LinkMan> linkMans = customer.getLinkMans();

1.3 方式三:HQL方式

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

1.4 方式四:QBC查询

QBC查询:Query By Criteria,条件查询。是一种更加面向对象化的查询方式。

1.5 方式五:SQL查询

SQL查询:通过使用SQL语句进行查询。

2. 环境搭建

创建一个新项目,导入相关jar包

新建数据库,新建数据表,分别为cst_custoemr和cst_linkman

新建两个实体,分别为Customer和LinkMan Customer中生成toString方法,不包含LinkManLinkMan中生成toString方法,不包含Customer

准备工具类,配置文件,映射文件

生成测试的数据,该方法执行3次

/** * HQL的查询方式的测试类 * @author itzhouq * */ public class HibernateDemo1 { @Test public void test1() { Session session = HibernateUtils.getCurrentSession(); Transaction transaction = session.beginTransaction(); Customer customer = new Customer(); customer.setCust_name("莫尔德"); for (int i = 0; i < 10; i++) { LinkMan linkMan = new LinkMan(); linkMan.setLkm_name("老马"+i); customer.getLinkMans().add(linkMan); session.save(linkMan); } session.save(customer); transaction.commit(); } }

3. HQL查询

3.1 简单查询

@Test public void test2() {//HQL的简单查询 Session session = HibernateUtils.getCurrentSession(); Transaction transaction = session.beginTransaction(); // 简单查询 Query query = session.createQuery("from Customer"); List<Customer> list = query.list(); // sql中支持*号的写法:select * from cst_customer;但是在HQL中不支持*号的写法。 // Query query2 = session.createQuery("select * from from Customer");// 报错 // List<Customer> list2 = query.list(); for (Customer customer : list) { System.out.println(customer); } transaction.commit(); }

3.2 别名查询

@Test public void test3() {// 别名查询 Session session = HibernateUtils.getCurrentSession(); Transaction transaction = session.beginTransaction(); // 别名查询 // Query query = session.createQuery("from Customer c"); // List<Customer> list = query.list(); Query query = session.createQuery("select c from Customer c"); List<Customer> list = query.list(); for (Customer customer : list) { System.out.println(customer); } transaction.commit(); }

3.3 排序查询

@Test public void test5() {// 排序查询 Session session = HibernateUtils.getCurrentSession(); Transaction transaction = session.beginTransaction(); // 排序查询 // 默认情况 //List<Customer> list = session.createQuery("from Customer order by cust_id").list(); // 设置兼降序排序 升序使用asc 降序使用desc List<Customer> list = session.createQuery("from Customer order by cust_id desc").list(); for (Customer customer : list) { System.out.println(customer); } transaction.commit(); }

3.4 条件查询

@Test public void test4() {// 排序查询 Session session = HibernateUtils.getCurrentSession(); Transaction transaction = session.beginTransaction(); // 排序查询 // 1. 按位置绑定:根据参数的位置进行绑定 // 一个条件 // Query query = session.createQuery("from Customer where cust_name = ?"); // query.setParameter(0, "朱元璋"); // 多个条件 // Query query = session.createQuery("from Customer where cust_source = ? and cust_name like ?"); // query.setParameter(0, "朋友推荐"); // query.setParameter(1, "朱%"); // 2. 按名称绑定 Query query = session.createQuery("from Customer where cust_source = :aaa and cust_name like :bbb"); // 设置参数: query.setParameter("aaa", "朋友推荐"); query.setParameter("bbb", "朱%"); List<Customer> list = query.list(); for (Customer customer : list) { System.out.println(customer); } transaction.commit(); }

3.4 投影查询

投影查询:查询对象的某个或某些属性 @Test public void test6() {// 投影查询 Session session = HibernateUtils.getCurrentSession(); Transaction transaction = session.beginTransaction(); // 投影查询 // 单个属性 // List<Object> list = session.createQuery("select c.cust_name from Customer c").list(); // for (Object 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<Object[]> list = session.createQuery("select c.cust_name,c.cust_source from Customer c").list(); for (Object[] customer : list) { System.out.println(Arrays.toString(customer)); } transaction.commit(); }

3.5 分页查询

@Test public void test7() {// 分页查询 Session session = HibernateUtils.getCurrentSession(); Transaction transaction = session.beginTransaction(); // 分页查询 Query query = session.createQuery("from LinkMan"); query.setFirstResult(20); query.setMaxResults(5); List<LinkMan> list = query.list(); for (LinkMan linkMan : list) { System.out.println(linkMan); } transaction.commit(); }

3.6 分组统计查询

@Test public void test8() {// 分组统计查询 Session session = HibernateUtils.getCurrentSession(); Transaction transaction = session.beginTransaction(); // 分组统计查询 Object object = session.createQuery("select count(*) from Customer").uniqueResult(); System.out.println(object); //分组统计: Query query = session.createQuery("select cust_source,count(*) from Customer group by cust_source"); List<Object[]> list = query.list(); for (Object[] objects : list) { System.out.println(Arrays.toString(objects)); } transaction.commit(); }

3.7 HQL的多表查询

3.7.1 SQL的多表查询

连接查询 交叉连接:笛卡尔积内连接:innner join(inner可以省略) 隐式内连接:select * from A,B where A.id = B.aid;显式内连接:select * from A inner join B on A.id = B.aid;外连接:outer可以省略 左外连接:select * from A left outer join B on A.id = B.id;右外连接:select * from A right outerjoin B on A.id = B.id;子查询

3.7.2 HQL的多表查询

连接查询 交叉连接内连接: 显式内连接隐式内连接迫切内连接外连接: 左外连接右外连接迫切左外连接 @Test public void test7() { // 多表查询 Session session = HibernateUtils.getCurrentSession(); Transaction transaction = session.beginTransaction(); // SQL:select * from cst_customer c inner join cst_linkman l on c.cust_id = l.lkm_cust_id // HQL:内连接from Customer c inner join c.linkMans // 内连接得到的是一个数组 // List<Object[]> list = session.createQuery("from Customer c inner join c.linkMans").list(); // for (Object[] objects : list) { // System.out.println(Arrays.toString(objects)); // } // HQL:迫切内连接,其实就是在普通的内连接inner join后添加一个关键字fetch. // 迫切内连接的到的是一个对象,在Customer的toString中给定LinkMans可以得到全部字段 List<Customer> list2 = session.createQuery("select distinct c from Customer c inner join fetch c.linkMans").list(); for (Customer customer : list2) { System.out.println(customer); } transaction.commit(); }

4. QBC查询

4.1 简单查询

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

4.2 排序查询

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

4.3 分页查询

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

4.4 条件查询

@Test public void test4() { // 条件查询 Session session = HibernateUtils.getCurrentSession(); Transaction transaction = session.beginTransaction(); //获得Criteria的对象 Criteria criteria = session.createCriteria(Customer.class); // 设置条件 /* * = eq * > gt * >= ge * < lt * <= le * <> ne * like * in * and * or */ 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(); }

4.5 统计查询

@Test public void test5() { // 条件查询 Session session = HibernateUtils.getCurrentSession(); Transaction transaction = session.beginTransaction(); //获得Criteria的对象 Criteria criteria = session.createCriteria(Customer.class); /** * add :普通的条件。where后面条件 * addOrder:排序 * setProjecttion:聚合函数和group by having */ criteria.setProjection(Projections.rowCount()); Long num = (Long) criteria.uniqueResult(); System.out.println(num); transaction.commit(); }

4.6 离线条件查询(***)DetachedCriteria

离线条件查询在前台需要传递多个条件,用于筛选的时候很方便,可以不用在dao层拼接字符串

代码

@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 public void test1() { Session session = HibernateUtils.getCurrentSession(); Transaction transaction = session.beginTransaction(); // 调用的createSQLQuery,返回的值遍历后是数组形式的集合 // SQLQuery sqlQuery = session.createSQLQuery("select * from cst_customer"); // List<Object[]> list = sqlQuery.list(); // for (Object[] objects : list) { // System.out.println(Arrays.toString(objects)); // } SQLQuery sqlQuery = session.createSQLQuery("select * from cst_customer"); sqlQuery.addEntity(Customer.class); //封装到实体Customer中 List<Customer> list = sqlQuery.list(); for (Customer customer : list) { System.out.println(customer); } transaction.commit(); }

6. Hibernate的抓取策略

6.1 延迟加载的概述

6.1.1 什么是延迟加载

延迟加载:lazy(懒加载)。执行到该行代码的时候,不会发送语句去进行查询,在真正使用这个对象的属性的时候才会发送SQL语句进行查询。

6.1.2 延迟加载的分类

类级别的延迟加载

指的是通过load方法查询某个对象的时候,是否采用延迟加载。session.load(Customer.class,1L);类级别的延迟加载通过<class>上的lazy进行配置。让lazy失效的方法有: 将lazy设置为false将持久化类使用final修改Hibernate.ininialize()

关联级别的延迟加载

指的是在查询到某个对象的时候,查询其关联对象的时候,是否采用延迟加载。

Customer customer = session.get(Customer.class,1L); customer.getLinkMans(); //通过客户获得联系人的时候,联系人对象是否采用了延迟记载,称为关联级别的延迟加载。

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

6.2 抓取策略

Customer.hbm.xml

<set name="linkMans" fetch="select" lazy="true"> <!-- column多的一方的外键的名称 --> <key column="lkm_cust_id"></key> <!-- class:多的一方的类的全限定名 --> <one-to-many class="com.itzhouq.hibernate.domain.LinkMan"/> </set>

6.2.1 抓取策略概述

通过一个对象抓取到关联对象需要发送SQL语句,SQL语句如何发送,发送成什么样格式?这些可以通过策略进行配置。 通过<set>或者<many-to-one>上的fetch属性进行配置fetch和这些标签上的lazy如何设置,优化发送的SQL语句。

6.2.2 set上的fetch和lazy

fetch:抓取策略,控制SQL语句格式 select:默认值,发送普通的select语句,查询关联对象。join:发送一条迫切左外连接查询关联对象。subeselect:发送一条子查询查询其关联对象。lazy:延迟加载,控制查询关联对象的时候是否采用延迟加载 true:默认值,查询关联对象的时候,采用延迟加载false:查询关联对象的时候,不采用延迟加载extra:及其懒惰。实际开发过程中,一般采用默认值。如果有特殊需求,可能需要配置join。

6.2.3 many-to-one上的fetch和lazy

fetch:抓取策略,控制SQL语句格式 select:默认值,发送普通的select语句,查询关联对象。join:发送一条迫切左外连接lazy:延迟加载,控制查询关联对象的时候是否采用延迟加载 proxy:默认值,proxy具体的取值,取决于另一端的class上的lazy的值。false:查询关联对象,不采用延迟。no-proxy:不用在实际开发过程中,一般采用默认值。如果有特殊的需求,可能需要配置join。

6.2.4 批量抓取

一批关联对象一起抓取,betch-size。

package com.itzhouq.hibernate.demo; import java.util.List; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Test; import com.itzhouq.hibernate.domain.Customer; import com.itzhouq.hibernate.domain.LinkMan; import com.itzhouq.hibernate.utils.HibernateUtils; /* * 批量抓取测试 */ public class HibernateDemo4 { @Test public void test1() { // 获取客户的时候,批量抓取联系人 // 在Customer.hbm.xml中set上配置batch-size Session session = HibernateUtils.getCurrentSession(); Transaction transaction = session.beginTransaction(); List<Customer> list = session.createQuery("from Customer").list(); for (Customer customer : list) { System.out.println(customer.getCust_name()); for (LinkMan linkMan : customer.getLinkMans()) { System.out.println(linkMan.getLkm_name()); } } transaction.commit(); } } <set name="linkMans" batch-size="5"> <!-- column多的一方的外键的名称 --> <key column="lkm_cust_id"></key> <!-- class:多的一方的类的全限定名 --> <one-to-many class="com.itzhouq.hibernate.domain.LinkMan"/> </set>

转载于:https://www.cnblogs.com/itzhouq/p/hibernate04.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)