實現Java批量插入數據庫數據,在javaeye中看到過幾篇關於實現Java批量插入數據庫數據,轉載時沒有找到,就自己寫一下,也算是對自己學習過程中所遇到過的問題做一個總結。
一般關於批量向數據庫插入數據都采用PreparedStatement、Statement…………也包括直接使用JDBC API、框架…………
也看到過幾篇關於這些內容的總結,及大家的評論,以下為我總結的關於批量向數據庫插入數據。
1,使用JDBC API實現配量插入數據:有篇文章介紹過關於JDBC API、Hibernate實現批量插入數據,采用JDBC API 方式實現隨著數據的增長,速度更勝於Hibernate。當然,對於這個測試的准確我並不保證,但是我也會優先選用JDBC API方式實現(原因:簡單、易學、相對於框架更通用,不會過時)。
2,采用PreparedStatement對象實現批量插入數據:PreparedStatement是真正的批處理命令,不是其他的偽批處理命令可以相比的(個人意見),它相對於其他的實現批量處理是非常的強大,比如字段不斷改變,每次都要從文件從新讀取就只能使用PreparedStatement對象來實現。再有就是存在即合理,既然PreparedStatement對象可以多次高效地執行預編譯的語句,就一定有其原因(JDk源碼沒有分析過,和Statement實現的區別不了解)。
3,實現批量插入數據庫數據
Java代碼
Class.forName("com.MySQL.jdbc.Driver");
Connection con = (Connection) DriverManager.getConnection("jdbc:MySQL://" +
"localhost:3306/Excel2MySQL", "wanle", "wanle"); con.setAutoCommit(false); SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss:SS");
TimeZone t = sdf.getTimeZone();
t.setRawOffset(0);
sdf.setTimeZone(t);
Long startTime = System.currentTimeMillis(); PreparedStatement pst = (PreparedStatement) con.prepareStatement("insert into test04 values (?,'中國')");
for (int i = 0; i < 10000; i++) {
pst.setInt(1, i);
// 把一個SQL命令加入命令列表
pst.addBatch(); // 執行批量更新
pst.executeBatch(); con.commit(); Long endTime = System.currentTimeMillis();
System.out.println("用時:" + sdf.format(new Date(endTime - startTime))); pst.close();
con.close();
批量刪除
public boolean delUser(int[] id) {
boolean flag = false;
String sql = "delete from userInfo where userId=?";
conn = base.getConnection();
PreparedStatement pst = null;
try {
pst = conn.prepareStatement(sql);
for (int i = 0; i < id.length; i++) {
pst.setInt(1, id[i]); pst.addBatch(); // 執行批處理
int[] result = pst.executeBatch();
if (result[0] > 0) {
flag = true; } catch (SQLException e) {
e.printStackTrace();
} finally {
try {
base.free(conn, pst, null);
} catch (SQLException e) {
e.printStackTrace(); }
return flag;
}
Java批量上傳處理2009-01-16 17:27//自寫的一個批量文件上傳的功能
public class AddPicInfo extends HttpServlet {
//給主播加入二級圖片信息
private ServletConfig config;
final public void init(ServletConfig config) throws ServletException {
this.config = config;
}
final public ServletConfig getServletConfig() {
return config;
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/Html;charset=GBK");
request.setCharacterEncoding("GBK");
PrintWriter out = response.getWriter();
SmartUpload mySmartUpload = new SmartUpload();
mySmartUpload.initialize(config, request, response); // 初始化信息
DealString ds = new DealString();
DbManger dbm=null;
PicInfo pic=null;
try {
mySmartUpload.upload();
pic=new PicInfo();
String picpath="E:/Tomcat 5.028/webaPPS/WebManager/5Look/mminfopic/";//路徑指定上傳的路徑這裡要指定絕對路徑才可重命名
pic.setInfoid((String)mySmartUpload.getRequest().getParameter("plmmid"));//所屬那個文或主播下
pic.setPicstate((String)mySmartUpload.getRequest().getParameter("isdisp")); //顯示級別
pic.setIsok((String)mySmartUpload.getRequest().getParameter("isok")); //顯示狀態
pic.setPictitle((String)mySmartUpload.getRequest().getParameter("pictitle"));//標題圖片
pic.setCtime((String) mySmartUpload.getRequest().getParameter("pictime")); //上傳時間
//pic.setPicpath((String) mySmartUpload.getRequest().getParameter("name")); //上傳文件的名字
pic.setPicinfo((String) mySmartUpload.getRequest().getParameter("description")); //圖片信息
pic.setMuserid((String) mySmartUpload.getRequest().getParameter("uploader"));//上傳人ID
pic.setRnumber(Integer.parseInt((String) mySmartUpload.getRequest().getParameter("action")));//訪問次數
int count = mySmartUpload.save(picpath); // 上傳文件 if(count==0){
out.println("<a href=addpic.JSP>文件上傳沒有成功</a>");
return;
}//cout==0
String isok="false";
for(int i=0;i<count;i++) com.JSPsmart.upload.File file1 = mySmartUpload.getFiles().getFile(i);// 獲得上傳的文件對象
if (file1.isMissing()) continue;// 若文件不存在則繼續
String picname = file1.getFileName();// 獲得上傳的文件名 old
String ext=ds.toString(picname.substring(picname.lastIndexOf(".")));//取後綴名
String newfile = ds.getDateTime().replaceAll(" ","").replaceAll(":","")+i+ext; //給文件從新命名
try Operation rename=new Operation();
if(rename.rename(picpath, picname,newfile)) pic.setPicname(newfile);
pic.setPicpath(picpath+newfile);
int fsize=file1.getSize()/1024;
pic.setPictype(Integer.toString(fsize));
dbm=new DbManger();
isok=dbm.insetpics(pic);//寫入到數據庫了返回值為true }catch(Exception e)
{ // out.println("<a href=addpic.Html>文件重命名異常指定的目錄不存在</a>");
e.printStackTrace(); // 將得到的值放到數據庫這裡是調用存儲過程加入數據庫先驗證是否有些用戶
}//end for
if(isok.equals("true")) // response.sendRedirect("addpic.JSP");
out.println("<script>");
out.println("if(confirm('"+count+"'+'個文件上傳成功是否繼續上傳?')){window.history.go(-1);} else {window.close();}");
out.println("</script>");
}else out.println("<script>");
out.println("alert('寫入數據庫失敗');");
out.println("window.close();");
out.println("</script>"); } catch (Exception e) {
e.printStackTrace();
out.println("<script>");
out.println("alert('上傳文件異常');");
out.println("window.close();");
out.println("</script>");
}//end try
}//end post
批量添加實例
方案一 用jdbc 的API 那麼這種方法的效率應該是最高的!
方案二 用hibernate 的API 這個方案比第一種方案的效率低!
我開始很猶豫到底用那一種呢!由於我們的項目使用SSH框架的!如果用單純的JDBC API 那麼還要在連接一次數據庫
顯然是不可取的!【減少socket通訊可以提高系統性能】
如果單純的用hibernate 的API 效率太低! 所以我最終選擇的方案是二者結合!
干脆吧 這個方法放到hibernate 自動生成的dao裡面
OK 首先把你的方法也放到Hibernate生成的dao裡面 為什麼 原因是用 this.getSession().connection();可以得到連接
Connection conn= this.getSession().connection(); [注意connection()這個方法已經過時]
conn.setAutoCommit(false);//自動提交事物設置為false 不自動提交
String sql = "insert into test(username,userpwd) values(?,?)";
PreparedStatement pstmt = conn.prepareStatement(sql);//創建PreparedStatement 對象
for (int index = 0; index < number; index++) {
pstmt.setString(1,"username");
pstmt.setString(2,"userPwd");
// 將一組對象添加到prepareStatement對象的批處理密令中
pstmt.addBatch();
//每5000條進行事物提交
if (index%5000==0) {
pstmt.executeBatch(); //執行prepareStatement對象中所有的sql語句
conn.commit();//事物提交
this.getSession().flush();//數據庫與緩存同步
this.getSession().clear();//清空緩存
if (null==conn) { //如果連接關閉了 就在創建一個 為什麼要這樣 原因是 conn.commit()後可能conn被關閉
conn = this.getSession().connection(); }
}
pstmt.executeBatch();//1.執行與5000去摸不是0的數據
conn.commit();//事物提交
conn.close();//釋放連接
pstmt.close();//釋放資源
我以上用的都是PreparedStatement 如果要用Statement 可以改成下面的
Connection conn= this.getSession().connection(); [注意connection()這個方法已經過時]
conn.setAutoCommit(false);//自動提交事物設置為false 不自動提交
Statement st=conn.createStatement();
for (int index = 0; index < number; index++) {
// 將一組對象添加到Statement對象的批處理密令中
st.addBatch("insert into test(username,userpwd) values('"+username+"','"+userpwd+"')");
//每5000條進行事物提交
if (index%5000==0) {
st.executeBatch(); //執行prepareStatement對象中所有的sql語句
conn.commit();//事物提交
this.getSession().flush();//數據庫與緩存同步
this.getSession().clear();//清空緩存
if (null==conn) { //如果連接關閉了 就在創建一個 為為什麼要這樣 原因是 conn.commit()後可能conn被關閉
conn = this.getSession().connection(); }
}
st.executeBatch();//1.執行與5000去摸不是0的數據
conn.commit();//事物提交
conn.close();//釋放連接
st.close();//釋放資源
注意Statement與 PreparedStatement在進行批處理時候唯一的不同家就是:addBatch();方法是否傳遞參數
從效率已經占用內存的多少上 我還是推薦大家使用PreparedStatement