這篇文章給大家分享的是有關(guān)Hibernate+JDBC實(shí)現(xiàn)批量插入、更新及刪除的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
成都創(chuàng)新互聯(lián)是一家專業(yè)從事成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、成都外貿(mào)網(wǎng)站建設(shè)公司的網(wǎng)絡(luò)公司。作為專業(yè)網(wǎng)站制作公司,成都創(chuàng)新互聯(lián)依托的技術(shù)實(shí)力、以及多年的網(wǎng)站運(yùn)營(yíng)經(jīng)驗(yàn),為您提供專業(yè)的成都網(wǎng)站建設(shè)、營(yíng)銷型網(wǎng)站建設(shè)及網(wǎng)站設(shè)計(jì)開(kāi)發(fā)服務(wù)!
具體如下:
一、批量插入(兩種方式)
1. 通過(guò)Hibernate緩存
如果這樣寫(xiě)代碼進(jìn)行批量插入(初始設(shè)想):
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(); } }
如果數(shù)據(jù)量太大,會(huì)有可能出現(xiàn)內(nèi)存溢出的異常;
小知識(shí):
(1).Hibernate一級(jí)緩存,對(duì)其容量沒(méi)有限制,強(qiáng)制使用,由于所有的對(duì)象都被保存到這個(gè)緩存中,內(nèi)存總會(huì)達(dá)到一定數(shù)目時(shí)出現(xiàn)內(nèi)存溢出的情況;
(2).Hibernate二級(jí)緩存可以進(jìn)行大小配置;
要解決內(nèi)存溢出的問(wèn)題,就應(yīng)該定時(shí)的將Sessiion緩存中的數(shù)據(jù)刷到數(shù)據(jù)庫(kù),正確的批量插入方式:
(1).設(shè)置批量尺寸(博主至今還沒(méi)有明白下面這個(gè)屬性和flush()方法的區(qū)別)
<property name="hibernate.jdbc.batch_size">2</property>
配置這個(gè)參數(shù)的原因就是盡量少讀數(shù)據(jù)庫(kù),該參數(shù)值越大,讀數(shù)據(jù)庫(kù)的次數(shù)越少,速度越快;上面這個(gè)配置,是Hibernate是等到程序積累了100個(gè)sql之后在批量提交;
(2).關(guān)閉二級(jí)緩存(這個(gè)博主也不是很明白)
<property name="hibernate.cache.use_second_level_cache">false</property>
除了Session級(jí)別的一級(jí)緩存,Hibernate還有一個(gè)SessionFactory級(jí)別的二級(jí)緩存,如果啟用了二級(jí)緩存,從機(jī)制上來(lái)說(shuō),Hibernate為了維護(hù)二級(jí)緩存,在批量插入時(shí),hibernate會(huì)將對(duì)象納入二級(jí)緩存,性能上就會(huì)有很大損失,也可能引發(fā)異常,因此最好關(guān)閉SessionFactory級(jí)別的二級(jí)緩存;
(3).在一二設(shè)置完成的基礎(chǔ)上,清空Session級(jí)別的一級(jí)緩存;
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個(gè)數(shù)據(jù)作為一個(gè)處理單元 sess.flush(); //保持與數(shù)據(jù)庫(kù)數(shù)據(jù)的同步 sess.clear(); //清楚Session級(jí)別的一級(jí)緩存的全部數(shù)據(jù),及時(shí)釋放占用的內(nèi)存 } } 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. 繞過(guò)Hibernate,直接調(diào)用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(); //執(zhí)行Work對(duì)象指定的操作,即調(diào)用Work對(duì)象的execute()方法 //Session會(huì)把當(dāng)前使用的數(shù)據(jù)庫(kù)連接傳給execute()方法 sess.doWork(new Work() { @Override public void execute(Connection arg0) throws SQLException {//需要注意的是,不需要調(diào)用close()方法關(guān)閉這個(gè)連接 //通過(guò)JDBC API執(zhí)行用于批量插入的sql語(yǔ)句 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(); } }
注意:通過(guò)JDBC API中的PreparedStatement接口來(lái)執(zhí)行sql語(yǔ)句,sql語(yǔ)句涉及到的數(shù)據(jù)不會(huì)被加載到Session的緩存中,因此不會(huì)占用內(nèi)存空間,因此直接調(diào)用JDBC API批量化插入的效率要高于Hibernate緩存的批量插入;
更新&&刪除
語(yǔ)法格式:(HQL)
update | delete from? <ClassName> [where where_conditions]
1>在from子句中,from關(guān)鍵字是可選的,即完全可以不寫(xiě)from關(guān)鍵字
2>在from子句中,只能有一個(gè)類名,可以在該類名后指定別名
3>不能在批量HQL語(yǔ)句中使用連接,顯示或者隱式的都不行,但可以在where子句中使用子查詢
4>整個(gè)where子句是可選的,where子句的語(yǔ)法sql語(yǔ)句中where子句的語(yǔ)法完全相同
5>Query.executeUpdate()方法返回一個(gè)整型值,該值是受此操作影響的記錄數(shù)量,由于hibernate的底層操作實(shí)際上是由JDBC完成的,因此,如果有批量update或delete操作被轉(zhuǎn)換成多條update或delete語(yǔ)句,(關(guān)聯(lián)或者繼承映射),該方法只能返回最后一條sql語(yǔ)句影響的記錄行數(shù),不是所有的記錄行數(shù),需要注意;
二、批量更新(兩種方式)
1. 使用Hibernate直接進(jìn)行批量更新
(1)方式1:(Hibernate的HQL直接支持update/delete的批量更新語(yǔ)法)
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進(jìn)行批量更新,下面的的語(yǔ)句是HQL語(yǔ)句,不是sql語(yǔ)句 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(); } }
(2)方式2:(強(qiáng)烈不推薦)
package com.anlw.util; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import org.hibernate.CacheMode; import org.hibernate.Query; import org.hibernate.ScrollMode; import org.hibernate.ScrollableResults; 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; 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(); //查詢表中的所有數(shù)據(jù) ScrollableResults student = sess.createQuery("from Student") .setCacheMode(CacheMode.IGNORE) .scroll(ScrollMode.FORWARD_ONLY); int count = 0; while(student.next()){ Student s = (Student)student.get(0); s.setName("haha"); if(++count%3 == 0){ sess.flush(); sess.clear(); } } tx.commit(); } catch (Exception e) { if (tx != null) { tx.rollback(); } } finally { sess.close(); sf.close(); } } public static void main(String[] args) { new SessionUtil().HIbernateTest(); } }
通過(guò)這種方式,雖然可以執(zhí)行批量更新,但效果非常不好,執(zhí)行效率不高,需要先執(zhí)行數(shù)據(jù)查詢,然后再執(zhí)行數(shù)據(jù)更新,而且這種更新將是逐行更新,即每更新一行記錄,都要執(zhí)行一條update語(yǔ)句,性能非常低;
2. 繞過(guò)Hibernate,調(diào)用JDBC API
(1)方式1:
package com.anlw.util; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; 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(); //執(zhí)行Work對(duì)象指定的操作,即調(diào)用Work對(duì)象的execute()方法 //Session會(huì)把當(dāng)前使用的數(shù)據(jù)庫(kù)連接傳給execute()方法 sess.doWork(new Work() { @Override public void execute(Connection arg0) throws SQLException {//需要注意的是,不需要調(diào)用close()方法關(guān)閉這個(gè)連接 String sql = "update student set name = 'oracle'"; //創(chuàng)建一個(gè)Satement對(duì)象 Statement st = arg0.createStatement(); //調(diào)用JDBC的update進(jìn)行批量更新 st.executeUpdate(sql); } }); 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)方式2:
package com.anlw.util; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; 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(); //執(zhí)行Work對(duì)象指定的操作,即調(diào)用Work對(duì)象的execute()方法 //Session會(huì)把當(dāng)前使用的數(shù)據(jù)庫(kù)連接傳給execute()方法 sess.doWork(new Work() { @Override public void execute(Connection arg0) throws SQLException {//需要注意的是,不需要調(diào)用close()方法關(guān)閉這個(gè)連接 String sql = "update student set name = ? where name=?"; PreparedStatement ps = arg0.prepareStatement(sql); for(int i=0;i<10;i++){ ps.setString(1,"tom"); ps.setString(2, "oracle"); 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(); } }
三、批量刪除(兩種方式)
1. 使用Hibernate直接進(jìn)行批量刪除
(1)方式1:(Hibernate的HQL直接支持update/delete的批量更新語(yǔ)法)
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查詢中使用delete進(jìn)行批量刪除,下面的的語(yǔ)句是HQL語(yǔ)句,不是sql Query query = sess.createQuery("delete Student");//也可以是delete from,from關(guān)鍵字是可選的,可以不要,加條件的時(shí)候可以指定類的別名 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(); } }
(2)方式2:(強(qiáng)烈不推薦)
package com.anlw.util; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import org.hibernate.CacheMode; import org.hibernate.Query; import org.hibernate.ScrollMode; import org.hibernate.ScrollableResults; 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; 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(); //查詢表中的所有數(shù)據(jù) ScrollableResults student = sess.createQuery("from Student") .setCacheMode(CacheMode.IGNORE) .scroll(ScrollMode.FORWARD_ONLY); int count = 0; while(student.next()){ Student s = (Student)student.get(0); sess.delete(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(); } }
通過(guò)這種方式,雖然可以執(zhí)行批量刪除,但效果非常不好,執(zhí)行效率不高,需要先執(zhí)行數(shù)據(jù)查詢,然后再執(zhí)行數(shù)據(jù)刪除,而且這種刪除將是逐行刪除,即每刪除一行記錄,都要執(zhí)行一條delete語(yǔ)句,性能非常低;
2. 繞過(guò)Hibernate,調(diào)用JDBC API
(1)方式1:
package com.anlw.util; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; 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.jdbc.Work; 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(); sess.doWork(new Work() { @Override public void execute(Connection arg0) throws SQLException { String sql = "delete from student where age > 5"; //MySQL中刪除語(yǔ)句不能省略from Statement st = arg0.createStatement(); st.executeUpdate(sql); } }); 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)方式2:
package com.anlw.util; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; 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.jdbc.Work; 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(); sess.doWork(new Work() { @Override public void execute(Connection arg0) throws SQLException { String sql = "delete from student where age = ?"; //mysql中刪除語(yǔ)句不能省略from PreparedStatement ps = arg0.prepareStatement(sql); for(int i=0;i<10;i++){ if(i%2 == 0){ ps.setInt(1, i); 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(); } }
感謝各位的閱讀!關(guān)于“Hibernate+JDBC實(shí)現(xiàn)批量插入、更新及刪除”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
網(wǎng)頁(yè)題目:Hibernate+JDBC實(shí)現(xiàn)批量插入、更新及刪除
文章鏈接:http://bm7419.com/article8/ijhiop.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營(yíng)銷、全網(wǎng)營(yíng)銷推廣、電子商務(wù)、標(biāo)簽優(yōu)化、定制網(wǎng)站、靜態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
營(yíng)銷型網(wǎng)站建設(shè)知識(shí)