Hibernate的查询&抓取策略

目录

一.Hibernate的查询的方式

1.1 OID查询

1.2 对象导航检索

1.3 HQL检索

1.3.1 初始化一些数据

1.3.2 HQL的简单查询

1.3.3 HQL的别名查询

1.3.4 HQL的排序查询

1.3.5 HQL的条件查询

1.3.6 HQL的投影查询

1.3.7 HQL的分页查询

1.3.8 HQL的分组统计查询

1.3.9 HQL的多表查询

1.4 QBC检索

1.4.1 简单查询

1.4.2 排序查询

1.4.3 分页查询

1.4.4 条件查询

1.4.5 统计查询

1.4.6 离线条件查询(SSH)---DetachedCriteria

1.5 SQL检索

二.Hibernate的抓取策略

2.1 延迟加载

2.1.1 什么是延迟加载

2.1.2 延迟加载的分类

2.2 抓取策略

2.2.1 抓取策略的概述

2.2.2 上的fetch和lazy

2.2.3 上的fetch和lazy

2.3 批量抓取

2.3.1 什么是批量抓取

2.3.2 测试批量抓取


一.Hibernate的查询的方式

Hibernate共提供了五种查询方式。

1.1 OID查询

OID检索:Hibernate根据对象的OID(主键)进行检索

  • 使用get方法
Customer customer = session.get(Customer.class,1l);
  • 使用load方法
Customer customer = session.load(Customer.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.3.1 初始化一些数据

	/**
	 * 初始化数据
	 */
	public void demo1() {
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();

		// 创建一个客户
		Customer customer = new Customer();
		customer.setCust_name("李向文");

		for (int i = 1; i <= 10; i++) {
			LinkMan linkMan = new LinkMan();
			linkMan.setLkm_name("王东" + i);
			linkMan.setCustomer(customer);

			customer.getLinkMans().add(linkMan);

			session.save(linkMan);
		}
		session.save(customer);

		tx.commit();
	}

1.3.2 HQL的简单查询

	/**
	 * HQL的简单查询
	 */
	public void demo2() {
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();
		// 简单的查询
		Query query = session.createQuery("from Customer");
		List<Customer> list = query.list();

		// sql中支持*号的写法:select * from cst_customer; 但是在HQL中不支持*号的写法。
		/*
		 * Query query = session.createQuery("select * from Customer");// 报错
		 * List<Customer> list = query.list();
		 */

		for (Customer customer : list) {
			System.out.println(customer);
		}
		tx.commit();
	}

1.3.3 HQL的别名查询

	/**
	 * 别名查询
	 */
	public void demo3() {
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = 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);
		}
		tx.commit();
	}

1.3.4 HQL的排序查询

	/**
	 * 排序查询
	 */
	public void demo4() {
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = 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);
		}
		tx.commit();
	}

1.3.5 HQL的条件查询

	/**
	 * 条件查询
	 */
	public void demo5() {
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();
		// 条件的查询
		// 一、按位置绑定:根据参数的位置进行绑定。
		// 一个条件
		/*
		 * Query query = session.createQuery("from Customer where cust_name = ?" );
		 * query.setParameter(0, "李兵"); 
		 * List<Customer> list = query.list();
		 */

		// 多个条件
		/*
		 * Query query = session.createQuery(
		 * "from Customer where cust_source = ? and cust_name like ?");
		 * query.setParameter(0, "小广告"); 
		 * query.setParameter(1, "李%");
		 * List<Customer> list = query.list();
		 */

		// 二、按名称绑定
		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);
		}
		tx.commit();
	}

1.3.6 HQL的投影查询

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

	/**
	 * 投影查询
	 */
	public void demo6() {
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();

		// 投影查询
		// 单个属性
		/*
		 * List<Object> list = session.createQuery(
		 * "select c.cust_name from Customer c").list(); 
		 * for (Object object :list) 
		 *     { System.out.println(object); 
		 * }
		 */

		// 多个属性:
		/*
		 * 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> list = session.createQuery("select new Customer(cust_name,cust_source) from Customer").list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		tx.commit();
	}

1.3.7 HQL的分页查询

	/**
	 * 分页查询
	 */
	public void demo7() {
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();

		// 分页查询
		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);
		}
		tx.commit();
	}

1.3.8 HQL的分组统计查询

	/**
	 * 分组统计查询
	 */
	public void demo8() {
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();

		// 聚合函数的使用:count(),max(),min(),avg(),sum()
		Object object = session.createQuery("select count(*) from Customer").uniqueResult();
		System.out.println(object);
		// 分组统计:
		List<Object[]> list = session.createQuery("select cust_source,count(*) from Customer group by cust_source")
				.list();
		for (Object[] objects : list) {
			System.out.println(Arrays.toString(objects));
		}
		tx.commit();
	}

1.3.9 HQL的多表查询

SQL的多表查询

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

 

	/**
	 * HQL的多表查询
	 */
	public void demo9() {
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = 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. from Customer c inner
		// join fetch c.linkMans
		List<Customer> list = session.createQuery("select distinct c from Customer c inner join fetch c.linkMans")
				.list();// 通知hibernate,将另一个对象的数据封装到该对象中

		for (Customer customer : list) {
			System.out.println(customer);
		}
		tx.commit();
	}

1.4 QBC检索

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

1.4.1 简单查询

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

1.4.2 排序查询

	/**
	 * 排序查询
	 */
	public void demo2(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = 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);
		}
		
		tx.commit();
	}

1.4.3 分页查询

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

1.4.4 条件查询

	/**
	 * 条件查询
	 */
	public void demo4(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();
		
		// 条件查询
		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.or(Restrictions.like("cust_name", "李%")));
		criteria.add(Restrictions.like("cust_name", "李%"));
		List<Customer> list = criteria.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		tx.commit();
	}

1.4.5 统计查询

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

1.4.6 离线条件查询(SSH)---DetachedCriteria

	/**
	 * 离线条件查询
	 */
	public void demo6(){
		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();
	}

1.5 SQL检索

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

@Test
	public void demo1(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();
		
		/*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);
		List<Customer> list = sqlQuery.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		tx.commit();
	}

二.Hibernate的抓取策略

2.1 延迟加载

2.1.1 什么是延迟加载

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

2.1.2 延迟加载的分类

  • 类级别的延迟加载
    • 指的是通过load方法查询某个对象的时候,是否采用延迟。session.load(Customer.class,1l);
    • 类级别延迟加载通过<class>上的lazy进行配置,如果让lazy失效
      • 将lazy设置为false
      • 将持久化类使用final修饰
      • Hibernate. Initialize()
  • 关联级别的延迟加载
    • 指的是在查询到某个对象的时候,查询其关联的对象的时候,是否采用延迟加载。
  • Customer customer = session.get(Customer.class,1l);
  • customer.getLinkMans();----通过客户获得联系人的时候,联系人对象是否采用了延迟加载,称为是关联级别的延迟。
  • 抓取策略往往会和关联级别的延迟加载一起使用,优化语句。

2.2 抓取策略

2.2.1 抓取策略的概述

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

2.2.2 <set>上的fetch和lazy

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

2.2.3 <many-to-one>上的fetch和lazy

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

2.3 批量抓取

2.3.1 什么是批量抓取

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

2.3.2 测试批量抓取

/**
 * 批量抓取
 *
 */
public class HibernateDemo4 {

	@SuppressWarnings("unchecked")
	@Test
	/**
	 * 获取客户的时候,批量抓取联系人
	 * 在Customer.hbm.xml中set上配置batch-size
	 */
	public void demo1(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = 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());
			}
		}
		tx.commit();
	}
	
	@SuppressWarnings("unchecked")
	@Test
	/**
	 * 获取联系人的时候,批量抓取客户
	 * * 在Customer.hbm.xml中<class>上配置
	 */
	public void demo2(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();
		
		List<LinkMan> list = session.createQuery("from LinkMan").list();
		for (LinkMan linkMan : list) {
			System.out.println(linkMan.getLkm_name());
			System.out.println(linkMan.getCustomer().getCust_name());
		}
		tx.commit();
	}
}

猜你喜欢

转载自blog.csdn.net/qq_30162219/article/details/86659731