hibernate hql update操作
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate hql update操作相关的知识,希望对你有一定的参考价值。
存在一对多两个对象
Student 和 Team
String sql ="update Student stu set stu.sex =0 where stu.team.id=10 ";
运用hql运行上面程序,无法更新
日志文件如下
update student stu_01
join
set stu_01.sex=0
日志文件
update student stu_01
join
set stu_01.sex=0
where team_id = 10
没有进行join 关联
Student 中的team对象 的Fetch设为false
查询sql="select student stu where stu.team=10 and stu.sex=0";
hql查询时没有问题的,这种连接判断就会做join操作
hibernate的update及JDBC数据库批量操作
最本质的区别是Session.update()更新的实体。而Query.update()更新的是执行SQL语句。
由此会带来一些问题。
性能问题
首先如果要使用Session去更新数据库需要执行一个获取实体的操作,也就是说需要先获取这个实体。而如果执行Query.update()则是直接执行SQL语句(或者HQL)。
本来以我的理解来看Query的效率应该比Session效率要高的,因为Query.update()更加原生,但是后来实现以下发现这个不一定。
首先,一般来说我们使用Query.update()不会直接构造一个Query区执行,因为软件中为了方便使用常常把Query.updata()包装成一些比较方便的方式,比如根据所给的class类型以及where的相关参数去生成Query所以这样更方便使用,这个过程也很麻烦。所以Query为了方便使用,效率有一定损失。比如我实测这两个方法使用相同的策略。但是使用生成Query形式的方式,10000次操作下Query.update()需要2min14s,而Session.update()则只需要使用1min19s。
批量操作
然后我又查了一下hibernate的批量操作的问题。
主要参考了这篇文章
Hiberante批量更新缺点及解决方案
Hibernate批量操作技巧
第一篇文章主要的观点在于两点:
以上批量更新方式有两个缺点:
(1)占用大量内存,必须把1万个Customer对象先加载到内存,然后一一更新它们。
(2)执行的update语句的数目太多,每个update语句只能更新一个Customer对象,必须通过1万条update语句才能更新一万个Customer对象,频繁的访问数据库,会大大降低应用的性能。第一个缺点的可以通过session的flush和evict来尽可能提早释放Customer。
第二个缺点没有办法解决,作者推荐直接使用JDBC API来实现。或者使用储存过程来做实现更快。
第二篇文章主要在讨论如何在hibernate来尽可能实现快速批量操作
主要通过flush和设置batch_size来实现。
Statement、preparedStatement和CallableStatement的区别
主要参考了这两篇文章:
Statement、preparedStatement和CallableStatement的区别
主要观点:
Statement 每次执行sql语句,数据库都要执行sql语句的编译 ,最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement.
PreparedStatement是预编译的,使用PreparedStatement有几个好处
a. 在执行可变参数的一条SQL时,PreparedStatement比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率要高。
b. 安全性好,有效防止Sql注入等问题。
c. 对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch;
d. 代码的可读性和可维护性。CallableStatement接口扩展 PreparedStatement,用来调用存储过程,它提供了对输出和输入/输出参数的支持。CallableStatement 接口还具有对 PreparedStatement 接口提供的输入参数的支持。
但是按照目前的资料来看我对PreparedStatement和CallableStatement之间有什么区别。大概可以总结如下:
- 首先CallableStatement是继承自PreparedStatement的。
- PreparedStatement主要来数据库支持预编译就可以了,而CallableStatement则需要数据库支持存储过程才行。
- 从执行效率来说CallableStatement要比PreparedStatement效率要高。
- 对于PreparedStatement只要在编程语言中定义就好了,而对于CallableStatement还需要在编程语言中预先写好存储过程才行。
另外一些疑问:
- 有一些说法是PreparedStatement就是存储过程,但是个人来说不太支持这种说法。我猜想可能是早起JDBC和存储过程版本支持问题。个人还是觉得CallableStatement的实现。
- 另外一个问题就是PreparedStatement的预处理过程是经过缓存的。这里的缓存策略是一个问题,比如缓存何时刷新,是由数据库刷新还是可以程序控制之类的。目前还没有找到资料。
以上是关于hibernate hql update操作的主要内容,如果未能解决你的问题,请参考以下文章
转: Hibernate HQL查询 插入 更新(update)实例
Hibernate HQL查询 插入 更新(update)实例