package com.db;
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 classDBManager {//--------------------------------------------------------- Instance
private static Logger logger = Logger.getLogger(DBManager.class);//--------------------------------------------------------- Methods//数据库连接对象
privateConnection con;//SQL语句对象
privateStatement stmt;//带参数的Sql语句对象
privatePreparedStatement pstmt;//记录集对象
privateResultSet 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 = "";/** ***********************************************************************/
//默认构造
publicDBManager() {
}/** *******************************************************************************************/
/**
* **************************************** 数据库连接初始化
* ************************************/
/** *******************************************************************************************/
/**
* 得到一个默认的数据库连接[从 com.hospital.dao.tools.db.properties文件初始化]
*
* @throws Exception*/
private voidgetConnection() {
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 voidgetConnection(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);throwex;
}catch(SQLException ex) {
logger
.info("###############Error[com.hospital.dao.tools.DBManager^^^Method:getConnection^^^Line:81]加载类:"
+ driver + "时出现 SQLException 异常");throwex;
}
}/** *******************************************************************************************/
/**
* **************************************** 数据库操作方法
* ************************************/
/** *******************************************************************************************/
/**
* 执行SQL语句操作(更新数据 无参数)
*
* @param strSql
* SQL语句
* @throws Exception*/
publicboolean 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 
close_DB_Object();
flag= true;
con.commit();
}
}catch(SQLException ex) {
logger
.info("###############Error DBManager Line126::执行SQL语句操作(更新数据 无参数):"
+ strSql + "失败!");
flag= false;
con.rollback();throwex;
}returnflag;
}/**
* 执行SQL语句操作(更新数据 有参数)
*
* @param strSql
* sql指令
* @param prams
* 参数列表
* @return
* @throws SQLException*/
public boolean executeUpdate(String strSql, HashMapprams)
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 
close_DB_Object();
flag= true;
con.commit();
}
}catch(SQLException ex) {
logger
.info("###############Error DBManager Line121::执行SQL语句操作(更新数据 无参数):"
+ strSql + "失败!");
flag= false;
con.rollback();throwex;
}catch(ClassNotFoundException ex) {
logger
.info("###############Error DBManager Line152::执行SQL语句操作(更新数据 无参数):"
+ strSql + "失败! 参数设置类型错误!");
con.rollback();throwex;
}returnflag;
}/**
* 执行SQL语句操作(查询数据 无参数)
*
* @param strSql
* SQL语句
* @return 数组对象列表
* @throws Exception*/
public ArrayList>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) {returnconvertResultSetToArrayList(rs);
}
close_DB_Object();return null;
}/**
* 执行SQL语句操作(查询数据 有参数)
*
* @param strSql
* SQL语句
* @param prams
* 参数列表
* @return 数组对象列表
* @throws Exception*/
public ArrayList>executeSql(String strSql,
HashMapprams) 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) {returnconvertResultSetToArrayList(rs);
}return null;
}/**
* 执行存储过程(查询数据 无参数)
*
* @param procName
* 存储过程名称
* @return 数组列表对象
* @throws Exception*/
public ArrayList>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();returnconvertResultSetToArrayList(rs);
}/**
* 执行存储过程(查询数据,带参数)返回结果集合
*
* @param procName
* 存储过程名称
* @param parameters
* 参数对象数组
* @param al
* 数组列表对象
* @return 数组列表对象
* @throws Exception*/
public ArrayList>executeProcedureQuery(
String procName, Object[] parameters) throws Exception {int parameterPoint = 0;//获取存储过程信息列表集合
ArrayList> procedureInfo =getProcedureInfo(procName);//获取存储过程的完全名称
String procedureCallName =getProcedureCallName(procName,parameters.length);//获取连接对象
getConnection();//初始化 存储过程 执行对象
CallableStatement cs =con.prepareCall(procedureCallName);//参数下标变量
int index = 0;//获取 存储过程信息列表集合的 迭代器 对象
Iterator> iter =procedureInfo.iterator();//遍历存储过程信息列表集合
while(iter.hasNext()) {
HashMap 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();returnprocedureInfo;
}/**
* 执行存储过程(更新,查询数据[简单查询、非纪录集],返回输出参数[非纪录集])
*
* @param procName
* 存储过程名称
* @param parameters
* 参数对象数组
* @param os
* 输出参数对象数组
* @return 输出参数对象数组
* @throws Exception*/
publicObject[] 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> p_Call_Info_List =getProcedureInfo(procName);//获取连接
getConnection();//创建 存储过程 执行对象
cs =con.prepareCall(fullPCallName);//数组下标
int index = 1;//输出参数下标 纪录
ArrayList outPutIndexList = new ArrayList();
logger.info("Run --> executeProcedureUpdate # 参数个数是:" + parameters.length +"#");for(HashMaptempHash: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= newObject[outPutIndexList.size()];
logger.info("Run --> executeProcedureUpdate # 执行成功! : #");//取输 出参数的 返回值
for(int i = 0 ;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();throwe;
}
logger.info("------------------------------------------------------------------------------------------------------");returnreturnVal;
}/** *******************************************************************************************/
/**
* ********************************* 小工具
* *************************************************/
/** *******************************************************************************************/
/**
* 关闭数据对象*/
public voidclose_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*/
privatePreparedStatement setParamet(PreparedStatement p_stmt,
HashMappramets) 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) {throwex;
}catch(SQLException ex) {throwex;
}
}
}
}returnp_stmt;
}/**
* 转换记录集对象为数组列表对象
*
* @param rs
* 纪录集合对象
* @return 数组列表对象
* @throws Exception*/
private ArrayList>convertResultSetToArrayList(
ResultSet rs) throws Exception {
logger.info("###############::转换记录集对象为数组列表对象");//获取rs 集合信息对象
ResultSetMetaData rsmd =rs.getMetaData();//创建数组列表集合对象
ArrayList> tempList = new ArrayList>();
HashMap tempHash = null;//填充数组列表集合
while(rs.next()) {//创建键值对集合对象
tempHash = new HashMap();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>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 intgetParametersCount(String procName) throws Exception {int returnVal = 0;for (HashMap 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());
}returnreturnVal;
}/**
* 得到调用存储过程的全名
*
* @param procName
* 存储过程名称
* @return 调用存储过程的全名
* @throws Exception*/
private String getProcedureCallName(String procName, intprametCount)
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 + ")}";returnprocedureCallName;
}/**
* 得到数据类型的整型值
*
* @param typeName
* 类型名称
* @return 数据类型的整型值*/
private intgetDataType(String typeName) {if (typeName.equals("varchar"))returnTypes.VARCHAR;if (typeName.equals("int"))returnTypes.INTEGER;if (typeName.equals("bit"))returnTypes.BIT;if (typeName.equals("float"))returnTypes.FLOAT;return 0;
}//设置驱动路径
@SuppressWarnings("static-access")public voidset_DRIVER(String _DRIVER) {this._DRIVER =_DRIVER;
}//设置数据库密码
@SuppressWarnings("static-access")public voidset_PASSWORD(String _PASSWORD) {this._PASSWORD =_PASSWORD;
}//设置数据库连接字符串
@SuppressWarnings("static-access")public voidset_URL(String _URL) {this._URL =_URL;
}//设置数据库用户名
@SuppressWarnings("static-access")public voidset_USER_NA(String _USER_NA) {this._USER_NA =_USER_NA;
}
}