Hibernate框架详解(四)

Hibernate查询方式

  • (1)对象导航查询:根据id查询某个班级,再查询这个班级里面的所有学生
  • (2)OID查询:根据id查询某一条记录,返回对象
  • (3)HQL查询:利用Query对象,写HQL语句实现查询
  • (4)QBC查询:利用Criteria对象实现查询
  • (5)本地sql查询:利用SQLQuery对象,使用普通sql实现查询

 

对象导航查询

对象导航查询是根据已经加载的对象,查询到它的关联对象。

需求:查询某个班级中的所有学生,使用对象导航查询

实现:

	public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		
		Classes classes=session.get(Classes.class, 4);
		Set<Student> s=classes.getcStudents();
		for(Student student:s){
			System.out.println(student);
		}
		

		transaction.commit();
		session.close();
		sessionFactory.close();
	}

 

OID查询

OID查询主要指用session的get方法加载某条记录对应的对象

需求:根据id属性查询某个班级

实现:

	public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		
		Classes classes=session.get(Classes.class, 4);
		
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

 

HQL查询

  • HQL(Hibernate Query Language)是面向对象的查询语言,它和sql查询语言很相似
  • HQL与SQL的区别:SQL操作数据表和字段,HQL操作实体类和属性
  • 使用HQL查询操作步骤:第一步:创建Query对象,写HQL语句;第二步:调用Query对象里面的方法得到结果

常用的HQL语句:

  • 查询所有:from  实体类名称
  • 条件查询:from  实体类名称  where  实体类属性名称=? and 实体类属性名称=?

                         from  实体类名称  where  实体类属性名称  like ?

  • 排序查询:from  实体类名称  order by 实体类属性名称  asc/desc

 

(1)查询所有

需求:查询所有学生记录

步骤:第一步:创建Query对象,写HQL语句;第二步:调用Query对象中的list方法,得到结果

语句:from 实体类名称

实现:

public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		//创建Query对象
		Query query=session.createQuery("from Student");
		//调用list方法得到结果
		List<Student> list=query.list();
		//通过for循环遍历结果集
		for(Student stu : list){
			System.out.println(stu);
		}
		
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

 

(2)条件查询

语法:from  实体类名称  where  实体类属性名称=? and 实体类属性名称=?(条件查询)

          from  实体类名称  where  实体类属性名称  like ?(模糊查询)

实现:

public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		//创建Query对象
		//select * from Student where sid=? and sname=?;

		Query query = session.createQuery("from Student s where s.sid=? and s.sname=? ");
		//设置条件值,第一个参数表示位置(从0开始),第二个参数表示具体参数值
        
        //按位置绑定参数
		query.setParameter(0, 3);
		query.setParameter(1, "张三");

		//调用query对象中的list方法
		List<Student> list=query.list();

		for(Student s:list){
			System.out.println(s);
		}
		
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

模糊查询:

	public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		//创建Query对象
		Query query=session.createQuery("from Student s where s.sname like ?");
		//设置占位符的值
		query.setParameter(0, "%李%");
		//调用query对象的list方法
		List<Student> list=query.list();
		for(Student s:list){
			System.out.println(s.getSname());
		}
		
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

结果:

 

(3)排序查询

语法:from 实体类名称  order by 实体类属性名称  asc/desc

实现:

	public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		Query query=session.createQuery("from Student s order by s.sid desc ");
		List<Student> list=query.list();
		
		for(Student student : list){
			System.out.println(student.getSid()+"   :  "+student.getSname());
		}
		
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

结果:

 

(4)分页查询

  • 分页功能是很常见的功能,如果结果集数据量很大,比如几万行数据,放在一个页面显示的话数据量太大,不如分页显示,每次显示100条。
  • Mysql实现分页:使用关键字limit

  • 在HQL中实现分页:hibernate中的Query对象封装了setFirstResult和setMaxResults两个方法实现分页操作

效果图:

实现:

	public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		Query query=session.createQuery("from Student");
		
		//设置分页数据开始位置
		query.setFirstResult(0);
		//设置分页数据每页记录数
		query.setMaxResults(2);
		
		List<Student> list=query.list();
		for(Student student:list){
			System.out.println(student.getSid()+"   +   "+student.getSname());
		}
		
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

 

(5)投影查询

投影查询:查询部分字段的值

select sname from student;

语法:select  实体类属性名称1,实体类属性名称2  from 实体类名称

实现:

	public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		Query query=session.createQuery("select sname from Student");
		List<Object> list=query.list();
		for(Object obj:list){
			System.out.println(obj);
		}
		
		
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

结果:

 

(6)聚集函数使用

常用的聚集函数:count,sum,avg,max,min

需求:查询数据表中的记录数

语法:select count(*) from 实体类名称

实现:

	public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		Query query=session.createQuery("select count(*) from Student");
		Object obj=query.uniqueResult();
		System.out.println(obj);

		
		
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

结果:

 

QBC查询

  • QBC(Query By Criteria)是Hibernate提供的另一种查询对象的方式
  • 使用QBC查询,不需要使用语句,直接使用方法实现
  • QBC查询,使用Criteria对象,操作的是实体类和属性
  • 使用步骤:第一步:创建Criteria对象;第二步:调用相关方法得到结果

(1)查询所有

需求:查询所有学生记录

实现:

	public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		Criteria criteria=session.createCriteria(Student.class);
		List<Student> list=criteria.list();
		for(Student s:list){
			System.out.println(s.getSname());
		}

			
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

 

(2)条件查询

HQL的条件查询可以在HQL语句中设置条件值,但是QBC使用封装的方法设置条件值

QBC查询使用Restrictions对象编写查询条件,在Restictions类中提供了大量的静态方法来创建查询条件,如下所示:

需求:根据学id和姓名进行查询

实现:

public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		//创建Criteria对象
		Criteria criteria=session.createCriteria(Student.class);
		//使用Criteria对象中的add方法设置条件值
		criteria.add(Restrictions.eq("sid", 3));
		criteria.add(Restrictions.eq("sname","王富贵"));
		//调用list方法,得到结果
		List<Student> list=criteria.list();
		for(Student student:list){
			System.out.println(student.getSname());
		}
		
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

结果:

模糊查询:

需求:查询姓名中有“李”的所有学生

	public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		//创建Criteria对象
		Criteria criteria=session.createCriteria(Student.class);
		//使用Criteria对象中的add方法设置条件值
		criteria.add(Restrictions.like("sname", "%李%"));

		//调用list方法,得到结果
		List<Student> list=criteria.list();
		for(Student student:list){
			System.out.println(student.getSname());
		}
		
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

结果:

 

(3)排序查询

需求:按照学生id,倒序查询所有学生

实现:

	public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		//创建Criteria对象
		Criteria criteria=session.createCriteria(Student.class);
		//设置对哪个属性进行排序,并设置排序方式
		criteria.addOrder(Order.desc("sid"));

		//调用list方法,得到结果
		List<Student> list=criteria.list();
		for(Student student:list){
			System.out.println(student.getSname());
		}
		
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

结果:

 

(4)分页查询

在QBC中实现分页:hibernate中的Criteria对象封装了setFirstResult和setMaxResults两个方法实现分页操作

需求:分页查询,从0开始,每页显示两个。开始位置计算公式: (当前页-1*每页记录数

实现:

	public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		//创建Criteria对象
		Criteria criteria=session.createCriteria(Student.class);
		//设置开始位置
		criteria.setFirstResult(0);
		//设置每页显示记录数
		criteria.setMaxResults(2);

		//调用list方法,得到结果
		List<Student> list=criteria.list();
		for(Student student:list){
			System.out.println(student.getSname());
		}
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

结果:

 

(5)统计查询

需求:统计学生表中的记录数

实现:

	public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		//创建Criteria对象
		Criteria criteria=session.createCriteria(Student.class);
		//设置操作(设置统计功能)
		criteria.setProjection(Projections.rowCount());
		//调用uniqueResult方法得到结果
		Object object=criteria.uniqueResult();
		System.out.println(object);


		transaction.commit();
		session.close();
		sessionFactory.close();
	}

结果:

 

(6)离线查询

  • 离线查询使用DetachedCriteria对象,它可以脱离session来使用。而Criteria对象必须由session对象来创建,即必须现有session才可以生成Criteria对象,而DetachedCriteria对象可以在其他层对条件进行封装。
  • 在以后的SSH整合中,会经常使用DetachedCriteria对象,其主要优点是做一些比较复杂的条件查询时,往往会在web层向service层传递很多参数,业务层也会将这些参数传递给dao层,最后在dao层中拼接SQL完成查询。有了离线查询以后,可以直接在web层将数据封装好,传递到service层,再传递到dao层完成查询。

实现:

	public void testDemo(){
		Configuration cfg=new Configuration();
		cfg.configure();
		
		SessionFactory sessionFactory=cfg.buildSessionFactory();
		Session session=sessionFactory.openSession();
		Transaction transaction=session.beginTransaction();
		
		DetachedCriteria detachedCriteria=DetachedCriteria.forClass(Student.class);
		Criteria criteria=detachedCriteria.getExecutableCriteria(session);
		List<Student> list=criteria.list();
		for(Student student : list){
			System.out.println(student.getSname());
		}

		transaction.commit();
		session.close();
		sessionFactory.close();
	}

结果:

 

 

HQL多表查询

(1)Mysql中多表查询

内连接

 

左外连接

右外连接

参考:https://blog.csdn.net/plg17/article/details/78758593

 

(2)HQL实现多表查询

HQL多表查询:

  •  内连接
  •  左外连接
  •  右外连接
  •  迫切内连接
  •  迫切左外连接

HQL内连接

1 内连接查询hql语句写法:以客户和联系人为例

1from  Customer  c  inner  join  c.setLinkMan

返回listlist里面每部分是数组形式

2 演示迫切内连接

1)迫切内连接和内连接底层实现一样的

2)区别:使用内连接返回list中每部分是数组,迫切内连接返回list每部分是对象

3hql语句写法

- from  Customer  c  inner  join  fetch  c.setLinkMan

 

 

HQL左外连接

1 左外连接hql语句:

1from  Customer  c  left  outer  join  c.setLinkMan

2)迫切左外连接from  Customer  c  left  outer  join  fetch  c.setLinkMan

 

2 左外连接返回list中每部分是数组,迫切左外连接返回list每部分是对象

1 右外连接hql语句:

1from  Customer  c  right  outer  join  c.setLinkMan

 

 

Hibernate检索策略

(1)hibernate检索策略分为两类:

立即查询:根据id查询,调用get方法,一调用get方法马上发送语句查询数据库

结果:

 

延迟查询:根据id查询,调用load方法,调用load方法不会马上发送语句查询数据,只有得到对象里面的其他值的时候才会发送语句查询数据库

结果:

 

(2)延迟查询分为两类:

类级别延迟:根据id查询返回实体类对象,调用load方法,不会马上发送语句。

结果:

 

关联级别延迟:查询某个班级,再查询这个班级中的所有学生。查询这个班级中的所有学生是否需要延迟,这个过程称为关联级别延迟。

结果:

关联级别延迟操作

(1)在映射文件中进行配置实现

根据班级得到所有学生,在班级映射文件中进行配置

(2)在set标签上使用属性

fetch:值select(默认使用)

lazy:

  • --true:延迟(默认)
  • --false:不延迟
  • --extra:极其延迟

实现:lazy属性值为true,即开启延迟

实现:lazy属性值为false,即关闭延迟

调用get方法之后,直接发送两条sql语句。

实现:lazy属性值为extra,极其延迟/极其懒惰

要什么值给什么值(查询set集合数量,只查询count)

 

 

Hibernate批量抓取

需求:查询所有的班级,返回list集合,遍历list集合,得到每个班级,得到每个班级的所有学生

实现:

问题:上面操作代码,发送多条sql语句,性能不高

解决:批量抓取

在班级的映射文件中,set标签里配置batch-size属性,值越大,发送语句越少。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值