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)


相关推荐

发表回复

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

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