天天看點

分享 Java 資料庫 Connect 連接配接器 封裝 JDBC 的 Query Excute 等

自制的 Java 連接配接器,該連接配接器将建立連接配接和删除連接配接進行了封裝,減少了J2EE開發關于 Database 操作的代碼,用于在編寫Java環境下無論是J2EE還是控制台、或者jUnit下,友善的連接配接資料庫。

/*
 * 資料庫連接配接類
 * 每一個連接配接實體用一個 Connect,循環體務必注意
 * 修改日志:<br>
 * 2016/7/1 增加關閉自動送出和送出函數
 * 2017/2/27 修正一些規範性設定,穩定性提高
 * 2017/4/10 Connect 構造函數機上異常狀态觸發
 * 
 */
package data;

/*
 * 資料庫連接配接類
 */

import java.sql.*;
import javax.sql.*;
import javax.naming.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import cn.sharcom.config.Constant;

public class Connect
{
  private static final Logger logger = LogManager.getLogger(Connect.class);

  private Connection conn = null;
  private Statement stmt = null;
  private CallableStatement cstmt = null;
  private PreparedStatement pstmt = null;
  private ResultSet rs = null;

  private boolean connected = false;

  /**
   * 連接配接模式:J2EE 環境下,連接配接池方式
   */
  public static int JNDI_MODE = 100;
  /**
   * 控制台環境下,URL 連接配接方式(用于jUnit測試)
   */
  public static int URL_MODE = 200;

  /**
   * 初始化連接配接
   * 
   * @param mode
   *          連接配接模式:JNDI 和 URL
   */
  public Connect(final int mode) throws SQLException
  {
    // J2EE 環境下連接配接池
    if (mode == JNDI_MODE)
    {
      logger.debug("JNDI_MODE begin ...");

      // 連接配接資料庫
      try
      {
        Context context = new InitialContext();
        logger.debug("InitialContext success");

        DataSource dataSource = (DataSource) context.lookup(Constant.JNDI_NAME);
        logger.debug(String.format("DataSource lookup \"%s\" %s", Constant.JNDI_NAME, "success"));

        conn = dataSource.getConnection();
        logger.debug(String.format("Connection dataSource %s", "success"));

        stmt = conn.createStatement();
        logger.debug(String.format("CreateStatement %s", "success"));

        // 修改連接狀態
        connected = true;
      }
      catch (NamingException e)
      {
        e.printStackTrace();
        logger.error(e.getMessage());
        Close();
        throw new SQLException("Connect fail by JNDI");
      }
      catch (SQLException e)
      {
        e.printStackTrace();
        logger.error(e.getMessage());
        Close();
        throw new SQLException("Connect fail by JNDI");
      }
      catch (Exception e)
      {
        e.printStackTrace();
        logger.error(e.getMessage());
        Close();
        throw new SQLException("Connect fail by JNDI");
      }
      finally
      {
      }
    }
    // 主要是用于 jUnit 測試時沒有連接配接池的情況
    else if (mode == URL_MODE)
    {
      logger.debug("URL_MODE begin...");
      try
      {
        //
        Class.forName("com.mysql.jdbc.Driver");
        // 建立連接配接 URL
        final String url = String.format("jdbc:mysql://127.0.0.1:3306/editor?user=%s&password=%s&useSSL=false", "root", "123456");
        // 連接配接 …… 并得到 connection
        conn = DriverManager.getConnection(url);
        // Statement
        stmt = conn.createStatement();
        // 修改連接狀態
        connected = true;
      }
      catch (ClassNotFoundException e)
      {
        e.printStackTrace();
        logger.error(e.getMessage());
        Close();
        throw new SQLException("Connect fail by URL");
      }
      catch (SQLException e)
      {
        e.printStackTrace();
        logger.error(e.getMessage());
        Close();
        throw new SQLException("Connect fail by URL");
      }
      catch (Exception e)
      {
        e.printStackTrace();
        logger.error(e.getMessage());
        Close();
        throw new SQLException("Connect fail by URL");
      }
      finally
      {
      }
    }
  }

  /**
   * 傳回連接配接狀态
   * 
   * @return
   */
  public boolean isConnected()
  {
    return connected;
  }

  /**
   * 檢查資料庫連接是否有效
   * 
   * @return
   */
  public boolean Test()
  {
    // 傳回值
    boolean result = false;
    ResultSet resultSet = null;
    // 檢查
    try
    {
      resultSet = conn.createStatement().executeQuery("select 1");

      if (resultSet.first() == true)
      {
        result = true;
        logger.debug("Test connect success");
      }

      if (resultSet != null)
      {
        try
        {
          resultSet.close();
        }
        catch (SQLException e)
        {
          e.printStackTrace();
        }
      }
    }
    catch (SQLException e)
    {
      e.printStackTrace();
      result = false;
      logger.debug("Test connect fail");
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    finally
    {

    }

    // 傳回
    return result;
  }

  /**
   * 傳入一個預備格式化的 SQL<br>
   * insert into table (`field1`, `field2`) values (?, ?);
   * 
   * @param sql
   * @throws SQLException
   */
  public void setPreparedStatementSQL(final String sql) throws SQLException
  {
    pstmt = conn.prepareStatement(sql);
  }

  /**
   * 傳入格式化的<br>
   * SQL connect.setPreparedStatementSQL(sql);<br>
   * 
   * 設置各個參數的類型和值<br>
   * connect.getPreparedStatement().setLong(1, 1);<br>
   * connect.getPreparedStatement().setString(2, "name");<br>
   * connect.getPreparedStatement().setString(3, null);<br>
   * 
   * 執行<br>
   * connect.executeUpdate(null);<br>
   * 
   * @return
   */
  public PreparedStatement getPreparedStatement()
  {
    return pstmt;
  }

  /**
   * 傳回 Connection
   * 
   * @return
   */
  public Connection getConnection()
  {
    return conn;
  }

  /**
   * 傳回 ResultSet
   * 
   * @return
   */
  public ResultSet getResultSet()
  {
    return rs;
  }

  /**
   * 獲得 Statement 執行 SQL 指令
   * 
   * @return Statement
   * @throws SQLException
   */
  public Statement getStatement() throws SQLException
  {
    // 建立 statement

    // mysql use
    stmt = conn.createStatement();
    // mssql use
    // stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

    return stmt;
  }

  /**
   * 擷取 CallableStatement 并建立存儲過程
   * 
   * @param strCallableStatement
   * @return CallableStatement
   * @throws SQLException
   */
  public CallableStatement getCallableStatement(String sql) throws SQLException
  {
    // storedProc
    cstmt = conn.prepareCall(sql);
    return cstmt;
  }

  public ResultSet executeQuery() throws SQLException
  {
    return executeQuery(null);
  }

  /**
   * 查詢 sql
   * 
   * @param sql
   * @return
   * @throws SQLException
   */
  public ResultSet executeQuery(final String sql) throws SQLException
  {
    // init ResultSet
    if (rs != null)
    {
      rs.close();
      rs = null;
    }

    // 正常的 SQL 傳入調用
    if (sql != null)
    {
      logger.debug("connect: stmt.executeQuery(sql)");
      if (stmt != null)
      {
        rs = stmt.executeQuery(sql);
      }
    }
    else
    {
      logger.debug("connect: pstmt.executeQuery()");
      if (pstmt != null)
      {
        rs = pstmt.executeQuery();
      }
    }

    return rs;
  }

  /**
   * 執行 sql
   * 
   * @param sql
   * @return
   * @throws SQLException
   */
  public int executeUpdate(final String sql) throws SQLException
  {
    int result = 0;

    if (sql == null && pstmt != null)
    {
      result = pstmt.executeUpdate();
    }
    else
    {
      result = stmt.executeUpdate(sql);
    }
    return result;
  }

  /**
   * pstmt 無參數時調用
   * 
   * @return
   * @throws SQLException
   */
  public int executeUpdate() throws SQLException
  {
    return executeUpdate(null);
  }

  /**
   * 取得最後編号
   * 
   * @return
   */
  public Long getLastInsertId()
  {
    Long result = null;
    ResultSet resultSet = null;

    try
    {
      // 查詢最後插入的記錄的編号
      String sql = "select last_insert_id() as `id`";
      // 調用查詢
      resultSet = stmt.executeQuery(sql);
      if (resultSet.first() == true)
      {
        result = resultSet.getLong("id");
        logger.debug("getLastInsertId is success");
      }
      else
      {
        logger.debug("getLastInsertId is null");
      }
    }
    catch (SQLException e)
    {
      e.printStackTrace();
      logger.error("getLastInsertId is fail");
    }
    finally
    {
      if (resultSet != null)
      {
        try
        {
          resultSet.close();
        }
        catch (SQLException e)
        {
          e.printStackTrace();
        }
      }
    }

    return result;
  }

  /**
   * 設定是否自動送出<br>
   * 默認爲 true,執行後即刻對數據庫改寫<br>
   * 當為 false 時,所有修改需調用 Commit() 方可實際完成。
   * 
   * @param model
   * @throws SQLException
   */
  public void setAutoCommit(boolean model) throws SQLException
  {
    logger.debug("setAutoCommit", model);
    conn.setAutoCommit(model);
  }

  /**
   * 若處于手動送出, 需要送出
   * 
   * @throws SQLException
   */
  public void Commit() throws SQLException
  {
    conn.commit();
  }

  /**
   * 事物回退
   * 
   * @throws SQLException
   */
  public void Rollback()
  {
    try
    {
      conn.rollback();
    }
    catch (SQLException e)
    {
      e.printStackTrace();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }

  /**
   * 關閉所有連接
   */
  public void Close()
  {
    logger.debug("Connect close all");
    connected = false;

    // Close ResultSet
    if (rs != null)
    {
      try
      {
        rs.close();
      }
      catch (Exception e)
      {
        e.printStackTrace();
      }
      rs = null;
    }

    // Close Statement
    if (stmt != null)
    {
      try
      {
        stmt.close();
      }
      catch (Exception e)
      {
        e.printStackTrace();
      }
      stmt = null;
    }

    // storedProc
    if (cstmt != null)
    {
      try
      {
        cstmt.close();
      }
      catch (Exception e)
      {
        e.printStackTrace();
      }
      cstmt = null;
    }

    if (conn != null)
    {
      try
      {
        conn.close();
      }
      catch (Exception e)
      {
        e.printStackTrace();
      }
      conn = null;
    }
  }

}
           

連接配接器的使用:執行方法

Connect connect = new Connect(Connect.URL_MODE);
if(connect.executeUpdate(sql) == 1)
{
  // 執行成功
}
connect.Close();
           

連接配接器的使用:查詢方法

Connect connect = new Connect(Connect.URL_MODE);
connect.executeQuery(sql);
while (connect.getResultSet().next() == true)
{
  String val = connect.getResultSet().getString("field1");
  System.out.println(val);
}
connect.Close();
           

執行個體:

Connect connect = null;
    try
    {
      connect = new Connect(Connect.JNDI_MODE);

      connect.executeQuery(sql);
      while (connect.getResultSet().next() == true)
      {
        String val = connect.getResultSet().getString("field");
      }
    }
    catch (SQLException e)
    {
      e.printStackTrace();
      result = Constant.DB_ERROR;
    }
    catch (Exception e)
    {
      e.printStackTrace();
      result = Constant.DB_ERROR;
    }
    finally
    {
      if (connect != null)
      {
        connect.Close();
      }
    }
           

需要注意的環節就是:當用完 Connect 後,一定要調用 Close() 以關閉連接配接,尤其是 J2EE 連接配接池環境,否則在連接配接逾時自動關閉前,連接配接會一直保持,這将會占用系統資源,而持續申請連接配接也會耗盡連接配接池,新的連接配接将無法申請。

本文連結 blog.csdn.net/joyous/article/details/51103046

Q群讨論:236201801

.