J2ee項目開發過程中用到的數據庫操作類
此數據庫操作封裝類在一個省級項目中使用到,在一個集團公司的科技管理項目中也使用過.
package jing.dbnew;
import java.sql.*;
import java.util.*;
import javax.sql.rowset.CachedRowSet;
import oracle.jdbc.rowset.OracleCachedRowSet;
import com.sun.rowset.CachedRowSetImpl;
/**
* Title:數據庫操作類,有數據事物控制功能,請注意main函數中的調用事例
* @author 歐朝敬
* QQ:35712069
* 手機:13873195792
* @version 1.0
*/
public class DBManager {
public DBManager(){
}
/**
* 開始事務
*
*/
public void beginTransaction() {
try {
Connection con = ConnectionFactory.getInstance().getConnection();
con.setAutoCommit(false);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 回滾事務
*
*/
public void rollbackTransactoin() {
try {
Connection con = ConnectionFactory.getInstance().getConnection();
con.rollback();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 提交事務
*
*/
public void commitTransaction() {
try {
Connection con = ConnectionFactory.getInstance().getConnection();
con.commit();
con.setAutoCommit(true);
ConnectionFactory.getInstance().closeConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 結束事務
*
*/
// public void endTransaction() {
// try {
// Connection con = ConnectionFactory.getInstance().getConnection();
// con.commit();
// con.setAutoCommit(true);
// ConnectionFactory.getInstance().closeConnection();
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
public boolean execute(String sql) throws Exception {
System.out.println("execute:" + sql);
boolean re = false;
Connection con = null;
PreparedStatement pstmt = null;
try {
con = ConnectionFactory.getInstance().getConnection();
pstmt =con.prepareStatement(sql);
re = pstmt.execute();
}catch(Exception ex){
ex.printStackTrace();
con.rollback();
} finally {
if (pstmt != null) {
pstmt.close();
}
}
return re;
}
/**
* 批量執行SQL語句,在一個事物裏
* @param sql
* @return
* @throws Exception
*/
public int[] executeBatch(String[] sql) throws Exception {
int[] re=null;;
Connection con = null;
Statement stmt = null;
try {
con = ConnectionFactory.getInstance().getConnection();
con.setAutoCommit(false);
stmt =con.createStatement();
stmt.clearBatch();
for(int i=0;i<sql.length;i++){
stmt.addBatch(sql[i]);
System.out.println("executeBatch:" + sql[i]);
}
re = stmt.executeBatch();
con.commit();
}catch(Exception ex){
ex.printStackTrace();
con.rollback();
}
finally {
if (stmt != null) {
stmt.close();
}
}
return re;
}
/**
*
* @param sql
* @param value
* @param type
* @return
* @throws Exception
*/
public boolean execute(String sql, String[] value, int[] type)
throws Exception {
System.out.println("execute:" + sql);
boolean re = false;
Connection con = null;
PreparedStatement pstmt = null;
try {
con = ConnectionFactory.getInstance().getConnection();
pstmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
this.setParameters(pstmt,value,type); //調用私有方法設置參數
re = pstmt.execute();
} catch(Exception ex){
ex.printStackTrace();
con.rollback();
}finally {
if (pstmt != null) {
pstmt.close();
}
}
return re;
}
/**
* 執行查詢,返回結果集 隱式事物處理
* @param sql String 要執行的SELECT語句
* @return CachedRowSet 未查到記錄則返回null
* @throws Exception
*/
public CachedRowSet executeQueryCachedRowSet(String sql) throws Exception {
System.out.println("executeQueryCachedRowSet:" + sql);
CachedRowSet crs = null;
//OracleCachedRowSet crs=null;
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = ConnectionFactory.getInstance().getConnection();
/*stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
* java.sql.SQLException: 不允許的操作: Unsupported syntax for refreshRow()
* Oracle: Unsupported syntax for refreshRow()報此錯使用以下方式解決
* 1、con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
* 2、con.createStatement();
*/
pstmt=con.prepareStatement(sql);
rs = pstmt.executeQuery();
if (!(rs.isBeforeFirst() == rs.isAfterLast())) {
crs = new CachedRowSetImpl();
//crs = new OracleCachedRowSet();
crs.populate(rs);
}
} catch(Exception ex){
ex.printStackTrace();
con.rollback();
}finally {
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
}
return crs;
}
/**使用OracleCachedRowSet實現,專門處理Oracle特有的SQL語句
* 執行查詢,返回結果集 隱式事物處理
* @param sql String 要執行的SELECT語句
* @return OracleCachedRowSet 未查到記錄則返回null
* @throws Exception
*/
public OracleCachedRowSet executeQueryOracleCachedRowSet(String sql) throws Exception {
System.out.println("executeQueryOracleCachedRowSet:" + sql);
OracleCachedRowSet crs=null;
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = ConnectionFactory.getInstance().getConnection();
/*stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
* java.sql.SQLException: 不允許的操作: Unsupported syntax for refreshRow()
* Oracle: Unsupported syntax for refreshRow()報此錯使用以下方式解決
* 1、con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
* 2、con.createStatement();
*/
pstmt=con.prepareStatement(sql);
rs = pstmt.executeQuery();
if (!(rs.isBeforeFirst() == rs.isAfterLast())) {
crs = new OracleCachedRowSet();
crs.populate(rs);
}
}catch(Exception ex){
ex.printStackTrace();
con.rollback();
} finally {
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
}
return crs;
}
/**
* 執行高效率的SELECT語句,使用ORACLE的SQL特點
* @param sql String 帶?號的SELECT語句
* @param value String[] ?對應的值
* @param type int[] ?對應的值的數據庫表中的類型
* @return CachedRowSet 未查到記錄則返回null
* @throws Exception
*/
public CachedRowSet executeQueryCachedRowSet(String sql, String[] value,
int[] type) throws Exception {
System.out.println("executeQueryRowSet:" + sql);
CachedRowSet crs = null;
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = ConnectionFactory.getInstance().getConnection();
pstmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
this.setParameters(pstmt,value,type); //調用私有方法設置參數
rs = pstmt.executeQuery();
if (!(rs.isBeforeFirst() == rs.isAfterLast())) {
crs = new CachedRowSetImpl();
crs.populate(rs);
}
}catch(Exception ex){
ex.printStackTrace();
con.rollback();
} finally {
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
}
return crs;
}
/**
* 執行查詢,返回Map單條記錄,如查執行結果有多條記錄的情況下也只返回第一條記錄 隱式事物處理
* @param sql String 要執行的SELECT語句
* @return Map 未查到記錄則返回null,使用列名的大家做爲Map的Key,列值對象爲Map的value
* @throws Exception
*/
public Map executeQueryMap(String sql) throws Exception {
System.out.println("executeQueryMap:" + sql);
Map map = null;
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = ConnectionFactory.getInstance().getConnection();
pstmt =con.prepareStatement(sql);
rs = pstmt.executeQuery();
if (rs.next()) { // 有記錄的情況
map = new HashMap();
ResultSetMetaData rsm = rs.getMetaData();
int colnum = rsm.getColumnCount(); // 得到記錄的列數
for (int i = 1; i <= colnum; i++) {
// rsm.getColumnName(i).toUpperCase()統一列名大寫
// rs.getObject(i)更的值爲對象類型
map
.put(rsm.getColumnName(i).toUpperCase(), rs
.getObject(i));
}
}
} catch(Exception ex){
ex.printStackTrace();
con.rollback();
}finally {
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
}
return map;
}
/**
* 執行高效率的SELECT語句,使用ORACLE的SQL特點
* @param sql String 帶?號的SELECT語句
* @param value String[] ?對應的值
* @param type int[] ?對應的值的數據庫表中的類型
* @return Map 未查到記錄則返回null,使用列名的大家做爲Map的Key,列值對象爲Map的value
* @throws Exception
*/
public Map executeQueryMap(String sql, String[] value, int[] type)
throws Exception {
System.out.println("executeQueryMap:" + sql);
Map map = null;
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = ConnectionFactory.getInstance().getConnection();
pstmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
this.setParameters(pstmt,value,type); //調用私有方法設置參數
rs = pstmt.executeQuery();
if (rs.next()) { // 有記錄的情況
map = new HashMap();
ResultSetMetaData rsm = rs.getMetaData();
int colnum = rsm.getColumnCount(); // 得到記錄的列數
for (int i = 1; i <= colnum; i++) {
// rsm.getColumnName(i).toUpperCase()統一列名大寫
// rs.getObject(i)更的值爲對象類型
map
.put(rsm.getColumnName(i).toUpperCase(), rs
.getObject(i));
}
}
} catch(Exception ex){
ex.printStackTrace();
con.rollback();
}finally {
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
}
return map;
}
/**
* 執行更新語句INSERT,UPDATE or DELETE
* @param sql String 要執行的SQL語句
* @return int 如果執行INSERT,UPDATE or DELETE則返回影響的記錄行數,如果執行沒有返回值的語句則返回爲0
* @throws Exception
*/
public int executeUpdate(String sql) throws Exception {
System.out.println("executeUpdate:" + sql);
int re = 0;
Connection con = null;
PreparedStatement pstmt = null;
try {
con = ConnectionFactory.getInstance().getConnection();
pstmt = con.prepareStatement(sql);
re = pstmt.executeUpdate();
}catch(Exception ex){
ex.printStackTrace();
con.rollback();
} finally {
if (pstmt != null) {
pstmt.close();
}
}
return re;
}
/**
* 執行更新語句INSERT,UPDATE or DELETE
* @param sql String 要執行的帶有?號的INSERT,UPDATE or DELETE語句
* @param value String[] ?對應的值
* @param type int[] ?對應的值的數據庫表中的類型
* @return int 如果執行INSERT,UPDATE or DELETE則返回影響的記錄行數,如果執行沒有返回值的語句則返回爲0
* @throws Exception
*/
public int executeUpdate(String sql, String[] value, int[] type)
throws Exception {
System.out.println("executeUpdate:" + sql);
int re = 0;
Connection con = null;
PreparedStatement pstmt = null;
try {
con = ConnectionFactory.getInstance().getConnection();
pstmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
this.setParameters(pstmt,value,type); //調用私有方法設置參數
re = pstmt.executeUpdate(); // 影響的記錄行數
}catch(Exception ex){
ex.printStackTrace();
con.rollback();
} finally {
if (pstmt != null) {
pstmt.close();
}
}
return re;
}
/**
私有方法用來設置
* @param pstmt PreparedStatement對象的參數
* @param value 參數值
* @param type 參數類型
* @throws Exception
*/
private void setParameters(PreparedStatement pstmt,String[] value,int[] type)throws Exception{
int j = 1;
for (int i = 0; i < value.length; i++) {
switch (type[i]) {
case Types.INTEGER:
pstmt.setInt(j, Integer.parseInt(value[i]));
System.out.println("Parameter("+i+") INTEGER "+value[i]);
break;
case Types.FLOAT:
case Types.DOUBLE:
case Types.DECIMAL:
case Types.NUMERIC:
pstmt.setDouble(j, Double.parseDouble(value[i]));
System.out.println("Parameter("+i+") FLOAT、DOUBLE、DECIMAL、NUMERIC "+value[i]);
break;
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGVARCHAR:
pstmt.setString(j, value[i]);
System.out.println("Parameter("+i+") CHAR、VARCHAR、LONGVARCHAR "+value[i]);
break;
case Types.DATE:
case Types.TIMESTAMP:
pstmt.setString(j, value[i]);
System.out.println("Parameter("+i+") DATE、TIMESTAMP "+value[i]);
break;
case Types.BOOLEAN:
// Boolean.parseBoolean(value[i]) JDK5API
pstmt.setBoolean(j, Boolean.getBoolean(value[i]));
System.out.println("Parameter("+i+") BOOLEAN "+value[i]);
break;
}
j = j + 1;
}
}
/**
* 執行記錄的查詢(調用存儲過程)
* @param procName:調用存儲過程的名稱;
* @param returnType:遊標返回類型
* 0爲CachedRowSet以及各種類型
* @param outParameter:傳入輸出參數的類型,例如:new int[]{Types.REF,Types.REF,Types.VARCHAR},
* 表示所調用的存儲過程前兩個輸出結果的類型爲遊標類型,第三個輸出結果的類型爲VARCHAR2類型。
* @param args 所調用存儲過程的輸入參數
* @return List<Object> 存儲過程的輸出結果
*
*/
public List<Object> executeProc(String procName,int returnType,int[] outParameter,Object... args) throws Exception {
List<Object> list = null;
Connection con = null;
CallableStatement cstmt = null;
try {
con = ConnectionFactory.getInstance().getConnection();
int iInStart = 1;// 存儲過程輸入參數的起始位
// 統計問號的個數
int parameterCount = args.length+outParameter.length; //調用的存儲過程的總參數個數
// 組裝帶問號的SQL
String sql = "{call " + procName + "(";
for (int i = 1; i <= parameterCount; i++) {
if (i == parameterCount){
sql += "?";
}else{
sql += "?,";
}
}
sql += ")}";
System.out.println("executeProc:"+sql);
cstmt = con.prepareCall(sql);
for (int i = 0; i < args.length; i++) {// 循環設定存儲過程的輸入參數
cstmt.setObject(iInStart + i, args[i]);
System.out.println("設置輸入參數:"+iInStart+" "+args[i]);
}
int iOutStart = args.length + iInStart;// 存儲過程輸出參數的起始位
for (int i = 0; i < outParameter.length; i++) {// 循環設定存儲過程的輸出參數
if (outParameter[i]==Types.REF){ //代表遊標
cstmt.registerOutParameter(i + iOutStart, oracle.jdbc.driver.OracleTypes.CURSOR);
System.out.println("設置輸出參數:"+(i + iOutStart)+" 遊標");
}else if((outParameter[i]==Types.INTEGER)){
cstmt.registerOutParameter(i + iOutStart, Types.INTEGER);
System.out.println("設置輸出參數:"+(i + iOutStart)+" 數值型");
}else{
cstmt.registerOutParameter(i + iOutStart, Types.VARCHAR);
System.out.println("設置輸出參數:"+(i + iOutStart)+" 字符型");
}
}
cstmt.execute(); //執行
list = new ArrayList<Object>();
switch (returnType) {
case 0:// 把存儲過程中返回的遊標轉換爲CachedRowSet類型輸出
for (int i = 0; i < outParameter.length; i++) {// 循環獲取存儲過程的輸出結果,包括遊標、字符串
if (outParameter[i]==Types.REF) { //處理遊標
CachedRowSet crs=new CachedRowSetImpl();
//OracleCachedRowSet crs=new OracleCachedRowSet(); //使用Oracle10g的數據則必須要用10g的驅動,Oracle 10g驅動解決了“ORA-01002: 讀取違反順序”這個問題
if (cstmt.getObject(i + iOutStart) != null){
crs.populate((ResultSet)cstmt.getObject(i + iOutStart));
}
list.add(crs);
} else{ //非遊標
list.add(cstmt.getObject(i + iOutStart));
}
}
break;
}
} catch (Exception ex) {
ex.printStackTrace();
con.rollback();
} finally {
cstmt.close();
}
return list;
}
public static void main(String[] args) throws Exception {
//DBManager dbm = new DBManager();
//dbm.execute("update dept set dname=? where deptno=? ",new String[]{"sdfsdfsad","51"},new int[]{Types.VARCHAR,Types.NUMERIC});
// Connection con = SingletonDataSource.getInstance().getConnection();
// CachedRowSet crs = dbm.executeQueryRowSet(
// "SELECT EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO FROM EMP WHERE
// EMPNO >7654",
// con);
// while (crs.next()) {
// System.out.println(crs.getString("EMPNO") + " " +
// crs.getString("ENAME"));
// }
// System.out.println("########################");
// Map map = dbm.executeQueryMap(
// "SELECT EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO FROM EMP WHERE
// EMPNO=7654",
// con);
// System.out.println(map.get("EMPNO") + " " + map.get("ENAME") + " " +
// map.get("COMM"));
// con.close();
/*
* String sql = "select * from emp where comm=?"; String[] value = new
* String[] {"500"}; int[] type = {Types.DOUBLE}; Map map =
* dbm.executeQueryMap(sql, value, type, null); //Map map =
* dbm.executeQueryMap("select * from emp where empno=? and ename=?",new
* String[] {"7654","MARTIN"},new int[]{Types.INTEGER,Types.VARCHAR},
* null); if (map != null) { System.out.println(map.get("EMPNO") + " " +
* map.get("ENAME")); }
*/
/*
* String sql = "select * from emp where empno>?"; String[] value = new
* String[] {"7693"}; int[] type = {Types.INTEGER}; CachedRowSet crs =
* dbm.executeQueryRowSet(sql, value, type, null); boolean isprint =
* true; while (crs.next()) { ResultSetMetaData rsmd =
* crs.getMetaData(); int colcount = rsmd.getColumnCount(); if (isprint) {
* isprint=false; for (int i = 0; i < colcount; i++) {
* System.out.print(rsmd.getColumnName(i + 1) + "/t/t"); }
* System.out.println(); } for (int i = 0; i < colcount; i++) {
* System.out.print(crs.getString(i + 1)+"/t/t"); }
* System.out.println(); }
*/
/*
* String sql = "update emp set comm=? where comm=?"; String[] value =
* new String[] {"56.22", "0"}; int[] type = {Types.DOUBLE,
* Types.INTEGER}; System.out.println(dbm.executeUpdate(sql, value,
* type, null));
*/
// System.out.println(dbm.selectList("test", "empno", "ename", true,
// "","select * from emp", null, null));
//DBManager dbmt = new DBManager();
/* //有事物操作示例
dbmt.beginTransaction();
try{
dbmt.execute("insert into emp values (1234, 'TEST', 'TEST', 0, to_date('2008-03-12', 'yyyy-mm-dd'), 0, 0, 10)");
dbmt.execute("insert into emp values (1235, 'TEST', 'TEST', 0, to_date('2008-03-12', 'yyyy-mm-dd'), 0, 0, 10)");
//dbmt.commitTransaction();
}catch(Exception ex){
dbmt.rollbackTransactoin();
}*/
//自動事物處理
//dbmt.execute("insert into emp values (1236, 'TEST', 'TEST', 0, to_date('2008-03-12', 'yyyy-mm-dd'), 0, 0, 10)");
}
}
package jing.dbnew;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
/**
* <p>
* Title: 使用單實例進行數據庫連接池中的數據庫連接獲取
* @author 歐朝敬
* QQ:35712069
* 手機:13873195792
* @version 1.0
*/
public class ConnectionFactory {
private static DataSource ds = null;
private static ConnectionFactory cf = new ConnectionFactory();
private static final ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>(); //線程本地變量
private ConnectionFactory() {
try {
InitialContext ctx = new InitialContext();
// 使用時改成正確的數據配置
//ds = (DataSource) ctx.lookup("jdbc/OracleSource");
//TomCat中的連接池獲取方式使用java:/comp/env/
ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/OracleSource");
} catch (NamingException ne) {
System.out.println(ne.getMessage() + "/n沒有使用連接池!");
}
}
public static ConnectionFactory getInstance() {
return cf;
}
public Connection getConnection() throws Exception {
Connection con = threadLocal.get();
if (con == null) {
if (ds == null) {
// 使用時改成正確的數據配置
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url = "jdbc:oracle:thin:@localhost:1521:sample";
con = DriverManager.getConnection(url, "scott", "tiger");
} else {
con = ds.getConnection();
}
//System.out.println("未使用線程中的連接!");
threadLocal.set(con);
}else{
//System.out.println("使用線程中的連接!");
}
return con;
/**
* 如果不做Main方法的調試則使用如下方法體 return ds.getConnection();
*/
}
/**
* 關閉連接<br>
* 同時刪除當前線程關聯的連接對象,Client不能對用getConnection()方法獲得的連接直接調用con.close()方法,必須使用此方法closeConnection()進行連接的關閉
*/
public void closeConnection() {
Connection con = threadLocal.get();
if (con != null) {
try {
con.close();
threadLocal.set(null);
con=null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception {
/**
* 調用方式如下
*/
Connection con =ConnectionFactory.getInstance().getConnection();
ConnectionFactory.getInstance().closeConnection();
con.createStatement();
}
}
-------------------------------------------------------------------------------------------------
畢業後頭五年決定你的一生 海量Android教程、開發資料和源碼
10類最急需IT人才:Java開發者居首 給將成爲“Android高手”的10個建議
成爲Java高手的25個學習目標--非常經典 Android 4.1果凍豆新特性詳解
芯片巨頭海思和展訊:給中國芯片業帶來信心 海量經典Java教程、學習資料和源碼
Java侵權訴訟Google獲勝,Android厚積薄發 面試必備:Android筆試總結
Android高手必須掌握的28大內容和10個建議 Android平臺研發人才缺口30萬
Android開發環境安裝和配置步驟詳細圖解 2012國內移動App開發者大調查結果
Windows 7下搭建android開發環境步驟圖解 Android 4.0的30個突出的新特性
Android高手要經過的6個階段和6個境界 linux下搭建Android開發環境步驟
從IT菜鳥變爲“IT骨幹開發者”的11個建議 程序員編程技術迅速提高的終極攻略
2012世界各國人均GDP排名,中國超泰國 2012年全國各省平均工資排行
2012年中國大學高校排行榜(580強排名) 中國各省市面積和人口數量排名
中國百萬開發者大調查:程序員的薪水不錯 Java高手需要越過的10座高山
周立功談嵌入式:我的25年嵌入式生涯 Android和Java語言的異同和關係
華爲中國區手機銷量達千萬,80%爲智能機 谷歌Android碎片化嚴重
2012年中國各省GDP和人均GDP排名 90後就業“錢景”:IT仍是最佳選擇
2012全球城市競爭力500強,69箇中國城市上榜 不要做浮躁的軟件工程師
2012年世界500強,79家大陸香港臺灣公司上榜名單 給IT新兵的15個建議
美國知名科技公司入門級軟件工程師的薪水排名 回顧Java經過的風風雨雨
71道經典Android面試題和答案--重要知識點都涉及到了