Hibernate框架–学习笔记(下):hibernate的查询方式、多表查询、检索策略、批量抓取

Hibernate框架–学习笔记(下):hibernate的查询方式、多表查询、检索策略、批量抓取

 

一、hibernate的查询方式:

主要有五种:对象导航查询;OID查询;hql查询;QBC查询;本地sql查询。

 

1、对象导航查询:根据id查询某个客户,再查询这个客户里面所有的联系人。

2、OID查询:根据id查询某一条记录,返回对象。

	//演示 OID查询,对象导航查询
	//OID查询:根据id查询,返回一个对象
	//对象导航查询:根据id查询客户,在根据这个客户查询所有的联系人
	@Test
	public void TextSelect1(){
		
		SessionFactory sessionfactory=null;
		Session session=null;
		Transaction tx=null;
		
		try{
			sessionfactory=HibernateUtil.getSessionFactory();
			session=sessionfactory.openSession();
			tx=session.beginTransaction();
			
			Customer customer=session.get(Customer.class, 1);
			Set<LinkMan> linkman=customer.getSetLinkMan();
			
			System.out.println(linkman.size());
			tx.commit();
		}catch(Exception e)
		{
			e.printStackTrace();
			tx.rollback();
		}
		finally{
			//session.close();
			//sessionfactory.close();
		}
	}

 

3、hql查询:Query对象,写hql语句实现查询:

①查询所有:

        //1.查询所有数据:from 实体类名称
	@Test
	public void Texthql1(){
		
		SessionFactory sessionfactory=null;
		Session session=null;
		Transaction tx=null;
		
		try{
			sessionfactory=HibernateUtil.getSessionFactory();
			session=sessionfactory.openSession();
			tx=session.beginTransaction();
				
			Query query=session.createQuery("from Customer");
			List<Customer> list=query.list();
			
			for(Customer customer:list)
			{
				System.out.println(customer.getCid()+"::"+customer.getCustName());
			}
			
			tx.commit();
		}
		catch(Exception e)
		{
			e.printStackTrace();
			tx.rollback();
		}
		finally{
			session.close();
			sessionfactory.close();
		}
	}        

②条件查询:

	//2.条件查询
	//2.1from 实体类名称  where 实体类属性=? and 实体类属性=?
	@Test
	public void Texthql2(){
		
		SessionFactory sessionfactory=null;
		Session session=null;
		Transaction tx=null;
		
		try{
			sessionfactory=HibernateUtil.getSessionFactory();
			session=sessionfactory.openSession();
			tx=session.beginTransaction();
			
			//创建Query对象
			Query query=session.createQuery("from Customer c where c.cid=? and c.custName=?");
			//给问号设值
			//setParamer方法两个参数:第一个表示?的位置,从0开始;第二个表示具体参数值
			query.setParameter(0, 2);
			query.setParameter(1, "腾讯");
			
			List<Customer> list=query.list();
			for(Customer customer:list)
			{
				System.out.println(customer.getCid()+"::"+customer.getCustName());
			}
			
			tx.commit();
		}
		catch(Exception e)
		{
			e.printStackTrace();
			tx.rollback();
		}
		finally{
			session.close();
			sessionfactory.close();
		}
	}
        //2.2模糊查询:from 实体类名称  like 实体类属性=?
	@Test
	public void Texthql22(){
		
		SessionFactory sessionfactory=null;
		Session session=null;
		Transaction tx=null;
		
		try{
			sessionfactory=HibernateUtil.getSessionFactory();
			session=sessionfactory.openSession();
			tx=session.beginTransaction();
			
			//创建Query对象
			Query query=session.createQuery("from Customer c where c.custName like ?");
			//给问号设值
			//setParamer方法两个参数:第一个表示?的位置,从0开始;第二个表示具体参数值
			query.setParameter(0, "%度%");
			
			List<Customer> list=query.list();
			for(Customer customer:list)
			{
				System.out.println(customer.getCid()+"::"+customer.getCustName());
			}
			
			tx.commit();
		}
		catch(Exception e)
		{
			e.printStackTrace();
			tx.rollback();
		}
		finally{
			session.close();
			sessionfactory.close();
		}
	}

③排序查询:

	//排序查询:from 实体类名称 order by 实体类属性名称 asc/desc
	@Test
	public void Texthql3(){
		
		SessionFactory sessionfactory=null;
		Session session=null;
		Transaction tx=null;
		
		try{
			sessionfactory=HibernateUtil.getSessionFactory();
			session=sessionfactory.openSession();
			tx=session.beginTransaction();
			
			//创建Query对象
			Query query=session.createQuery("from Customer order by cid asc");
			//Query query=session.createQuery("from Customer order by cid desc");
			
			List<Customer> list=query.list();
			
			for(Customer customer:list){
				System.out.println(customer.getCid()+"::"+customer.getCustName());
			}
			
			tx.commit();
		}
		catch(Exception e)
		{
			e.printStackTrace();
			tx.rollback();
		}
		finally{
			session.close();
			sessionfactory.close();
		}
	}

④分页查询:

开始位置=(当前页-1)*每页记录数

        //mysql数据库:
	//分页查询:先查询所有数据,在使用Query封装好的两个方法:
	//设置开始位置:query.setFirstResult();
	//设置每页数据个数query.setMaxResults();
	@Test
	public void Texthql4(){
		
		SessionFactory sessionfactory=null;
		Session session=null;
		Transaction tx=null;
		
		try{
			sessionfactory=HibernateUtil.getSessionFactory();
			session=sessionfactory.openSession();
			tx=session.beginTransaction();
			
			//创建Query对象
			Query query=session.createQuery("from Customer");
			query.setFirstResult(0);//设置开始位置
			query.setMaxResults(3);//设置每页数据个数
					
			List<Customer> list=query.list();
			for(Customer customer:list){
				System.out.println(customer.getCid()+"::"+customer.getCustName());
			}
					
			tx.commit();
		}catch(Exception e){
			e.printStackTrace();
			tx.rollback();
		}
		finally{
			session.close();
			sessionfactory.close();
		}
	}

⑤投影查询:

	//投影查询:查询不是所有字段值,而是部分字段的值
	//写法:select 实体类属性名称1,实体类属性名车2 from 实体类
	//select后面不能写*,不支持
	@Test
	public void Texthql5(){
		
		SessionFactory sessionfactory=null;
		Session session=null;
		Transaction tx=null;
		
		try{
			sessionfactory=HibernateUtil.getSessionFactory();
			session=sessionfactory.openSession();
			tx=session.beginTransaction();
			
			//创建Query对象
			Query query=session.createQuery("select custName from Customer");

			List<Customer> list=query.list();
			for(Object object:list){
				System.out.println(object);
			}
					
			tx.commit();
		}catch(Exception e){
			e.printStackTrace();
			tx.rollback();
		}
		finally{
			session.close();
			sessionfactory.close();
		}
	}

⑥聚集函数使用:

	//聚集函数:
	//count、sum、avg、max、min
	@Test
	public void Texthql6(){
		SessionFactory sessionfactory=null;
		Session session=null;
		Transaction tx=null;
		
		try{
			sessionfactory=HibernateUtil.getSessionFactory();
			session=sessionfactory.openSession();
			tx=session.beginTransaction();
			
			//1.创建Query对象
			Query query=session.createQuery("select count(*) from Customer");

			//2.调用方法得到结果
			//也可以用list():
			Object obj = query.uniqueResult();
			System.out.println(obj);
			
			//转成Int类型:首先把object变成long类型,再变成int类型
			//不能直接变int,会抛出异常
			Long lobj=(Long)obj;
			int count=lobj.intValue();
			System.out.println(count);
			
			tx.commit();
		}catch(Exception e){
			e.printStackTrace();
			tx.rollback();
		}
		finally{
			session.close();
			sessionfactory.close();
		}
	}

 

4、QBC查询:

使用hql查询需要写hql语句实现,但使用qbc时候,不需要写语句,使用方法实现;

使用qbc时候,操作实体类和属性;使用qbc的时候,使用Criteria对象;

Criteria对象:

https://gitee.com/mush2016/box/raw/mg/gm/2021/09/81bbd1b9-86f4-4a95-ac0d-87fbd0f34c17-1632592987584.jpg

①查询所有:

        //查询所有
	@Test
	public void TextQBC1(){
		
		SessionFactory sessionfactory=null;
		Session session=null;
		Transaction tx=null;
		
		try{
			sessionfactory=HibernateUtil.getSessionFactory();
			session=sessionfactory.openSession();
			tx=session.beginTransaction();
				
			Criteria criteria=session.createCriteria(Customer.class);
			List<Customer> list=criteria.list();
			for(Customer customer:list){
				System.out.println(customer.getCid()+"::"+customer.getCustName());
			}
			
			tx.commit();
		}catch(Exception e){
			e.printStackTrace();
			tx.rollback();
		}
		finally{
			session.close();
			sessionfactory.close();
		}
	}

②条件查询:

//条件查询
	@Test
	public void TextQBC2(){
		
		SessionFactory sessionfactory=null;
		Session session=null;
		Transaction tx=null;
		
		try{
			sessionfactory=HibernateUtil.getSessionFactory();
			session=sessionfactory.openSession();
			tx=session.beginTransaction();
			
			//1.创建对象
			Criteria criteria=session.createCriteria(Customer.class);
			
			//使用Criteria对象里面的方法设置条件值:
			//首先使用add方法,表示设置条件值
			//在add方法里面使用类的方法实现条件设置
			//类似于cid=?
			//criteria.add(Restrictions.eq("cid",4));
			//criteria.add(Restrictions.eq("custName","百度"));
			criteria.add(Restrictions.like("custName","%歌%"));
			List<Customer> list=criteria.list();
			
			for(Customer customer:list){
				System.out.println(customer.getCid()+"::"+customer.getCustName());
			}
			tx.commit();
		}catch(Exception e){
			e.printStackTrace();
			tx.rollback();
		}finally
		{
			session.close();
			sessionfactory.close();
		}
	}

③排序查询:

        //排序查询:
	@Test
	public void TextQBC3(){
		
		SessionFactory sessionfactory=null;
		Session session=null;
		Transaction tx=null;
		
		try{
			sessionfactory=HibernateUtil.getSessionFactory();
			session=sessionfactory.openSession();
			tx=session.beginTransaction();
			
			Criteria criteria=session.createCriteria(Customer.class);
			
			//升序:
			//criteria.addOrder(Order.asc("cid"));
			//降序:
			criteria.addOrder(Order.desc("cid"));
			List<Customer> list=criteria.list();
			
			for(Customer customer:list){
				System.out.println(customer.getCid()+"::"+customer.getCustName());
			}
			tx.commit();
		}catch(Exception e){
			e.printStackTrace();
			tx.rollback();
		}
		finally{
			session.close();
			sessionfactory.close();
		}
	}

④分页查询:

开始位置=(当前页-1)*每页记录数

        //mysql数据库的分页查询:
	@Test
	public void TextQBC4(){
		
		SessionFactory sessionfactory=null;
		Session session=null;
		Transaction tx=null;
		
		try{
			sessionfactory=HibernateUtil.getSessionFactory();
			session=sessionfactory.openSession();
			tx=session.beginTransaction();
			
			Criteria criteria=session.createCriteria(Customer.class);
			
			//设置开始位置,最前面的位置是0:
			criteria.setFirstResult(3);
			//设置每页显示的数据:
			criteria.setMaxResults(3);
			
			List<Customer> list=criteria.list();
			for(Customer customer:list){
				System.out.println(customer.getCid()+"::"+customer.getCustName());
			}
			tx.commit();
		}catch(Exception e){
			e.printStackTrace();
			tx.rollback();
		}
		finally{
			session.close();
			sessionfactory.close();
		}
	}

⑤统计查询:

	//统计查询
	@Test
	public void TextQBC5(){
		
		SessionFactory sessionfactory=null;
		Session session=null;
		Transaction tx=null;
		
		try{
			sessionfactory=HibernateUtil.getSessionFactory();
			session=sessionfactory.openSession();
			tx=session.beginTransaction();
			
			Criteria criteria=session.createCriteria(Customer.class);

			criteria.setProjection(Projections.rowCount());
			
			Object object=criteria.uniqueResult();
			//将Object转成int类型:先转Long类型再转int类型
			Long lobj=(Long)object;
			int count=lobj.intValue();
			
			System.out.println(count);
			
			tx.commit();
		}catch(Exception e){
			e.printStackTrace();
			tx.rollback();
		}
		finally{
			session.close();
			sessionfactory.close();
		}
	}

⑥离线查询:

        //离线查询:一开始不使用session
	@Test
	public void TextQBC6(){
		
		SessionFactory sessionfactory=null;
		Session session=null;
		Transaction tx=null;
		
		try{
			sessionfactory=HibernateUtil.getSessionFactory();
			session=sessionfactory.openSession();
			tx=session.beginTransaction();
			
			//Criteria criteria=session.createCriteria(Customer.class);
			//1.创建对象:不需要使用session
			DetachedCriteria detachedCriteria=DetachedCriteria.forClass(Customer.class);
			
			//2.最终执行的时候才需要用到sesison
			Criteria criteria=detachedCriteria.getExecutableCriteria(session);
			
			List<Customer> list=criteria.list();

			for(Customer customer:list){
				System.out.println(customer.getCid()+"::"+customer.getCustName());
			}
			
			tx.commit();
		}catch(Exception e)	{
			e.printStackTrace();
			tx.rollback();
		}
		finally{
			session.close();
			sessionfactory.close();
		}
	}

5、本地sql查询:SQLQuery对象,使用普通sql实现查询。

 

 

二、Hibernate的多表查询:

1、在介绍hibernate的多表查询之前,首先介绍一下mysql的多表查询方式:

–内连接:

select * from t_customer c,t_linkman l where c.cid=l.clid;

select * from t_customer c inner join t_linkman l on c.cid=l.clid;

–左外连接:

select * from t_customer c left outer join t_linkman l on c.cid=l.clid;

外连接:

select * from t_customer c right outer join t_linkman l on c.cid=l.clid;

2、hIbernate的多表查询:

(1)内连接:返回list,list里面每部分是数组形式:

	// 内连接:
	@Test
	public void ManyTableSelect1() {

		SessionFactory sessionfactory = null;
		Session session = null;
		Transaction tx = null;

		try {
			sessionfactory = HibernateUtil.getSessionFactory();
			session = sessionfactory.openSession();
			tx = session.beginTransaction();

			// 1.创建对象
			Query query = session.createQuery("from Customer c inner join c.setLinkMan");

			// 内连接返回的list,list里面的每一部分都是数组形式
			List list = query.list();

			System.out.println(list.size());

			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
			tx.rollback();
		} finally {
			session.close();
			sessionfactory.close();
		}
	}

(2)迫切内连接:底层实现与内连接是一样的,不过返回的list每部分是对象::

        // 迫切内连接
	@Test
	public void ManyTableSelect2() {

		SessionFactory sessionfactory = null;
		Session session = null;
		Transaction tx = null;

		try {
			sessionfactory = HibernateUtil.getSessionFactory();
			session = sessionfactory.openSession();
			tx = session.beginTransaction();

			// 1.创建对象,在hql语句中加fetch关键字
			Query query = session.createQuery("from Customer c inner join fetch c.setLinkMan");

			// 迫切内连接返回的list,list里面的每一部分都是对象形式,底层和内连接是一样的
			List list = query.list();

			System.out.println(list.size());

			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
			tx.rollback();
		} finally {
			session.close();
			sessionfactory.close();
		}
	}

(3)左外连接:返回list,list里面每部分是数组形式:

        // 左外连接
	@Test
	public void ManyTableSelect3() {

		SessionFactory sessionfactory = null;
		Session session = null;
		Transaction tx = null;

		try {
			sessionfactory = HibernateUtil.getSessionFactory();
			session = sessionfactory.openSession();
			tx = session.beginTransaction();

			// 1.创建对象
			Query query = session.createQuery("from Customer c left outer join c.setLinkMan");

			// 左外连接返回的list,list里面的每一部分都是数组形式
			List list = query.list();

			System.out.println(list.size());

			tx.commit();

		} catch (Exception e) {
			e.printStackTrace();
			tx.rollback();
		} finally {
			session.close();
			sessionfactory.close();
		}
	}

(4)迫切左外连接:底层实现与内连接是一样的,不过返回的list每部分是对象:

        // 迫切左外连接
	@Test
	public void ManyTableSelect4() {

		SessionFactory sessionfactory = null;
		Session session = null;
		Transaction tx = null;

		try {
			sessionfactory = HibernateUtil.getSessionFactory();
			session = sessionfactory.openSession();
			tx = session.beginTransaction();

			// 1.创建对象,在hql语句中加fetch关键字
			Query query = session.createQuery("from Customer c left outer join fetch c.setLinkMan");

			// 迫切左外连接返回的list,list里面的每一部分都是对象形式,底层和内连接是一样的
			List list = query.list();

			System.out.println(list.size());

			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
			tx.rollback();
		} finally {
			session.close();
			sessionfactory.close();
		}
	}

(5)右外连接:返回list,list里面每部分是数组形式(没有迫切右外连接):

	// 右外连接
	@Test
	public void ManyTableSelect5() {

		SessionFactory sessionfactory = null;
		Session session = null;
		Transaction tx = null;

		try {
			sessionfactory = HibernateUtil.getSessionFactory();
			session = sessionfactory.openSession();
			tx = session.beginTransaction();

			// 1.创建对象
			Query query = session.createQuery("from Customer c right outer join c.setLinkMan");

			// 右外连接返回的list,list里面的每一部分都是数组形式
			List list = query.list();

			System.out.println(list.size());

			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
			tx.rollback();
		} finally {
			session.close();
			sessionfactory.close();
		}
	}

 

三、hibernate的检索策略:

Hibernate的检索策略主要分成两种:立即查询和延迟查询。

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

2、延迟查询:根据id查询,还有load方法,调用load方法,不会马上发送语句查询数据,只有得到对象里面的值时候才会发送语句查询数据库。(即想要查询对象里面不是id的其他值得时候才会发送语句,提高性能)

(1)延迟查询分为:

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

②关联级别延迟:查询某个客户,在查询这个客户的所有联系人,查询客户的所有联系 人的过程是否需要延迟,这个过程称为关联级别延迟。

(2)关联级别延迟操作:

①根据客户得到所有的联系人,在客户映射文件中配置;

②在set标签上使用属性

—fetch:值select(默认)

—lazy的值:true:延迟(默认);false:不延迟;extra:极其延迟。

<!-- 在客户映射文件中,表示所有联系人。
关联级别延迟操作:fetch="select" lazy="true"。
fetch值:select(默认) 。lazy值:true延迟(默认) false不延迟  extra极其延迟-->
<set name="setLinkMan" cascade="save-update,delete" inverse="true" fetch="select" lazy="true">
	<key column="clid"></key>
	<!-- 客户所有的联系人,class里面写联系人实体全路径 -->
	<one-to-many class="com.zwp.onetomany.LinkMan"/>
</set>

 

 

四、Hibernate的批量抓取:

<!-- 在客户映射文件中,表示所有联系人。
	batch-size="10":批量抓取,值越大,效率越高 -->
<set name="setLinkMan" cascade="save-update,delete" inverse="true" fetch="select" lazy="true" batch-size="10">
	<key column="clid"></key>
	<!-- 客户所有的联系人,class里面写联系人实体全路径 -->
	<one-to-many class="com.zwp.onetomany.LinkMan"/>
</set>
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/114721.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 为什么电脑压缩文件图标突然变成这样了

    为什么电脑压缩文件图标突然变成这样了

  • Linux(程序设计):55—非阻塞connect(EINPROGRESS)「建议收藏」

    Linux(程序设计):55—非阻塞connect(EINPROGRESS)「建议收藏」非阻塞connect详情介绍可以参见文章:https://blog.csdn.net/qq_41453285/article/details/89890429一、非阻塞connect概述man手册connect的man手册有如下一段内容:EINPROGRESSThesocketisnonblockingandtheconnectioncannotbe…

  • 网闸上数据库同步

    网闸上数据库同步最近要实施数据库架构调整。1.数据库服务器要加台内网服务器,使用网闸隔离。中间有台文件中转服务器。要求实现数据库复制到内网服务器上供应用使用。考虑的方案有如下: 1.使用中转服务器作复制桥接。先从外网服务器同步到中转服务器,再同步到内网服务器。 2.貌似有的网闸产品支持数据库同步,如果本次上的产品支持,就不用什么桥接了,直接复制到内网服务器就OK了。  等待方案确认中

  • 单选按钮控件和复选框控件_单选按钮控件和复选框控件都具有

    单选按钮控件和复选框控件_单选按钮控件和复选框控件都具有Windows单按钮、复选框、分组框控件单选按钮(Radio Button)和复选框(Check Box)是常见的Windows控件,用于从给出的选项中选择一项或多项,如下图所示:单选钮与复选框单选按钮是互斥的,只能选择其中一项;而复选框没有限制,可以选择一项或多项。单选按钮和复选框都是一种特殊的按钮,窗口类名称都是button,只不过增加了一些特殊的窗口样式罢了。单选按钮的样式为BS_…

  • android 学生模式,(续上篇)多亲AI助手——学生模式体验小记

    android 学生模式,(续上篇)多亲AI助手——学生模式体验小记(续上篇)多亲AI助手——学生模式体验小记2019-08-1811:02:5617点赞9收藏14评论朋友的多亲2,是过了好几手的。哦,原来不是他的,那上次半推半就借给我,是几个意思?寄走前,他允许我再摸摸。正好,本人还有几个疑问,需要验证。本篇体验,以问答形式撰写,没有废话,都是干货。网红遥控器值不值得买——多亲AI助手体验小记由来“多亲AI助手”到手,来自一位朋友,过两天还要还回去,并非全新,…

  • Winform控件开发(1)——Label(史上最全)

    Winform控件开发(1)——Label(史上最全)作用:一般用于显示文本或者作为”按钮使用”,当作为显示文本使用时,通过设置label的Text属性实现,当作为“按钮使用时”,在lable的单击事件下注册事件即可,下面详细介绍label的属性:1、Name属性,该属性代表label类对象的名称,通过该属性可以获取到该label对象,如下图:该label对象名称为label1,当然也可以更改为其他名称2、AllowDrop属性,该属性的值是…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号