【hibernate】——hql简单属性+实体对象查询

    最近一直在研究hibernate,真是觉得越深入乐趣越多,由衷佩服hibernate的开发者,真正的体验到什么时灵活自如!真的很喜欢!
    本文小编主要讲解hibernate中原生sql在查询简单属性和实体对象的怎么使用,以及几种不同的参数查询。

    简单属性查询

1】 单个属性

//返回结果集属性列表,元素类型和实体类中的属性类型一致,其中Student对应的是程序中实体
List students = session.createQuery("select name from Student").list();
for (Iterator iter=students.iterator(); iter.hasNext();){
	String name = (String)iter.next();
	System.out.println(name);
}

2】 多个属性

//查询多个属性,返回对象数组集合
//数组元素的类型与查询的属性类型一致
//数组的长度与select中查询的属性个数一致
List students = session.createQuery("select id, name from Student").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
	Object[] obj = (Object[])iter.next();
	System.out.println(obj[0] + ", " + obj[1]);
}

在是使用原生sql的时候可以采用别名,或者采用as命名别名的方法进行处理,同样在hql支持

// 可以使用别名
List students = session.createQuery("select s.id, s.name from Student s").list();
// 可以采用as命名别名
List students = session.createQuery("select s.id, s.name from Student as s").list();

3】 参数查询

    1) 单个属性查询

a)拼串
// 可以拼串
List students = session.createQuery("select id,name from Student where name like '%0%'").list();

b)占位符

List students = session.createQuery("select id,name from Student where name like ?")
		       .setParameter(0, "%0%").list();
c)冒号 参数名
List students = session.createQuery("select id,name from Student where name like :myname")
		       .setParameter("myname", "%0%").list();

   2) 多个属性查询

a)占位符
List students = session.createQuery( "select id,name from Student where id in(?,?,?,?,?)")
                    .setParameter(0, 1)
                    .setParameter(1, 2)
                    .setParameter(2, 3)
                    .setParameter(3, 4)
                    .setParameter(4, 5)
                    .list();
b)参数名
List students = session.createQuery("select id,name from Student where id in(:ids)")
                   .setParameterList("ids", new Object[]{1,2,3,4,5})
                   .list();
   上述两种方式哪种更好?
    小编更推荐第二种,理由当参数的个数的发生变化时,方法二需要改动地方更少,更加灵活,简便。

   实体对象查询

1】 List

List students = session.createQuery("from Student").list();
  for (Iterator iterator = students.iterator(); iterator.hasNext();)
 {
     Student student = (Student) iterator.next();
     System.out.println(student.getId() + ";" + student.getName());
 }         	
提示:注意观察执行hql的时候select可以忽略,同时执行此查询仅仅发出了一条sql,对比下面的iterate

2】iterate

Iterator iter = session.createQuery("from Student").iterate();
 while (iter.hasNext())
      {
          Student student = (Student) iter.next();
          System.out.println(student.getName());
      }
提示:使用迭代后执行此hql,在控制台会出现N+1条sql语句,从系统执行的效率来说是低下,不值得使用,但是还是应该分析利弊再决定!

3】 List和iterate使用规范

上述说到iterate出现N+1问题,那我们就拒绝使用迭代么!其实不是这样,下面做二个demo
1、list查询之后再使用list查询
@SuppressWarnings("unchecked")
    public void testQuery4()
    {
        Session session = null;
        try
        {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            List students = session.createQuery("from Student").list();
            for (Iterator iterator = students.iterator(); iterator.hasNext();)
            {
                Student student = (Student) iterator.next();
                System.out.println(student.getId() + ";" + student.getName());

            }
            System.out.println("-----------------------------");
            /**
             * 再次发出查询语句
             * 
             * 默认情况下,每次执行list查询实体对象都会发出查询语句,除非配置了查询缓存
             * 虽然一级缓存中存在student数据,但list不用,仍然发出查询语句
             * 
             * 其实list就是只向缓存中放入数据,而不利用缓存中的数据
             */
            students = session.createQuery("from Student").list();
            for (Iterator iterator = students.iterator(); iterator.hasNext();)
            {
                Student student = (Student) iterator.next();
                System.out.println(student.getId() + ";" + student.getName());

            }
            session.getTransaction().commit();
        }
        catch (Exception e)
        {
            e.printStackTrace();
            session.getTransaction().commit();
        }
        finally
        {
            HibernateUtils.closeSession(session);
        }
    }
2、先用list查询,再使用iterate查询
@SuppressWarnings("unchecked")
    public void testQuery3()
    {
        Session session = null;
        try
        {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            List students = session.createQuery("from Student").list();
            for (Iterator iterator = students.iterator(); iterator.hasNext();)
            {
                Student student = (Student) iterator.next();
                System.out.println(student.getId() + ";" + student.getName());

            }
            System.out.println("-----------------------------");
            /**
             * 避免N+1问题 因为执行list操作后会将数据放到session的缓存中,所以采用iterator的时候
             * 首先会发出一条查询id列表的语句,在根据id到缓存中加载相应的数据。如果缓存中存在与之匹配的数据,
             * 则不再发出根据id查询的sql语句,直接使用缓存中的数据
             * iterate方法,如果缓存中存在数据,它可以提高性能,否则出现N+1问题
             */
            Iterator iter = session.createQuery("from Student").iterate();
            while (iter.hasNext())
            {
                Student student = (Student) iter.next();
                System.out.println(student.getName());

            }
            session.getTransaction().commit();
        }
        catch (Exception e)
        {
            e.printStackTrace();
            session.getTransaction().commit();
        }
        finally
        {
            HibernateUtils.closeSession(session);
        }
    }
    两者需要根据使用情况考虑,如果内存已经存在数据了,那么使用iterate完美满足。如果内存中没有,还是先使用list。

【总结】

    关于hql这一部分因为sql的基础,接触起来还是比较容易。关于hql查询这一部分内容基本上这么多了,返回属性和返回实体基本没有差别,还有关于list和iterate这两个使用情况一定要分区情况,所有都是为了程序有更好的性能!

转载于:https://my.oschina.net/u/3705835/blog/1550120

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值