Hibernate+JDBC实现批量插入、更新及删除的方法详解
|
本文实例讲述了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一级缓存,对其容量没有限制,强制使用,由于所有的对象都被保存到这个缓存中,内存总会达到一定数目时出现内存溢出的情况; 要解决内存溢出的问题,就应该定时的将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关键字 二、批量更新(两种方式) 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 = 'www'");
query.executeUpdate();
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
} finally {
sess.close();
sf.close();
}
}
public static void main(String[] args) {
new SessionUtil().HIbernateTest();
}
}
(编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
