传智播客 Hibernate HQL语言与其它

 

    HQL(Hibernate Query Language):具有与sql语言类似的语法规范,只不过sql是针对于数据表字段进行查询,而 HQL 是针对持久化对象,它用来取得对象。HQL 是完全面向对象的,具备继承,多态和关联等特性,除了JAVA类和属性 外HQL对大小写不敏感。HQL 查询依赖于 Query 类,每个 Query 实例对应一个查询对象。Query 接口用来执行 HQL,Query 接口实例可以从 Session 对象 session 中生成:
    Query query = session.createQuery(“from User u where u.userName like ?”);
    Query 的主要方法:
        setXXX()方法:用于设置HQL中的问号或变量的值,每一个方法都有两种重载形式,以 setString()为例:
          setString(int position,String value):用于设置HQL中的 ”?” 的值;期中position代表 ”?” 在HQL中的位置,value为 ”?” 设置的值.例如:
      Query query = session.createQuery(“from User u where u.age > ? and u.userName like ?”);
      query.setInteger(0,12);
      query.setString(1,”%Tom%”);
        list()方法:返回查询结果,并把查询结果转变为 List对象
        excuteUpdate()方法:执行更新或删除语句
    在查询时,如果希望查询得到的是具体的关联的对象。则应该在查询语句中加上 fetch 关键字。例如:
        from Customers as customer inner join fetch customer.orders as order
    查询 Customers 对象的时候,默认只有 Customers 的内容,并不包含 orders 集合的信息,在 Customers.hbm.xml 里设置lazy=“false”可以同时取出关联的所有 orders 内容.但若既想要 hibernate 默认的性能又想要临时的灵活性,则可以使用 fetch。总之,fetch就是在代码这一层给你一个主动抓取得机会fetch 关键字只对 inner join 和 left join 有效。对于 right join 而言, 由于作为关联对象的 Customers 对象可能为 null,所以无法通过 fetch 关键字强制 Hibernate 进行集合填充操作。这意味着只能对返回集合中的各个数组进行处理。
    在通过JDBC操作数据时,只能通过SQL语句来加载所需要的数据由于O-R Mapping的帮助,Hibernate总共有4种数据加载方式:即时加载、延迟加载、预先加载、批量加载。
    1.即时加载:当实体加载完成后,立即加载该实体所关联的数据。例如:客户和订单之间的一对多关联映射:当查询 Customers 实体时,会自动加载它所关联的 Orders 实体对象,因此会出现二条查询语句。即时加载的基本原理,当宿主实体加载时,会立即自动加载关联的实体对象,并完成关联实体对象的属性填充和实体对象的构造。即时加载中,当加载 Customers 对象时,通过另一条查询语句自动加载了它所关联的实体对象,但是如果只需要 Customers 对象数据,而不需要它所关联的 Orders 对象数据,就造成了性能的损耗。
    2.延迟加载机制就是为了解决这个问题。当查询 Customers 对象时,并没有立即加载它所关联的Orders 对象,只有执行确实获取关联的 Orders 对象数据时,才会发起对关联对象的查询。延迟加载机制,只有当确实需要获取关联数据时,才去真正加载关联对象
    3.预先加载:与即时加载类似,预先加载时,实体及其关联的对象同时读取,不同的是预先加载只通过一条 SQL 语句(基于外连接[outer join])完成同时读取.预先加载通过 outer-join 完成关联数据的加载。对于集合属性不推荐使用。
    4.批量加载,通过批量提交多个限定条件,一次完成多个数据的 读取:
     select * from customer where id=’1’;
      select * from customer where id=’2’;
    将以上两个SQL语句合并:
     select * from customer where id=’1’ or id=’2’;
    当使用批量加载时,Hibernate会自动在当前session中查找是否还有同类型的待加载的实体对象,如果有就将查询条件合并到当前的查询语句中,这样就通过一次数据库操作完成了多次读取任务,从而提高读取性能。
如需启用批量加载,须配置实体类的class元素:
  <class name=”customer” table=”customer” batch-size=”5” >
  batch-size属性:指定批量加载尺寸以及启用批量加载,以上配置每次最多同时加载5个同类型实体对象。
    在利用Hibernate开发DAO模块时,和Session打交道最多,所以如何合理的管理Session,避免Session的频繁创建和销毁,对于提高系统的性能来说是非常重要的。Session是由SessionFactory负责创建的,而SessionFactory的实现是线程安全的,多个并发的线程可以同时访问一个SessionFactory并从中获取Session实例,但 Session 却是线程不安全的。多个线程同时使用一个Session实例进行CRUD,就有可能导致数据存取的混乱。建议为每个请求对应一个 Session。为了达到这种效果,推荐使用一个 ThreadLocal 变量,把 Session 绑定到处理客户端请求的线程上去。这种方式可以让运行在该线程上的所有代码轻松的访问 Session。
    ThreadLocal是一个线程隔离(或者说是线程安全)的变量存储的管理实体(注意:不是存储用的),以Java类方式表现当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。一个ThreadLocal变量类似一个HashMap,它的key集合就是Thread.currentThread(),它的value集合就是要跨域共享的对象。当代码从threadLocal变量get()来取对象的时候,就是以代码运行所在的currentThread为key,去找它对应的value共享对象。因而在一个thread里面,任何被该thread调用到的类,方法代码都可以取到同一个跨域共享对象。而不同的thread则取到不同的对象。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值