hibernate笔记4——hibernate查询方式、抓取策略

0 总述

0.1 写在前面 碎碎念

  上午拆了笔记本清了一下灰,重新涂了硅脂。好像是有稍微快一点了的错觉,今天肯定是学不完了…一个hibernate原本四天的课愣是被我看了八天,我也真的太懒了。晚上要上团日、做网络营销的PPT、给爸爸打电话。
  不说了,冲冲冲。
  3/31/2019

0.1 地图

在这里插入图片描述

1 hibernate的查询方式

hibernate中提供了五种查询方式。

1.1 OID查询

根据对象的OID(主键)进项检索。使用get(Class c,Long long)&load(Class c,Long long)的方法。

Customer c1 = session.get(Customer.class,3l);
Customer c2 = session.load(Customer.class,4l);

1.2 对象导航查询

hibernate根据已经查询到的对象,获得其关联的对象的一种查询方式。

LinkMan lm1 = session.get(LinkMan.class,3l);
Customer c1 = lm.getCustomer();

Customer c2 = session.get(Customer.class,2l);
Set<LinkMan> linkMans = c2.getLinkMans();

1.3 HQL检索(重要)

HibernateQueryLanguage:面向对象的查询语言,语法类似SQL。通过session.createQuery(),用于接收一个HQL进行查询。

1.3.1 初始化数据

1.3.2 HQL简单查询

		Query q = s.createQuery("from Customer");
		List<Customer> list = q.list();
		//sql中支持*写法:select * from cst_customer,HQL中不支持*
		
		for (Customer customer : list) {
			System.out.println(customer);
		}
  • 别名的查询
		Query q = s.createQuery("select c from Customer c");
		List<Customer> list = q.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}

1.3.3 HQL排序查询

		//升序asc,降序desc
		List<Customer> list = session.createQuery("select c from Customer c order by cust_id desc").list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		tx.commit();

1.3.4 HQL条件查询

1.3.4.1 按位置绑定
	Query q= session.createQuery("from Customer where cust_name like ?");
	q.setParameter(0, "5%");
	List<Customer> list = q.list();
1.3.4.2 按名称绑定
	Query q = session.createQuery("from Customer where cust_name like :aaa");	//冒号后面没有空格
	q.setParameter("aaa","5%");
	List<Customer> list = q.list();

1.3.5 HQL投影查询

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

	//投影查询
	/*List<Object[]> list = s.createQuery("select c.cust_id,c.cust_name from Customer c").list();
	List<Object> list1 = s.createQuery("select c.cust_name from Customer c").list();
	for (Object[] objects : list) {
		System.out.println(Arrays.toString(objects));
	}
	for (Object object : list1) {
		System.out.println(object);
	}*/
	//查询多个属性并进行封装
	List<Customer> list = s.createQuery("select new Customer(cust_name,cust_source) from Customer").list();
	for (Customer customer : list) {
		System.out.println(customer);
	}

1.3.6HQL分页查询

	q.setFirstResult(0);
	q.setMaxResults(10);

1.3.7 HQL分组统计查询

	Query q = session.createQuery("select c.cust_source,count(*) from Customer c group by c.cust_source having count(*) >= 2");
	List<Object[]> list = q.list();
	for (Object[] objects : list) {
		System.out.println(Arrays.toString(objects));

1.3.8 HQL 多表查询(未学到)

  • SQL多表查询
    • 连接查询
      • 交叉连接(不常用)笛卡尔积 select * from A,B;
      • 内连接 inner join(inner 可以省略),查到两个表的交集
        • 隐式内连接
          • select * from A,B where A.id = B.id;
        • 显式内连接,语句中有inner join
          • select * from A inner join B on A.id=B.id;
      • 外连接 outer join
        • 左外连接,left outer join(outer可以省略),查到左边表的全部部分,和右边表的公共部分
          • select * from A left outer join B on A.id=B.idl;
        • 右外连接,right outer join
          • select * from A right outer join B on A.id=B.id;
    • 子查询(SQL嵌套)
  • HQL 多表查询
    • 连接查询
      • 交叉连接
      • 内连接
        • 隐式内连接
        • 显式内连接
          • List<Object[]> list = session.createQuery("from Customer c inner join c.linkMans").list();
        • 迫切内连接
          • 迫切内连接 在普通内连接的inner join后添加关键字fetch
          • fetch通知hibernate将另一个对象的数据封装到该对象中
          • List<Customer> list = session.createQuery("select distict c from Customer c inner join fetch c.linkMans").list();
      • 外连接
      • 左外连接
      • 右外连接
      • 迫切左外连接

1.4 QBC检索(重要)

1.4.1 简述

Query By Criteria :条件查询,面向对象化的查询方式。

1.4.2 简单查询

	Criteria criteria = session.createCriteria(Customer.class);
	List<Customer> list = criteria.list();

1.4.3 排序查询

	Criteria criteria = session.createCriteria(Customer.class);
	criteria.addOrder(Order.desc("cust_id"));
	List<Customer> list = criteria.list();

1.4.4 分页查询

	Criteria criteria = session.createCriteria(LinkMan.class);
	criteria.setFirstResult(0);
	criteria.setMaxResults(10);
	List<LinkMan> list = criteria.list();

1.4.5 条件查询

	Criteria criteria = session.createCriteria(Customer.class);
	criteria.add(Restrictions.eq("cust_source","chichi"));
	List<Customer> list = criteria.list();

1.4.6 统计分组查询

	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	Criteria criteria = session.createCriteria(Customer.class);
	criteria.setProjection(Projections.rowCount());
	Object o = criteria.uniqueResult();

1.4.7 离线条件查询(SSH)DetachedCriteria

离线:脱离Session使用。

	DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
	dc.add(Restrictions.eq("cust_source", "chichi"));
	
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	Criteria c = dc.getExecutableCriteria(session);
	List<Customer> list = c.list();

1.5 SQL检索

使用sql基本语句进行查询

	SQLQuery q = session.createSQLQuery("select * from cst_customer");
	q.addEntity(Customer.class);		//创建Customer实体
	List<Customer> list = q.list();

2 HQL 查询语句总结

3 Hibernate的抓取策略(优化手段)

3.1 延迟加载的概述

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

3.2 延迟加载的分类

  • 类级别的延迟加载
    • 指的是通过load方法查询某个对象的时候,是否采用延迟。
    • 在xxx.hbm.xml的<class>标签上配置的lazy=“true/false”,true默认,false失效。
    • Session.load(Customer.class,1l);
  • 关联级别的延迟加载
    • 指的是在查询到某个对象的时候,查询其关联对象的时候,是否会采用延迟加载。
    • 在关联对象的hbm.xml的<set><many-to-one>标签上配置lazy=“true/false”,true默认,false失效。
    • Customer c = Session.get(Customer.class,1l);
    • c.getLinkMans(); //通过 客户获得联系人的时候,联系人对象是否采用了延迟加载。
  • 抓起策略往往会和关联级别的延迟加载一起使用,优化语句。

3.3 抓取策略

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

3.3.1 <set>上的fetch和lazy

  • fetch:抓取策略,控制SQL语句格式
    • select(默认),发送普通的select语句,查询关联对象
    • join,发送一条迫切左外连接查询关联对象
    • subselect,发送一条子查询语句查询其关联对象
  • lazy:延迟加载,控制查询关联对象的时候是否采用延迟
    • true(默认),查询关联对象时采用延迟加载
    • false,不采用延迟加载
    • extra,极其懒惰
3.3.1.1 fetch=“select” lazy=“true”

发送普通SQL语句查询,关联对象采用延迟加载(关联对象被调用的时候才开始加载)。

3.3.1.2 fetch=“select” lazy=“false”

发送普通SQL语句查询,关联对象不采用延迟加载(关联对象在加载对象时已经加载)。

3.3.1.3 fetch=“select” lazy=“extra”

发送普通SQL语句查询,关联对象采用延迟加载(调用关联对象的某个属性的时候才发送sql语句查询该属性)。

3.3.1.4 fetch=“join” lazy失效

发送迫切左外连接SQL语句查询

3.3.1.5 fetch=“subselect” lazy=“true”

在调用对象时:发送查询所有客户的sql语句,在使用关联对象时:发送一条子查询。

3.3.1.5 fetch=“subselect” lazy=false"

在调用对象时:发送查询所有客户的sql语句,并且发送一条子查询,查询所有关联对象。

3.3.1.3 fetch=“select” lazy=“extra”

在调用对象时:发送查询所有客户的sql语句,关联对象采用延迟加载(调用关联对象的某个属性的时候才发送sql子查询语句查询该属性)。

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

  • fetch:抓取策略,控制SQL语句格式
    • select(默认),发送普通的select语句,查询关联对象
    • join,发送一条迫切左外连接查询关联对象
  • lazy:延迟加载,控制查询关联对象的时候是否采用延迟
    • proxy(默认),取决于关联对象的<class>标签上的lazy属性的值
    • false,查询关联对象不采用延迟
    • no-proxy(不会使用

3.3.3 批量抓取

一批关联对象一起抓取,添加属性batch-size=”一次抓几个对象“。

  • 批量抓取联系人,在Customer.hbm.xml中的set标签中添加属性batch-size=”一次抓几个LinkMan对象“
  • 批量抓取客户,在Customer.hbm.xml中的class标签中添加属性batch-size=”一次抓几个Customer对象“
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值