首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

Java 通用数据库连接种[支持存储过程 参数自动识别]

2012-11-06 
Java 通用数据库连接类[支持存储过程 参数自动识别]package com.hospital.dao.toolsimport java.sql.Call

Java 通用数据库连接类[支持存储过程 参数自动识别]

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;
?}

}

热点排行