1. 程式人生 > >JDBC資料庫操作封裝(PreparedStatement)

JDBC資料庫操作封裝(PreparedStatement)

之前有用過老師給的實現好的JDBC封裝類,今天自己看著書按自己思路實現了一遍,並將Statement改為了PreparedStatement。

程式碼

import com.sun.tools.javac.util.List;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

/**
 * Created by shiyi on 16/9/18.
 */
public class DBUtil
{
private static DBUtil dbUtil = null; private String dbDriver; private String dbUrl; private String dbUser; private String dbPass; private Connection conn; private PreparedStatement stmt; private ResultSet rst; private DBUtil(){} public static DBUtil getInstance
() { if(dbUtil == null) { dbUtil = new DBUtil(); dbUtil.openConnection(); } return dbUtil; } //從配置檔案獲取資訊 private void loadConnProperties() { ResourceBundle rb = ResourceBundle.getBundle("database"); dbDriver = rb.getString("driver"
); dbUrl = rb.getString("url"); dbUser = rb.getString("user"); dbPass = rb.getString("pass"); } //獲取資料庫連線物件 private void openConnection() { loadConnProperties(); try { //載入driver介面,完成註冊 Class.forName(dbDriver); conn = DriverManager.getConnection(dbUrl, dbUser, dbPass); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } //執行sql命令 public int execCommand(String sql) { int flag = 0; try { stmt = conn.prepareStatement(sql); flag = stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } return flag; } //插入新紀錄,並獲取標識列的值 public int execUpdate(String sql, Object[] data) { int flag = 0; try { if(conn == null) throw new Exception("Database not connected!"); stmt = conn.prepareStatement(sql); for(int i=0; i<data.length; i++) { stmt.setObject(i+1, data[i]); } flag = stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } return flag; } //查詢並返回結果集 public ResultSet execQuery(String sql, Object[] data) { try { stmt = conn.prepareStatement(sql); for(int i=0; i<data.length; i++) { stmt.setObject(i+1, data[i]); } rst = stmt.executeQuery(); } catch (SQLException e) { e.printStackTrace(); } return rst; } //查詢並以連結串列形式返回結果 public ArrayList<Object> execQueryList(String sql, Object[] data) { int colCount = 0; ResultSetMetaData rstmd = null; rst = execQuery(sql, data); try { rstmd = rst.getMetaData(); colCount = rstmd.getColumnCount(); } catch (SQLException e) { e.printStackTrace(); } ArrayList<Object> list = new ArrayList<Object>(); try { while(rst.next()) { Map<String, Object> map = new HashMap<String, Object>(); for(int i=1; i<=colCount; i++) { /* getColumnLabel獲取用於列印輸出和顯示的指定列的建議標 getColumnName獲取指定列的名稱 select的結果集返回的是Label 所以此處只能用Label而不能用Name */ map.put(rstmd.getColumnLabel(i), rst.getObject(i)); } list.add(map); } } catch (SQLException e) { e.printStackTrace(); } finally { try { stmt.close(); rst.close(); } catch (SQLException e) { e.printStackTrace(); } } return list; } public static void main(String argc[]) { DBUtil db = DBUtil.getInstance(); Object[] data = {}; db.execCommand("create table temp(id int, name char(100))"); db.execUpdate("insert into temp values(?, ?)", new Object[]{1, "aaa"}); db.execUpdate("insert into temp values(?, ?)", new Object[]{2, "bbb"}); db.execUpdate("insert into temp values(?, ?)", new Object[]{3, "ccc"}); db.execUpdate("insert into temp values(?, ?)", new Object[]{4, "ddd"}); ArrayList<Object> list = db.execQueryList("select * from temp where id > ? and id < ?", new Object[]{1, 4}); for(Object it : list) { Map<String, Object> map = (Map<String, Object>) it; System.out.println(map.get("id") + " -- " + map.get("name")); } } }

測試結果

2 – bbb
3 – ccc

注意點

1. 在從ResultSetMetaDate獲取列名時,要使用getColumnLabel,而不能用getColumnName:

原因在於:
getColumnLabel獲取用於列印輸出和顯示的指定列的建議標
getColumnName獲取指定列的名稱
而select的結果集返回的是Label
所以此處只能用Label而不能用Name

2. 在使用ResultSet之前不能關閉Statement,否則會出現SqlException:

java.sql.SQLException: Operation not allowed after ResultSet closed