posts - 495,comments - 227,trackbacks - 0
//http://wing929.javaeye.com/blog/185475
package
 com.hospital.dao.tools;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import org.apache.log4j.Logger;

/**
 * 数据库操作管理类
 * 
 * 
@author Harlyhood
 * 
 
*/
public class DBManager {

    
// --------------------------------------------------------- Instance
    private static Logger logger = Logger.getLogger(DBManager.class);
    
// --------------------------------------------------------- Methods

    
// 数据库连接对象
    private Connection con;
    
// SQL语句对象
    private Statement stmt;
    
// 带参数的Sql语句对象
    private PreparedStatement pstmt;
    
// 记录集对象
    private ResultSet rs;
    
// 数据连接管理(连接池对象)
    private DBConnectionManager dcm = null;

    
/** ***********************手动设置的连接参数********************************* */
    @SuppressWarnings(
"unused")
    
private static String _DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
    @SuppressWarnings(
"unused")
    
private static String _URL = "jdbc:sqlserver://localhost:1433;database=Hospital_AI_DB;characterEncoding=gb2312";
    @SuppressWarnings(
"unused")
    
private static String _USER_NA = "sa";
    @SuppressWarnings(
"unused")
    
private static String _PASSWORD = "";

    
/** ********************************************************************** */

    
// 默认构造
    public DBManager() {
    }

    
/** ****************************************************************************************** */
    
/**
     * **************************************** 数据库连接初始化
     * ***********************************
     
*/
    
/** ****************************************************************************************** */

    
/**
     * 得到一个默认的数据库连接[从 com.hospital.dao.tools.db.properties文件初始化]
     * 
     * 
@throws Exception
     
*/
    
private void getConnection() {
        logger.info(
"###############open:::::从默认的配置文件得到一个数据库连接");
        
// 获取一个连接池管理类的实例
        dcm = DBConnectionManager.getInstance();
        
// 得到一个数据库连接
        con = dcm.getConnection("mysql");

        
try {
            con.setAutoCommit(
false);
        } 
catch (SQLException e) {

            e.printStackTrace();
        }
    }

    
/**
     * 从指定参数得到一个连接对象
     * 
     * 
@param driver
     * 
@param url
     * 
@param user_na
     * 
@param password
     * 
@throws Exception
     
*/
    
public void getConnection(String driver, String url, String user_na,
            String password) 
throws Exception {
        
try {
            logger.info(
"###############open:::::从指定配置中得到一个数据库连接");
            Class.forName(driver);
            con 
= DriverManager.getConnection(url, user_na, password);
        } 
catch (ClassNotFoundException ex) {
            logger
                    .info(
"###############Error[com.hospital.dao.tools.DBManager^^^Method:getConnection^^^Line:81]找不到类驱动类: "
                            
+ driver);
            
throw ex;
        } 
catch (SQLException ex) {
            logger
                    .info(
"###############Error[com.hospital.dao.tools.DBManager^^^Method:getConnection^^^Line:81]加载类: "
                            
+ driver + " 时出现 SQLException 异常");
            
throw ex;
        }
    }

    
/** ****************************************************************************************** */
    
/**
     * **************************************** 数据库操作方法
     * ***********************************
     
*/
    
/** ****************************************************************************************** */

    
/**
     * 执行SQL语句操作(更新数据 无参数)
     * 
     * 
@param strSql
     *            SQL语句
     * 
@throws Exception
     
*/
    
public boolean executeUpdate(String strSql) throws SQLException {
        getConnection();
        
// getConnection(_DRIVER,_URL,_USER_NA,_PASSWORD);
        boolean flag = false;
        stmt 
= con.createStatement();
        logger.info(
"###############::执行SQL语句操作(更新数据 无参数):" + strSql);
        
try {
            
if (0 < stmt.executeUpdate(strSql)) {
                close_DB_Object();
                flag 
= true;
                con.commit();
            }
        } 
catch (SQLException ex) {
            logger
                    .info(
"###############Error DBManager Line126::执行SQL语句操作(更新数据 无参数):"
                            
+ strSql + "失败!");
            flag 
= false;
            con.rollback();
            
throw ex;
        }
        
return flag;

    }

    
/**
     * 执行SQL语句操作(更新数据 有参数)
     * 
     * 
@param strSql
     *            sql指令
     * 
@param prams
     *            参数列表
     * 
@return
     * 
@throws SQLException
     
*/
    
public boolean executeUpdate(String strSql, HashMap<Integer, Object> prams)
            
throws SQLException, ClassNotFoundException {
        getConnection();
        
// getConnection(_DRIVER,_URL,_USER_NA,_PASSWORD);
        boolean flag = false;
        
try {
            pstmt 
= con.prepareStatement(strSql);
            setParamet(pstmt, prams);
            logger.info(
"###############::执行SQL语句操作(更新数据 有参数):" + strSql);

            
if (0 < pstmt.executeUpdate()) {
                close_DB_Object();
                flag 
= true;
                con.commit();
            }
        } 
catch (SQLException ex) {
            logger
                    .info(
"###############Error DBManager Line121::执行SQL语句操作(更新数据 无参数):"
                            
+ strSql + "失败!");
            flag 
= false;
            con.rollback();
            
throw ex;
        } 
catch (ClassNotFoundException ex) {
            logger
                    .info(
"###############Error DBManager Line152::执行SQL语句操作(更新数据 无参数):"
                            
+ strSql + "失败! 参数设置类型错误!");
            con.rollback();
            
throw ex;
        }
        
return flag;

    }

    
/**
     * 执行SQL语句操作(查询数据 无参数)
     * 
     * 
@param strSql
     *            SQL语句
     * 
@return 数组对象列表
     * 
@throws Exception
     
*/
    
public ArrayList<HashMap<Object, Object>> executeSql(String strSql)
            
throws Exception {
        getConnection();
        
// getConnection(_DRIVER,_URL,_USER_NA,_PASSWORD);
        stmt = con.createStatement();
        logger.info(
"###############::执行SQL语句操作(查询数据):" + strSql);
        rs 
= stmt.executeQuery(strSql);
        con.commit();
        
if (null != rs) {
            
return convertResultSetToArrayList(rs);
        }
        close_DB_Object();
        
return null;
    }

    
/**
     * 执行SQL语句操作(查询数据 有参数)
     * 
     * 
@param strSql
     *            SQL语句
     * 
@param prams
     *            参数列表
     * 
@return 数组对象列表
     * 
@throws Exception
     
*/
    
public ArrayList<HashMap<Object, Object>> executeSql(String strSql,
            HashMap
<Integer, Object> prams) throws Exception {
        getConnection();
        
// getConnection(_DRIVER,_URL,_USER_NA,_PASSWORD);
        pstmt = con.prepareStatement(strSql);
        setParamet(pstmt, prams);
        logger.info(
"###############::执行SQL语句操作(查询数据):" + strSql);
        rs 
= pstmt.executeQuery();
        con.commit();
        
if (null != rs) {
            
return convertResultSetToArrayList(rs);
        }
        
return null;
    }

    
/**
     * 执行存储过程(查询数据 无参数)
     * 
     * 
@param procName
     *            存储过程名称
     * 
@return 数组列表对象
     * 
@throws Exception
     
*/
    
public ArrayList<HashMap<Object, Object>> executeProcedureQuery(
            String procName) 
throws Exception {
        getConnection();
// 获取连接
        String callStr = "{call " + procName + "}";// 构造执行存储过程的sql指令
        CallableStatement cs = con.prepareCall(callStr);
        logger.info(
"###############::执行存储过程(查询数据):" + procName);
        rs 
= cs.executeQuery();
        con.commit();
        cs.close();
        close_DB_Object();
        
return convertResultSetToArrayList(rs);
    }

    
/**
     * 执行存储过程(查询数据,带参数)返回结果集合
     * 
     * 
@param procName
     *            存储过程名称
     * 
@param parameters
     *            参数对象数组
     * 
@param al
     *            数组列表对象
     * 
@return 数组列表对象
     * 
@throws Exception
     
*/
    
public ArrayList<HashMap<Object, Object>> executeProcedureQuery(
            String procName, Object[] parameters) 
throws Exception {
        
int parameterPoint = 0;
        
// 获取存储过程信息列表集合
        ArrayList<HashMap<Object, Object>> procedureInfo = getProcedureInfo(procName);
        
// 获取存储过程的完全名称
        String procedureCallName = getProcedureCallName(procName,parameters.length);
        
// 获取连接对象
        getConnection();
        
// 初始化 存储过程 执行对象
        CallableStatement cs = con.prepareCall(procedureCallName);
        
// 参数下标变量
        int index = 0;
        
// 获取 存储过程信息列表集合的 迭代器 对象
        Iterator<HashMap<Object, Object>> iter = procedureInfo.iterator();
        
// 遍历存储过程信息列表集合
        while (iter.hasNext()) {
            HashMap
<Object, Object> hm = iter.next();

            parameterPoint
++;
            
// 如果参数是输入参数 way = 0
            if (hm.get("WAY").equals("0")) {
                
// 设置参数到cs
                cs.setObject(parameterPoint, parameters[index]);
                
// 参数下标+1
                index++;
            }
        }
        
// 释放这个对象,做为第二次使用
        procedureInfo = null;
        logger.info(
"###############::执行存储过程(查询数据):::::" + procedureCallName);
        rs 
= cs.executeQuery();
        con.commit();
        procedureInfo 
= convertResultSetToArrayList(rs);
        cs.close();
        close_DB_Object();
        
return procedureInfo;

    }

    
/**
     * 执行存储过程(更新,查询数据[简单查询、非纪录集],返回输出参数[非纪录集])
     * 
     * 
@param procName
     *            存储过程名称
     * 
@param parameters
     *            参数对象数组
     * 
@param os
     *            输出参数对象数组
     * 
@return 输出参数对象数组
     * 
@throws Exception
     
*/
    
public Object[] executeProcedureUpdate(String procName, Object[] parameters)
            
throws Exception {
        logger.info(
"------------------------------------------------------------------------------------------------------");
        logger.info(
" Run --> executeProcedureUpdate ##############   正在执行 存储过程: " + procName +"   ##############");
        CallableStatement cs 
= null;
        Object []returnVal 
= null;
        
try {
        
// 获取 存储过程 调用全名
        String fullPCallName = getProcedureCallName(procName,parameters.length);
        logger.info(
" Run --> executeProcedureUpdate #   存储过程命令: " + fullPCallName +"   #");
        
//获取存储过程参数信息
        ArrayList<HashMap<Object, Object>> p_Call_Info_List = getProcedureInfo(procName);
        
//获取连接
        getConnection();
        
//创建 存储过程 执行对象
        cs = con.prepareCall(fullPCallName);
        
//数组下标
        int index = 1;
        
//输出参数下标 纪录
        ArrayList<Integer> outPutIndexList = new ArrayList<Integer>();
        logger.info(
" Run --> executeProcedureUpdate #   参数个数是: " + parameters.length +"   #");
        
for(HashMap<Object,Object> tempHash:p_Call_Info_List)
        {
            
if("0".equals(tempHash.get("WAY")))
            {
                
//设置输入参数
                cs.setObject(index, parameters[index-1]);
                logger.info(
" Run --> executeProcedureUpdate #   输入 Input: 编号:" + index +" 值: "+parameters[index-1]+" 类型: "+parameters[index-1].getClass()+"   #");
            }
            
else
            {
                
//注册输出参数
                cs.registerOutParameter(index, getDataType(tempHash.get("TYPENAME").toString()));
                
//纪录输出参数的下标
                outPutIndexList.add(index);
                logger.info(
" Run --> executeProcedureUpdate #   输出 OutPut: 编号:" + index +" 值: "+parameters[index-1]+" 类型: "+parameters[index-1].getClass()+"   #");
            }
            index
++;
        }
        logger.info(
" Run --> executeProcedureUpdate #   参数设置完毕,正在执行中  :   #");
        
        
//-------------------- 执行 -----------------
        if(!cs.execute())
        {
            returnVal 
= new Object[outPutIndexList.size()];
            logger.info(
" Run --> executeProcedureUpdate #   执行成功! :   #");
            
//取输 出参数的 返回值
            for(int i = 0 ;i<outPutIndexList.size();i++)
            {
                returnVal[i] 
= cs.getObject(outPutIndexList.get(i));
                logger.info(
" Run --> executeProcedureUpdate #   返回值 "+(i+1)+" "+returnVal[i]+"   #");
            }
            con.commit();
//提交
        }
        } 
catch (Exception e) {
            logger.info(
" Run --> executeProcedureUpdate #   执行失败!事务回滚中 :   #");
            con.rollback();
            
throw e;
        } 
        logger.info(
"------------------------------------------------------------------------------------------------------");
        
return returnVal;
    }

    
/** ****************************************************************************************** */
    
/**
     * ********************************* 小工具
     * ************************************************
     
*/
    
/** ****************************************************************************************** */

    
/**
     * 关闭数据对象
     
*/
    
public void close_DB_Object() {
        logger.info(
"###############close:::::关闭连接对象,语句对象,记录集对象");
        
if (null != rs) {
            
try {
                rs.close();
            } 
catch (SQLException ex) {
                rs 
= null;
            }
        }
        
if (null != stmt) {
            
try {
                stmt.close();
            } 
catch (SQLException ex) {
                stmt 
= null;
            }
        }
        
if (null != pstmt) {
            
try {
                pstmt.close();
            } 
catch (SQLException ex) {
                pstmt 
= null;
            }
        }
        
if (con != null) {
            dcm.freeConnection(
"mysql", con);
        }
    }


    
/**
     * 设置Sql 指令参数
     * 
     * 
@param p_stmt
     *            PreparedStatement
     * 
@param pramets
     *            HashMap
     
*/
    
private PreparedStatement setParamet(PreparedStatement p_stmt,
            HashMap
<Integer, Object> pramets) throws ClassNotFoundException,
            SQLException {
        
// 如果参数为空
        if (null != pramets) {
            
// 如果参数个数为0
            if (0 <= pramets.size()) {
                
for (int i = 1; i <= pramets.size(); i++) {
                    
try {
                        
// 字符类型 String
                        if (pramets.get(i).getClass() == Class
                                .forName(
"java.lang.String")) {
                            p_stmt.setString(i, pramets.get(i).toString());
                        }
                        
// 日期类型 Date
                        if (pramets.get(i).getClass() == Class
                                .forName(
"java.sql.Date")) {
                            p_stmt.setDate(i, java.sql.Date.valueOf(pramets
                                    .get(i).toString()));
                        }
                        
// 布尔类型 Boolean
                        if (pramets.get(i).getClass() == Class
                                .forName(
"java.lang.Boolean")) {
                            p_stmt.setBoolean(i, (Boolean) (pramets.get(i)));
                        }
                        
// 整型 int
                        if (pramets.get(i).getClass() == Class
                                .forName(
"java.lang.Integer")) {
                            p_stmt.setInt(i, (Integer) pramets.get(i));
                        }
                        
// 浮点 float
                        if (pramets.get(i).getClass() == Class
                                .forName(
"java.lang.Float")) {
                            p_stmt.setFloat(i, (Float) pramets.get(i));
                        }
                        
// 双精度型 double
                        if (pramets.get(i).getClass() == Class
                                .forName(
"java.lang.Double")) {
                            p_stmt.setDouble(i, (Double) pramets.get(i));
                        }

                    } 
catch (ClassNotFoundException ex) {
                        
throw ex;
                    } 
catch (SQLException ex) {
                        
throw ex;
                    }
                }
            }
        }
        
return p_stmt;
    }

    
/**
     * 转换记录集对象为数组列表对象
     * 
     * 
@param rs
     *            纪录集合对象
     * 
@return 数组列表对象
     * 
@throws Exception
     
*/
    
private ArrayList<HashMap<Object, Object>> convertResultSetToArrayList(
            ResultSet rs) 
throws Exception {
        logger.info(
"###############::转换记录集对象为数组列表对象");
        
// 获取rs 集合信息对象
        ResultSetMetaData rsmd = rs.getMetaData();
        
// 创建数组列表集合对象
        ArrayList<HashMap<Object, Object>> tempList = new ArrayList<HashMap<Object, Object>>();
        HashMap
<Object, Object> tempHash = null;
        
// 填充数组列表集合
        while (rs.next()) {
            
// 创建键值对集合对象
            tempHash = new HashMap<Object, Object>();
            
for (int i = 0; i < rsmd.getColumnCount(); i++) {
                
// 遍历每列数据,以键值形式存在对象tempHash中
                tempHash.put(rsmd.getColumnName(i + 1).toUpperCase(), rs
                        .getString(rsmd.getColumnName(i 
+ 1)));
            }
            
// 第一个键值对,存储在tempList列表集合对象中
            tempList.add(tempHash);
        }
        close_DB_Object();
// 关闭相关链接
        return tempList;// 返回填充完毕的数组列表集合对象
    }

    
/**
     * 从数据库得到存储过程信息
     * 
     * 
@param procName
     *            存储过程名称
     * 
@return 数组列表对象
     * 
@throws Exception
     
*/
    
private ArrayList<HashMap<Object, Object>> getProcedureInfo(String procName)
            
throws Exception {
        
return this.executeSql("select Syscolumns.isoutparam as Way,systypes.name as TypeName from sysobjects,syscolumns,systypes where systypes.xtype=syscolumns.xtype and syscolumns.id=sysobjects.id and sysobjects.name='"
                
+ procName + "' order by Syscolumns.isoutparam");
    }

    
/**
     * 从数据库得到存储过程参数个数
     * 
     * 
@param procName
     *            存储过程名称
     * 
@return 数组列表对象
     * 
@throws Exception
     
*/
    @SuppressWarnings(
"unused")
    
private int getParametersCount(String procName) throws Exception {
        
int returnVal = 0;
        
for (HashMap<Object, Object> tempHas : this
                .executeSql(
"select count(*) as RowsCount from sysobjects,syscolumns,systypes where systypes.xtype=syscolumns.xtype and syscolumns.id=sysobjects.id and sysobjects.name='"
                        
+ procName + "'")) {
            returnVal 
= Integer.parseInt(tempHas.get("ROWSCOUNT").toString());
        }
        
return returnVal;
    }

    
/**
     * 得到调用存储过程的全名
     * 
     * 
@param procName
     *            存储过程名称
     * 
@return 调用存储过程的全名
     * 
@throws Exception
     
*/
    
private String getProcedureCallName(String procName, int prametCount)
            
throws Exception {
        String procedureCallName 
= "{call " + procName;
        
for (int i = 0; i < prametCount; i++) {
            
if (0 == i) {
                procedureCallName 
= procedureCallName + "(?";
            }
            
if (0 != i) {
                procedureCallName 
= procedureCallName + ",?";
            }
        }
        procedureCallName 
= procedureCallName + ")}";
        
return procedureCallName;
    }

    
/**
     * 得到数据类型的整型值
     * 
     * 
@param typeName
     *            类型名称
     * 
@return 数据类型的整型值
     
*/
    
private int getDataType(String typeName) {
        
if (typeName.equals("varchar"))
            
return Types.VARCHAR;
        
if (typeName.equals("int"))
            
return Types.INTEGER;
        
if (typeName.equals("bit"))
            
return Types.BIT;
        
if (typeName.equals("float"))
            
return Types.FLOAT;
        
return 0;
    }

    
// 设置驱动路径
    @SuppressWarnings("static-access")
    
public void set_DRIVER(String _DRIVER) {
        
this._DRIVER = _DRIVER;
    }

    
// 设置数据库密码
    @SuppressWarnings("static-access")
    
public void set_PASSWORD(String _PASSWORD) {
        
this._PASSWORD = _PASSWORD;
    }

    
// 设置数据库连接字符串
    @SuppressWarnings("static-access")
    
public void set_URL(String _URL) {
        
this._URL = _URL;
    }

    
// 设置数据库用户名
    @SuppressWarnings("static-access")
    
public void set_USER_NA(String _USER_NA) {
        
this._USER_NA = _USER_NA;
    }

}
posted on 2010-09-11 05:33 SIMONE 阅读(2268) 评论(1)  编辑  收藏 所属分类: JAVA

FeedBack:
# re: Java 通用数据库连接类[支持存储过程 参数自动识别]
2010-09-19 07:27 | 纽斯丽
我不学JAVA的我学C#差不多  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: