JDBC操作数据库

来源:互联网 发布:python必备书 编辑:程序博客网 时间:2024/05/03 12:27
  package com.hospital.dao.tools;     3.  import java.sql.CallableStatement;  4.  import java.sql.Connection;  5.  import java.sql.DriverManager;  6.  import java.sql.PreparedStatement;  7.  import java.sql.ResultSet;  8.  import java.sql.ResultSetMetaData;  9.  import java.sql.SQLException;  10. import java.sql.Statement;  11. import java.sql.Types;  12. import java.util.ArrayList;  13. import java.util.HashMap;  14. import java.util.Iterator;  15. import org.apache.log4j.Logger;  16.   17. /** 18.  * 数据库操作管理类 19.  *  20.  * @author Harlyhood 21.  *  22.  */  23. public class DBManager {  24.   25.     // --------------------------------------------------------- Instance  26.     private static Logger logger = Logger.getLogger(DBManager.class);  27.     // --------------------------------------------------------- Methods  28.   29.     // 数据库连接对象  30.     private Connection con;  31.     // SQL语句对象  32.     private Statement stmt;  33.     // 带参数的Sql语句对象  34.     private PreparedStatement pstmt;  35.     // 记录集对象  36.     private ResultSet rs;  37.     // 数据连接管理(连接池对象)  38.     private DBConnectionManager dcm = null;  39.   40.     /** ***********************手动设置的连接参数********************************* */  41.     @SuppressWarnings("unused")  42.     private static String _DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver";  43.     @SuppressWarnings("unused")  44.     private static String _URL = "jdbc:sqlserver://localhost:1433;database=Hospital_AI_DB;characterEncoding=gb2312";  45.     @SuppressWarnings("unused")  46.     private static String _USER_NA = "sa";  47.     @SuppressWarnings("unused")  48.     private static String _PASSWORD = "";  49.   50.     /** ********************************************************************** */  51.   52.     // 默认构造  53.     public DBManager() {  54.     }  55.   56.     /** ****************************************************************************************** */  57.     /** 58.      * **************************************** 数据库连接初始化 59.      * *********************************** 60.      */  61.     /** ****************************************************************************************** */  62.   63.     /** 64.      * 得到一个默认的数据库连接[从 com.hospital.dao.tools.db.properties文件初始化] 65.      *  66.      * @throws Exception 67.      */  68.     private void getConnection() {  69.         logger.info("###############open:::::从默认的配置文件得到一个数据库连接");  70.         // 获取一个连接池管理类的实例  71.         dcm = DBConnectionManager.getInstance();  72.         // 得到一个数据库连接  73.         con = dcm.getConnection("mysql");  74.   75.         try {  76.             con.setAutoCommit(false);  77.         } catch (SQLException e) {  78.   79.             e.printStackTrace();  80.         }  81.     }  82.   83.     /** 84.      * 从指定参数得到一个连接对象 85.      *  86.      * @param driver 87.      * @param url 88.      * @param user_na 89.      * @param password 90.      * @throws Exception 91.      */  92.     public void getConnection(String driver, String url, String user_na,  93.             String password) throws Exception {  94.         try {  95.             logger.info("###############open:::::从指定配置中得到一个数据库连接");  96.             Class.forName(driver);  97.             con = DriverManager.getConnection(url, user_na, password);  98.         } catch (ClassNotFoundException ex) {  99.             logger  100.                      .info("###############Error[com.hospital.dao.tools.DBManager^^^Method:getConnection^^^Line:81]找不到类驱动类: "  101.                              + driver);  102.              throw ex;  103.          } catch (SQLException ex) {  104.              logger  105.                      .info("###############Error[com.hospital.dao.tools.DBManager^^^Method:getConnection^^^Line:81]加载类: "  106.                              + driver + " 时出现 SQLException 异常");  107.              throw ex;  108.          }  109.      }  110.    111.      /** ****************************************************************************************** */  112.      /** 113.       * **************************************** 数据库操作方法 114.       * *********************************** 115.       */  116.      /** ****************************************************************************************** */  117.    118.      /** 119.       * 执行SQL语句操作(更新数据 无参数) 120.       *  121.       * @param strSql 122.       *            SQL语句 123.       * @throws Exception 124.       */  125.      public boolean executeUpdate(String strSql) throws SQLException {  126.          getConnection();  127.          // getConnection(_DRIVER,_URL,_USER_NA,_PASSWORD);  128.          boolean flag = false;  129.          stmt = con.createStatement();  130.          logger.info("###############::执行SQL语句操作(更新数据 无参数):" + strSql);  131.          try {  132.              if (0 < stmt.executeUpdate(strSql)) {  133.                  close_DB_Object();  134.                  flag = true;  135.                  con.commit();  136.              }  137.          } catch (SQLException ex) {  138.              logger  139.                      .info("###############Error DBManager Line126::执行SQL语句操作(更新数据 无参数):"  140.                              + strSql + "失败!");  141.              flag = false;  142.              con.rollback();  143.              throw ex;  144.          }  145.          return flag;  146.    147.      }  148.    149.      /** 150.       * 执行SQL语句操作(更新数据 有参数) 151.       *  152.       * @param strSql 153.       *            sql指令 154.       * @param prams 155.       *            参数列表 156.       * @return 157.       * @throws SQLException 158.       */  159.      public boolean executeUpdate(String strSql, HashMap<Integer, Object> prams)  160.              throws SQLException, ClassNotFoundException {  161.          getConnection();  162.          // getConnection(_DRIVER,_URL,_USER_NA,_PASSWORD);  163.          boolean flag = false;  164.          try {  165.              pstmt = con.prepareStatement(strSql);  166.              setParamet(pstmt, prams);  167.              logger.info("###############::执行SQL语句操作(更新数据 有参数):" + strSql);  168.    169.              if (0 < pstmt.executeUpdate()) {  170.                  close_DB_Object();  171.                  flag = true;  172.                  con.commit();  173.              }  174.          } catch (SQLException ex) {  175.              logger  176.                      .info("###############Error DBManager Line121::执行SQL语句操作(更新数据 无参数):"  177.                              + strSql + "失败!");  178.              flag = false;  179.              con.rollback();  180.              throw ex;  181.          } catch (ClassNotFoundException ex) {  182.              logger  183.                      .info("###############Error DBManager Line152::执行SQL语句操作(更新数据 无参数):"  184.                              + strSql + "失败! 参数设置类型错误!");  185.              con.rollback();  186.              throw ex;  187.          }  188.          return flag;  189.    190.      }  191.    192.      /** 193.       * 执行SQL语句操作(查询数据 无参数) 194.       *  195.       * @param strSql 196.       *            SQL语句 197.       * @return 数组对象列表 198.       * @throws Exception 199.       */  200.      public ArrayList<HashMap<Object, Object>> executeSql(String strSql)  201.              throws Exception {  202.          getConnection();  203.          // getConnection(_DRIVER,_URL,_USER_NA,_PASSWORD);  204.          stmt = con.createStatement();  205.          logger.info("###############::执行SQL语句操作(查询数据):" + strSql);  206.          rs = stmt.executeQuery(strSql);  207.          con.commit();  208.          if (null != rs) {  209.              return convertResultSetToArrayList(rs);  210.          }  211.          close_DB_Object();  212.          return null;  213.      }  214.    215.      /** 216.       * 执行SQL语句操作(查询数据 有参数) 217.       *  218.       * @param strSql 219.       *            SQL语句 220.       * @param prams 221.       *            参数列表 222.       * @return 数组对象列表 223.       * @throws Exception 224.       */  225.      public ArrayList<HashMap<Object, Object>> executeSql(String strSql,  226.              HashMap<Integer, Object> prams) throws Exception {  227.          getConnection();  228.          // getConnection(_DRIVER,_URL,_USER_NA,_PASSWORD);  229.          pstmt = con.prepareStatement(strSql);  230.          setParamet(pstmt, prams);  231.          logger.info("###############::执行SQL语句操作(查询数据):" + strSql);  232.          rs = pstmt.executeQuery();  233.          con.commit();  234.          if (null != rs) {  235.              return convertResultSetToArrayList(rs);  236.          }  237.          return null;  238.      }  239.    240.      /** 241.       * 执行存储过程(查询数据 无参数) 242.       *  243.       * @param procName 244.       *            存储过程名称 245.       * @return 数组列表对象 246.       * @throws Exception 247.       */  248.      public ArrayList<HashMap<Object, Object>> executeProcedureQuery(  249.              String procName) throws Exception {  250.          getConnection();// 获取连接  251.          String callStr = "{call " + procName + "}";// 构造执行存储过程的sql指令  252.          CallableStatement cs = con.prepareCall(callStr);  253.          logger.info("###############::执行存储过程(查询数据):" + procName);  254.          rs = cs.executeQuery();  255.          con.commit();  256.          cs.close();  257.          close_DB_Object();  258.          return convertResultSetToArrayList(rs);  259.      }  260.    261.      /** 262.       * 执行存储过程(查询数据,带参数)返回结果集合 263.       *  264.       * @param procName 265.       *            存储过程名称 266.       * @param parameters 267.       *            参数对象数组 268.       * @param al 269.       *            数组列表对象 270.       * @return 数组列表对象 271.       * @throws Exception 272.       */  273.      public ArrayList<HashMap<Object, Object>> executeProcedureQuery(  274.              String procName, Object[] parameters) throws Exception {  275.          int parameterPoint = 0;  276.          // 获取存储过程信息列表集合  277.          ArrayList<HashMap<Object, Object>> procedureInfo = getProcedureInfo(procName);  278.          // 获取存储过程的完全名称  279.          String procedureCallName = getProcedureCallName(procName,parameters.length);  280.          // 获取连接对象  281.          getConnection();  282.          // 初始化 存储过程 执行对象  283.          CallableStatement cs = con.prepareCall(procedureCallName);  284.          // 参数下标变量  285.          int index = 0;  286.          // 获取 存储过程信息列表集合的 迭代器 对象  287.          Iterator<HashMap<Object, Object>> iter = procedureInfo.iterator();  288.          // 遍历存储过程信息列表集合  289.          while (iter.hasNext()) {  290.              HashMap<Object, Object> hm = iter.next();  291.    292.              parameterPoint++;  293.              // 如果参数是输入参数 way = 0  294.              if (hm.get("WAY").equals("0")) {  295.                  // 设置参数到cs  296.                  cs.setObject(parameterPoint, parameters[index]);  297.                  // 参数下标+1  298.                  index++;  299.              }  300.          }  301.          // 释放这个对象,做为第二次使用  302.          procedureInfo = null;  303.          logger.info("###############::执行存储过程(查询数据):::::" + procedureCallName);  304.          rs = cs.executeQuery();  305.          con.commit();  306.          procedureInfo = convertResultSetToArrayList(rs);  307.          cs.close();  308.          close_DB_Object();  309.          return procedureInfo;  310.    311.      }  312.    313.      /** 314.       * 执行存储过程(更新,查询数据[简单查询、非纪录集],返回输出参数[非纪录集]) 315.       *  316.       * @param procName 317.       *            存储过程名称 318.       * @param parameters 319.       *            参数对象数组 320.       * @param os 321.       *            输出参数对象数组 322.       * @return 输出参数对象数组 323.       * @throws Exception 324.       */  325.      public Object[] executeProcedureUpdate(String procName, Object[] parameters)  326.              throws Exception {  327.          logger.info("------------------------------------------------------------------------------------------------------");  328.          logger.info(" Run --> executeProcedureUpdate ##############   正在执行 存储过程: " + procName +"   ##############");  329.          CallableStatement cs = null;  330.          Object []returnVal = null;  331.          try {  332.          // 获取 存储过程 调用全名  333.          String fullPCallName = getProcedureCallName(procName,parameters.length);  334.          logger.info(" Run --> executeProcedureUpdate #   存储过程命令: " + fullPCallName +"   #");  335.          //获取存储过程参数信息  336.          ArrayList<HashMap<Object, Object>> p_Call_Info_List = getProcedureInfo(procName);  337.          //获取连接  338.          getConnection();  339.          //创建 存储过程 执行对象  340.          cs = con.prepareCall(fullPCallName);  341.          //数组下标  342.          int index = 1;  343.          //输出参数下标 纪录  344.          ArrayList<Integer> outPutIndexList = new ArrayList<Integer>();  345.          logger.info(" Run --> executeProcedureUpdate #   参数个数是: " + parameters.length +"   #");  346.          for(HashMap<Object,Object> tempHash:p_Call_Info_List)  347.          {  348.              if("0".equals(tempHash.get("WAY")))  349.              {  350.                  //设置输入参数  351.                  cs.setObject(index, parameters[index-1]);  352.                  logger.info(" Run --> executeProcedureUpdate #   输入 Input: 编号:" + index +" 值: "+parameters[index-1]+" 类型: "+parameters[index-1].getClass()+"   #");  353.              }  354.              else  355.              {  356.                  //注册输出参数  357.                  cs.registerOutParameter(index, getDataType(tempHash.get("TYPENAME").toString()));  358.                  //纪录输出参数的下标  359.                  outPutIndexList.add(index);  360.                  logger.info(" Run --> executeProcedureUpdate #   输出 OutPut: 编号:" + index +" 值: "+parameters[index-1]+" 类型: "+parameters[index-1].getClass()+"   #");  361.              }  362.              index++;  363.          }  364.          logger.info(" Run --> executeProcedureUpdate #   参数设置完毕,正在执行中 ... :   #");  365.            366.          //-------------------- 执行 -----------------  367.          if(!cs.execute())  368.          {  369.              returnVal = new Object[outPutIndexList.size()];  370.              logger.info(" Run --> executeProcedureUpdate #   执行成功! :   #");  371.              //取输 出参数的 返回值  372.              for(int i = 0 ;i<outPutIndexList.size();i++)  373.              {  374.                  returnVal[i] = cs.getObject(outPutIndexList.get(i));  375.                  logger.info(" Run --> executeProcedureUpdate #   返回值 "+(i+1)+" "+returnVal[i]+"   #");  376.              }  377.              con.commit();//提交  378.          }  379.          } catch (Exception e) {  380.              logger.info(" Run --> executeProcedureUpdate #   执行失败!事务回滚中... :   #");  381.              con.rollback();  382.              throw e;  383.          }   384.          logger.info("------------------------------------------------------------------------------------------------------");  385.          return returnVal;  386.      }  387.    388.      /** ****************************************************************************************** */  389.      /** 390.       * ********************************* 小工具 391.       * ************************************************ 392.       */  393.      /** ****************************************************************************************** */  394.    395.      /** 396.       * 关闭数据对象 397.       */  398.      public void close_DB_Object() {  399.          logger.info("###############close:::::关闭连接对象,语句对象,记录集对象");  400.          if (null != rs) {  401.              try {  402.                  rs.close();  403.              } catch (SQLException ex) {  404.                  rs = null;  405.              }  406.          }  407.          if (null != stmt) {  408.              try {  409.                  stmt.close();  410.              } catch (SQLException ex) {  411.                  stmt = null;  412.              }  413.          }  414.          if (null != pstmt) {  415.              try {  416.                  pstmt.close();  417.              } catch (SQLException ex) {  418.                  pstmt = null;  419.              }  420.          }  421.          if (con != null) {  422.              dcm.freeConnection("mysql", con);  423.          }  424.      }  425.    426.    427.      /** 428.       * 设置Sql 指令参数 429.       *  430.       * @param p_stmt 431.       *            PreparedStatement 432.       * @param pramets 433.       *            HashMap 434.       */  435.      private PreparedStatement setParamet(PreparedStatement p_stmt,  436.              HashMap<Integer, Object> pramets) throws ClassNotFoundException,  437.              SQLException {  438.          // 如果参数为空  439.          if (null != pramets) {  440.              // 如果参数个数为0  441.              if (0 <= pramets.size()) {  442.                  for (int i = 1; i <= pramets.size(); i++) {  443.                      try {  444.                          // 字符类型 String  445.                          if (pramets.get(i).getClass() == Class  446.                                  .forName("java.lang.String")) {  447.                              p_stmt.setString(i, pramets.get(i).toString());  448.                          }  449.                          // 日期类型 Date  450.                          if (pramets.get(i).getClass() == Class  451.                                  .forName("java.sql.Date")) {  452.                              p_stmt.setDate(i, java.sql.Date.valueOf(pramets  453.                                      .get(i).toString()));  454.                          }  455.                          // 布尔类型 Boolean  456.                          if (pramets.get(i).getClass() == Class  457.                                  .forName("java.lang.Boolean")) {  458.                              p_stmt.setBoolean(i, (Boolean) (pramets.get(i)));  459.                          }  460.                          // 整型 int  461.                          if (pramets.get(i).getClass() == Class  462.                                  .forName("java.lang.Integer")) {  463.                              p_stmt.setInt(i, (Integer) pramets.get(i));  464.                          }  465.                          // 浮点 float  466.                          if (pramets.get(i).getClass() == Class  467.                                  .forName("java.lang.Float")) {  468.                              p_stmt.setFloat(i, (Float) pramets.get(i));  469.                          }  470.                          // 双精度型 double  471.                          if (pramets.get(i).getClass() == Class  472.                                  .forName("java.lang.Double")) {  473.                              p_stmt.setDouble(i, (Double) pramets.get(i));  474.                          }  475.    476.                      } catch (ClassNotFoundException ex) {  477.                          throw ex;  478.                      } catch (SQLException ex) {  479.                          throw ex;  480.                      }  481.                  }  482.              }  483.          }  484.          return p_stmt;  485.      }  486.    487.      /** 488.       * 转换记录集对象为数组列表对象 489.       *  490.       * @param rs 491.       *            纪录集合对象 492.       * @return 数组列表对象 493.       * @throws Exception 494.       */  495.      private ArrayList<HashMap<Object, Object>> convertResultSetToArrayList(  496.              ResultSet rs) throws Exception {  497.          logger.info("###############::转换记录集对象为数组列表对象");  498.          // 获取rs 集合信息对象  499.          ResultSetMetaData rsmd = rs.getMetaData();  500.          // 创建数组列表集合对象  501.          ArrayList<HashMap<Object, Object>> tempList = new ArrayList<HashMap<Object, Object>>();  502.          HashMap<Object, Object> tempHash = null;  503.          // 填充数组列表集合  504.          while (rs.next()) {  505.              // 创建键值对集合对象  506.              tempHash = new HashMap<Object, Object>();  507.              for (int i = 0; i < rsmd.getColumnCount(); i++) {  508.                  // 遍历每列数据,以键值形式存在对象tempHash中  509.                  tempHash.put(rsmd.getColumnName(i + 1).toUpperCase(), rs  510.                          .getString(rsmd.getColumnName(i + 1)));  511.              }  512.              // 第一个键值对,存储在tempList列表集合对象中  513.              tempList.add(tempHash);  514.          }  515.          close_DB_Object();// 关闭相关链接  516.          return tempList;// 返回填充完毕的数组列表集合对象  517.      }  518.    519.      /** 520.       * 从数据库得到存储过程信息 521.       *  522.       * @param procName 523.       *            存储过程名称 524.       * @return 数组列表对象 525.       * @throws Exception 526.       */  527.      private ArrayList<HashMap<Object, Object>> getProcedureInfo(String procName)  528.              throws Exception {  529.          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='"  530.                  + procName + "' order by Syscolumns.isoutparam");  531.      }  532.    533.      /** 534.       * 从数据库得到存储过程参数个数 535.       *  536.       * @param procName 537.       *            存储过程名称 538.       * @return 数组列表对象 539.       * @throws Exception 540.       */  541.      @SuppressWarnings("unused")  542.      private int getParametersCount(String procName) throws Exception {  543.          int returnVal = 0;  544.          for (HashMap<Object, Object> tempHas : this  545.                  .executeSql("select count(*) as RowsCount from sysobjects,syscolumns,systypes where systypes.xtype=syscolumns.xtype and syscolumns.id=sysobjects.id and sysobjects.name='"  546.                          + procName + "'")) {  547.              returnVal = Integer.parseInt(tempHas.get("ROWSCOUNT").toString());  548.          }  549.          return returnVal;  550.      }  551.    552.      /** 553.       * 得到调用存储过程的全名 554.       *  555.       * @param procName 556.       *            存储过程名称 557.       * @return 调用存储过程的全名 558.       * @throws Exception 559.       */  560.      private String getProcedureCallName(String procName, int prametCount)  561.              throws Exception {  562.          String procedureCallName = "{call " + procName;  563.          for (int i = 0; i < prametCount; i++) {  564.              if (0 == i) {  565.                  procedureCallName = procedureCallName + "(?";  566.              }  567.              if (0 != i) {  568.                  procedureCallName = procedureCallName + ",?";  569.              }  570.          }  571.          procedureCallName = procedureCallName + ")}";  572.          return procedureCallName;  573.      }  574.    575.      /** 576.       * 得到数据类型的整型值 577.       *  578.       * @param typeName 579.       *            类型名称 580.       * @return 数据类型的整型值 581.       */  582.      private int getDataType(String typeName) {  583.          if (typeName.equals("varchar"))  584.              return Types.VARCHAR;  585.          if (typeName.equals("int"))  586.              return Types.INTEGER;  587.          if (typeName.equals("bit"))  588.              return Types.BIT;  589.          if (typeName.equals("float"))  590.              return Types.FLOAT;  591.          return 0;  592.      }  593.    594.      // 设置驱动路径  595.      @SuppressWarnings("static-access")  596.      public void set_DRIVER(String _DRIVER) {  597.          this._DRIVER = _DRIVER;  598.      }  599.    600.      // 设置数据库密码       @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;       }       }  


 

原创粉丝点击