JDBC原生寫法+原生連線池
阿新 • • 發佈:2019-01-27
目錄
在網上找了許多文章,關於JDBC連線的雜七雜八,要麼寫的很複雜,所以自己總結了一下。
1.專案結構圖
2.新建一個properites檔案
用於jdbc載入資料庫資訊
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbctest
username=root
password=root
jdbcPoolInitSize=10
3.新建jdbc連線池工具類JdbcPool
package com.test.util; import java.io.InputStream; import java.io.PrintWriter; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.LinkedList; import java.util.Properties; import java.util.logging.Logger; import javax.sql.DataSource; /** * * 原生的jdbc連線池,載入jdbc.properties檔案 */ public class JdbcPool implements DataSource { /** * * @Field: listConnections 使用LinkedList集合來存放資料庫連結, * 由於要頻繁讀寫List集合,所以這裡使用LinkedList儲存資料庫連線比較合適 */ private static LinkedList<Connection> listConnections = new LinkedList<Connection>(); private static Connection conn; // 在靜態程式碼塊中載入src/jdbc.properties資料庫配置檔案 static { InputStream in = JdbcPool.class.getResourceAsStream("/jdbc.properties"); Properties prop = new Properties(); try { prop.load(in); String driver = prop.getProperty("driver"); String url = prop.getProperty("url"); String username = prop.getProperty("username"); String password = prop.getProperty("password"); // 資料庫連線池的初始化連線數大小 int jdbcPoolInitSize = Integer.parseInt(prop.getProperty("jdbcPoolInitSize")); // 載入資料庫驅動 Class.forName(driver); for (int i = 0; i < jdbcPoolInitSize; i++) { conn = DriverManager.getConnection(url, username, password); // System.out.println("獲取到了連線" + conn); // 將獲取到的資料庫連線加入到listConnections集合中,listConnections集合此時就是一個存放了資料庫連線的連線池 listConnections.add(conn); } } catch (Exception e) { throw new ExceptionInInitializerError(e); } } /* * * 獲取資料庫連線 */ @Override public Connection getConnection() throws SQLException { // 如果資料庫連線池中的連線物件的個數大於0 if (listConnections.size() > 0) { // 從listConnections集合中獲取一個數據庫連線 System.out.println("listConnections資料庫連線池大小是:" + listConnections.size()); // 返回Connection物件的代理物件 return (Connection) Proxy.newProxyInstance(JdbcPool.class.getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (!method.getName().equals("close")) { System.out.println("獲取到連線池連線物件......" + conn); return method.invoke(conn, args); } else { // 如果呼叫的是Connection物件的close方法,就把conn還給資料庫連線池 listConnections.add(conn); // System.out.println(conn+ ",還給資料庫連線池了"); // System.out.println("listConnections資料庫連線池大小為"+ listConnections.size()); return null; } } }); } else { throw new RuntimeException("對不起,資料庫忙"); } } //省略@Override方法 @Override public PrintWriter getLogWriter() throws SQLException { // TODO Auto-generated method stub return null; } @Override public void setLogWriter(PrintWriter out) throws SQLException { // TODO Auto-generated method stub } @Override public void setLoginTimeout(int seconds) throws SQLException { // TODO Auto-generated method stub } @Override public int getLoginTimeout() throws SQLException { // TODO Auto-generated method stub return 0; } @Override public Logger getParentLogger() throws SQLFeatureNotSupportedException { // TODO Auto-generated method stub return null; } @Override public <T> T unwrap(Class<T> iface) throws SQLException { // TODO Auto-generated method stub return null; } @Override public boolean isWrapperFor(Class<?> iface) throws SQLException { // TODO Auto-generated method stub return false; } @Override public Connection getConnection(String username, String password) throws SQLException { // TODO Auto-generated method stub return null; } }
4.新建JDBCUtil工具類
package com.test.util; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class JDBCUtil { private static JdbcPool pool = new JdbcPool(); /** * * 獲取資源 */ public static Connection getConnection() throws SQLException { return pool.getConnection(); } /** * * 關閉資源 * * @param resultSet 查詢返回的結果集,沒有為空 * * @param statement * * @param connection */ public static void close(ResultSet resultSet, Statement statement, Connection connection) { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { throw new RuntimeException(e); } resultSet = null; } if (statement != null) { try { statement.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } }
5.資料庫操作
package com.test.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.test.util.JDBCUtil; public class JDBCDao { /** * * 增加,刪除,修改 */ public static void insertOrDeleteOrUpdate(String sql) { try { Connection connection = JDBCUtil.getConnection(); PreparedStatement pst = connection.prepareStatement(sql); int execute = pst.executeUpdate(); System.out.println("執行語句:" + sql + "," + execute + "行資料受影響"); JDBCUtil.close(null, pst, connection); } catch (SQLException e) { System.out.println("異常提醒:" + e); } } /** * * 查詢,返回結果集 */ public static List<Map<String, Object>> select(String sql) { List<Map<String, Object>> returnResultToList = null; try { Connection connection = JDBCUtil.getConnection(); PreparedStatement pst = connection.prepareStatement(sql); ResultSet resultSet = pst.executeQuery(); // returnResultToList = returnResultToList(resultSet); JDBCUtil.close(resultSet, pst, connection); } catch (SQLException e) { System.out.println("異常提醒:" + e); } return returnResultToList; } /** * * 資料返回集合 * @param resultSet * @return * @throws SQLException */ public static List<Map<String, Object>> returnResultToList(ResultSet resultSet) { List<Map<String, Object>> values = null; try { // 鍵: 存放列的別名, 值: 存放列的值. values = new ArrayList<>(); // 存放欄位名 List<String> columnName = new ArrayList<>(); ResultSetMetaData rsmd = resultSet.getMetaData(); for (int i = 0; i < rsmd.getColumnCount(); i++) { // 欄位名 columnName.add(rsmd.getColumnLabel(i + 1)); } System.out.println("表字段為:"); System.out.println(columnName); System.out.println("表資料為:"); Map<String, Object> map = null; // 處理 ResultSet, 使用 while 迴圈 while (resultSet.next()) { map = new HashMap<>(); for (String column : columnName) { Object value = resultSet.getObject(column); map.put(column, value); System.out.print(value + "\t"); } // 把一條記錄的 Map 物件放入準備的 List 中 values.add(map); System.out.println(); } } catch (SQLException e) { System.out.println("異常提醒:" + e); } return values; } }