时间:2021-05-20
本文实例讲述了Hibernate JDBC实现批量插入、更新及删除的方法。分享给大家供大家参考,具体如下:
一、批量插入(两种方式)
1. 通过Hibernate缓存
如果这样写代码进行批量插入(初始设想):
package com.anlw.util;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.boot.registry.StandardServiceRegistryBuilder;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import com.anlw.entity.Student;public class SessionUtil { Configuration conf = null; ServiceRegistry st = null; SessionFactory sf = null; Session sess = null; Transaction tx = null; public void HIbernateTest() { conf = new Configuration().configure(); st = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build(); sf = conf.buildSessionFactory(st); try { sess = sf.openSession(); tx = sess.beginTransaction(); for (int i = 0; i < 10; i++) { Student s = new Student(); s.setAge(i + 1); s.setName("test"); sess.save(s); } tx.commit(); } catch (Exception e) { if (tx != null) { tx.rollback(); } } finally { sess.close(); sf.close(); } } public static void main(String[] args) { new SessionUtil().HIbernateTest(); }}如果数据量太大,会有可能出现内存溢出的异常;
小知识:
(1).Hibernate一级缓存,对其容量没有限制,强制使用,由于所有的对象都被保存到这个缓存中,内存总会达到一定数目时出现内存溢出的情况;
(2).Hibernate二级缓存可以进行大小配置;
要解决内存溢出的问题,就应该定时的将Sessiion缓存中的数据刷到数据库,正确的批量插入方式:
(1).设置批量尺寸(博主至今还没有明白下面这个属性和flush()方法的区别)
<property name="hibernate.jdbc.batch_size">2</property>配置这个参数的原因就是尽量少读数据库,该参数值越大,读数据库的次数越少,速度越快;上面这个配置,是Hibernate是等到程序积累了100个sql之后在批量提交;
(2).关闭二级缓存(这个博主也不是很明白)
<property name="hibernate.cache.use_second_level_cache">false</property>除了Session级别的一级缓存,Hibernate还有一个SessionFactory级别的二级缓存,如果启用了二级缓存,从机制上来说,Hibernate为了维护二级缓存,在批量插入时,hibernate会将对象纳入二级缓存,性能上就会有很大损失,也可能引发异常,因此最好关闭SessionFactory级别的二级缓存;
(3).在一二设置完成的基础上,清空Session级别的一级缓存;
package com.anlw.util;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.boot.registry.StandardServiceRegistryBuilder;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import com.anlw.entity.Student;public class SessionUtil { Configuration conf = null; ServiceRegistry st = null; SessionFactory sf = null; Session sess = null; Transaction tx = null; public void HIbernateTest() { conf = new Configuration().configure(); st = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build(); sf = conf.buildSessionFactory(st); try { sess = sf.openSession(); tx = sess.beginTransaction(); for (int i = 0; i < 10; i++) { Student s = new Student(); s.setAge(i + 1); s.setName("test"); sess.save(s); if(i%100 == 0){ //以每100个数据作为一个处理单元 sess.flush(); //保持与数据库数据的同步 sess.clear(); //清楚Session级别的一级缓存的全部数据,及时释放占用的内存 } } tx.commit(); } catch (Exception e) { if (tx != null) { tx.rollback(); } } finally { sess.close(); sf.close(); } } public static void main(String[] args) { new SessionUtil().HIbernateTest(); }}2. 绕过Hibernate,直接调用JDBC API
package com.anlw.util;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.boot.registry.StandardServiceRegistryBuilder;import org.hibernate.cfg.Configuration;import org.hibernate.jdbc.Work;import org.hibernate.service.ServiceRegistry;public class SessionUtil { Configuration conf = null; ServiceRegistry st = null; SessionFactory sf = null; Session sess = null; Transaction tx = null; public void HIbernateTest() { conf = new Configuration().configure(); st = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build(); sf = conf.buildSessionFactory(st); try { sess = sf.openSession(); tx = sess.beginTransaction(); //执行Work对象指定的操作,即调用Work对象的execute()方法 //Session会把当前使用的数据库连接传给execute()方法 sess.doWork(new Work() { @Override public void execute(Connection arg0) throws SQLException {//需要注意的是,不需要调用close()方法关闭这个连接 //通过JDBC API执行用于批量插入的sql语句 String sql = "insert into student(name,age) values(?,?)"; PreparedStatement ps = arg0.prepareStatement(sql); for(int i=0;i<10;i++){ ps.setString(1, "kobe"); ps.setInt(2,12); ps.addBatch(); } ps.executeBatch(); } }); tx.commit(); } catch (Exception e) { if (tx != null) { tx.rollback(); } } finally { sess.close(); sf.close(); } } public static void main(String[] args) { new SessionUtil().HIbernateTest(); }}注意:通过JDBC API中的PreparedStatement接口来执行sql语句,sql语句涉及到的数据不会被加载到Session的缓存中,因此不会占用内存空间,因此直接调用JDBC API批量化插入的效率要高于Hibernate缓存的批量插入;
更新&&删除
语法格式:(HQL)
update | delete from? <ClassName> [where where_conditions]
1>在from子句中,from关键字是可选的,即完全可以不写from关键字
2>在from子句中,只能有一个类名,可以在该类名后指定别名
3>不能在批量HQL语句中使用连接,显示或者隐式的都不行,但可以在where子句中使用子查询
4>整个where子句是可选的,where子句的语法sql语句中where子句的语法完全相同
5>Query.executeUpdate()方法返回一个整型值,该值是受此操作影响的记录数量,由于hibernate的底层操作实际上是由JDBC完成的,因此,如果有批量update或delete操作被转换成多条update或delete语句,(关联或者继承映射),该方法只能返回最后一条sql语句影响的记录行数,不是所有的记录行数,需要注意;
二、批量更新(两种方式)
1. 使用Hibernate直接进行批量更新
(1)方式1:(Hibernate的HQL直接支持update/delete的批量更新语法)
package com.anlw.util;import org.hibernate.Query;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.boot.registry.StandardServiceRegistryBuilder;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;public class SessionUtil { Configuration conf = null; ServiceRegistry st = null; SessionFactory sf = null; Session sess = null; Transaction tx = null; public void HIbernateTest() { conf = new Configuration().configure(); st = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build(); sf = conf.buildSessionFactory(st); try { sess = sf.openSession(); tx = sess.beginTransaction(); //在HQL查询中使用update进行批量更新,下面的的语句是HQL语句,不是sql语句 Query query = sess.createQuery("update Student set name = 'mit(); } catch (Exception e) { if (tx != null) { tx.rollback(); } } finally { sess.close(); sf.close(); } } public static void main(String[] args) { new SessionUtil().HIbernateTest(); }}希望本文所述对大家基于Hibernate的java程序设计有所帮助。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了Yii2.0实现的批量更新及批量插入功能。分享给大家供大家参考,具体如下:批量更新方法1/***批量更新循环周期*@paramarray$cond
文章首先介绍三种JDBC批量插入编程方法,进行比较,具体内容如下JDBC批量插入主要用于数据导入和日志记录因为日志一般都是先写在文件下的等。我用Mysql5.1
使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(100000),如何提高效率呢?在JDBC编程接口中Statement有两个方法特
使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(10W+),如何提高效率呢?在JDBC编程接口中Statement有两个方法特别值
主要内容:jdbc连接数据库步骤。一个简单详细的查询数据的例子。封装连接数据库,释放数据库连接方法。实现查询,插入,删除,更新等十一个处理数据库信息的功能。(包