JDBC資料庫操作封裝(PreparedStatement)
阿新 • • 發佈:2019-02-14
之前有用過老師給的實現好的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