日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java基础(三十二)JDBC(2)连接数据库

發布時間:2023/12/18 java 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java基础(三十二)JDBC(2)连接数据库 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  一、連接數據庫的過程

  連接數據庫的過程:加載數據庫驅動程序,不過只需在第一次訪問數據庫時加載一次,然后在每次訪問數據庫時創建一個Connection實例,然后執行操作數據庫的SQL語句,并返回執行結果,最后在完成此次操作時銷毀前面創建的Connection實例,釋放與數據庫的連接。

  1.加載JDBC驅動程序

// 加載數據庫驅動類,加載失敗拋出ClassNotFoundException異常Class.forName(Driver);

  2.創建數據庫連接

// 創建一個數據庫連接對象,創建失敗會拋出SQLException異常Connection conn = DriverManager.getConnection(Url, User, Password);

  3.創建一個Statement對象

// 通過Connection示例創建Statement實例Statement statement = conn.createStatement();

  4.執行SQL語句并獲得查詢結果

// 通過Statement實例執行SQL語句并返回執行結果ResultSet rs = statement.executeQuery("select * from user");

  5.關閉連接釋放資源

  在每次訪問數據庫后,應該按照下面的順序,及時銷毀這些實例,釋放它們占用的所有資源。

rs.close();statement.close();conn.close();

?

  二、Statement實例的三種類型

  Statement接口中,執行executeQuery方法可以返回查詢結果到結果集中,執行executeUpdate方法可以插入、刪除或者修改數據庫記錄,并返回一個int型數值,表示影響數據庫記錄的條數。

  Statement實例分為三種類型:Statement實例、(繼承自Statement)PreparedStatement實例和(繼承自PreparedStatement)CallableStatement實例。

  (1)Statement實例是最簡單的Statement實例,只能用來執行靜態的SQL語句

ResultSet rs_queue = statement.executeQuery("select * from user");while (rs_queue.next()) {System.out.println(rs_queue.getInt("id") + " " + rs_queue.getString("name") + " " + rs_queue.getString("sex") + " "+ rs_queue.getString("birthday"));}System.out.println(statement.executeUpdate("update user set sex='女' where id=1")); // 打印:1
       rs_queue.close();
?? ??? ??? ?statement.close()

  (2)PreparedStatement實例增加了執行動態SQL語句的功能

String sql = "update user set name = ?, sex = ?, birthday = ?where id =?";PreparedStatement predStatement = conn.prepareStatement(sql);predStatement.setString(1, "loser");predStatement.setString(2, "女");predStatement.setDate(3, new Date(System.currentTimeMillis()));predStatement.setInt(4, 1);System.out.println(predStatement.executeUpdate()); // 打印:1predStatement.close();

  (3)CallableStatement實例增加了執行數據庫存儲過程的功能

  首先在MySQL中創建一個存儲過程并測試:

mysql> select * from user // +----+-------+------+------------+ | id | name | sex | birthday | +----+-------+------+------------+ | 1 | loser || 2018-08-06 | | 2 | lsl || 2017-12-12 | | 3 | zgs || 2016-06-01 | +----+-------+------+------------+ 3 rows in set (0.00 sec)mysql> create procedure proc_count_select_by_sex(IN girl_or_boy VARCHAR(255))-> READS SQL DATA-> BEGIN-> select count(*) from user where sex=girl_or_boy;-> END-> // Query OK, 0 rows affected (0.00 sec)mysql> call proc_count_select_by_sex('') // +----------+ | count(*) | +----------+ | 2 | +----------+ 1 row in set (0.00 sec)Query OK, 0 rows affected (0.00 sec)

  然后使用CallableStatement對象調用存儲過程:

String sql = "{call proc_count_select_by_sex(?)}";CallableStatement cablStat = conn.prepareCall(sql);cablStat.setString(1, "女");ResultSet rs = cablStat.executeQuery();while (rs.next()) {System.out.println(rs.getInt(1)); // 打印:2}
rs.close();cablStat.
close();

?

  三、標準JDBC程序設計

package jdbc.jun.iplab;import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;public class JDBC {private static final String Driver = "com.mysql.jdbc.Driver";private static final String Url = "jdbc:mysql://localhost:3306/mysqldb?useSSL=false";private static final String User = "root";private static final String Password = "bjtungirc";static {try {Class.forName(Driver); } catch (ClassNotFoundException e) {e.printStackTrace();}}public static void main(String[] args) {try { // 創建一個數據庫連接對象,創建失敗會拋出SQLException異常Connection conn = DriverManager.getConnection(Url, User, Password);// 通過Connection示例創建Statement實例Statement statement = conn.createStatement();// 通過Statement實例執行SQL語句并返回執行結果ResultSet rs_queue = statement.executeQuery("select * from user");while (rs_queue.next()) {System.out.println(rs_queue.getInt("id") + " " + rs_queue.getString("name") + " " + rs_queue.getString("sex") + " "+ rs_queue.getString("birthday"));}System.out.println(statement.executeUpdate("update user set sex='女' where id=1"));rs_queue.close();statement.close();conn.close();} catch (SQLException e) {e.printStackTrace();} } } JDBC標準代碼設計

?  實際工程中使用JDBC的標準寫法

package fileTransfer;import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ResourceBundle;public class DBUtils {private static String driverClass;private static String url ;private static String userName;private static String password;private static Connection connection = null;static{//讀取配置文件,加載數據庫相關信息ResourceBundle resourceBundle = ResourceBundle.getBundle("info");driverClass = resourceBundle.getString("driverClass");url = resourceBundle.getString("url");userName = resourceBundle.getString("userName");password = resourceBundle.getString("password");try {Class.forName(driverClass);} catch (Exception e) {System.out.println(e.toString()+"加載驅動失敗!");}}public static Connection getConnection(){try {connection = DriverManager.getConnection(url, userName, password);} catch (SQLException e) {// TODO Auto-generated catch blockSystem.out.println(e.toString()+"數據庫連接失敗!");}return connection;}public static void CloseAll(ResultSet resultSet, PreparedStatement pStatement, Connection connection){if (resultSet!=null) {try {resultSet.close();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();}}if (pStatement != null) {try {pStatement.close();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();}}if(connection != null){try {connection.close();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();}}} } JDBC標準工程寫法

?

  四、JDBC連接池

?  實際工程中應該考慮下面的問題:建立數據庫連接需要開銷,因為數據庫連接是有限的資源,如果用戶要離開應用一段時間,那么他占用的連接就不應該保持打開狀態;另一方面,每次查詢都獲取連接并在隨后關閉它的代價也是相當高的。

  解決上述問題的方法時建立數據庫連接池(pool),這意味著數據庫連接在物理上并為關閉,而是保留在一個隊列中并被反復重用。

  連接池的使用對程序員來說是完全透明的,可以通過獲取數據源并調用getConnection方法來得到連接池中的連接。使用完連接后,需要調用close()方法,該方法不再物理上關閉連接,而是只告訴連接池已經使用完該連接,將Connection對象返回到LinkedList對象中。

  1.編寫連接池需要實現java.sql.DataSource接口

  2.創建LinkedList對象,并創建“最小連接數”個Connection對象并將這些對象添加到LinkedList對象中

  3.重寫getConnection方法,使用動態代理技術管理連接池中的Connection對象

  4.封裝getConnection()方法和release()方法

  示例代碼

  • 配置文件jdbc.properties
driver = com.mysql.jdbc.Driver url = jdbc:mysql://localhost:3306/mysqldb?useSSL=false userName = root password = bjtungircConnectionPoolInitSize = 10 jdbc.properties
  • 連接池類ConnectionPool
  • 初始化:通過ResourceBundle.getBundle("jdbc")讀取jdbc.properties里面的配置內容,然后初始化新建立默認的最小數據庫連接對象10個Connection對象,并將這些對象加入到由LinkedList類實現的鏈表中。 public class ConnectionPool implements DataSource {private static String driver;private static String url ;private static String userName;private static String password;private static int ConnectionPoolInitSize;private static LinkedList<Connection> conn_list = new LinkedList<>();static {try {ResourceBundle resourceBundle = ResourceBundle.getBundle("jdbc");driver = resourceBundle.getString("driver");url = resourceBundle.getString("url");userName = resourceBundle.getString("userName");password = resourceBundle.getString("password");ConnectionPoolInitSize = Integer.parseInt(resourceBundle.getString("ConnectionPoolInitSize"));Class.forName(driver);for (int i = 0; i < ConnectionPoolInitSize; i++) {Connection conn = DriverManager.getConnection(url, userName, password);conn_list.add(conn);}} catch (SQLException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}} @Overridepublic Connection getConnection() throws SQLException {...
    }
    }
  • getConnection()方法的重寫:執行該方法會從LinkedList鏈表中拿出一個Connection對象conn并返回,然后通過動態代理實現:如果拿出來的這個conn對象執行了close方法,就將這個conn對象重新放回到LinkedList鏈表中。 @Overridepublic Connection getConnection() throws SQLException {if (conn_list.size()>0) {final Connection conn = conn_list.removeFirst();System.out.println(1);return (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (!method.getName().equalsIgnoreCase("close")) {return method.invoke(conn, args);} else {conn_list.add(conn);return null;}}});} else {System.out.println("數據庫連接失敗");}return null;}
    • 封裝的JDBC連接類DBUtils類(包括了getConnection方法和closeAll方法) package connPool.jun.iplab;import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;public class Get_jdbc_conn_from_cPool {private static ConnectionPool cPool = new ConnectionPool();public static Connection getConnection() throws SQLException{return cPool.getConnection();}public static void CloseAll(ResultSet resultSet, PreparedStatement pStatement, Connection connection){if (resultSet!=null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (pStatement != null) {try {pStatement.close();} catch (SQLException e) {e.printStackTrace();}}if(connection != null){try {connection.close();} catch (SQLException e) {e.printStackTrace();}}} }
    • 測試類 package connPool.jun.iplab;import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;public class CPoolTest {public static void main(String[] args) throws SQLException {// 得到數據庫連接對象Connection conn = DBUtils.getConnection();// 數據庫操作Statement statement = conn.createStatement();ResultSet rs = statement.executeQuery("select * from user where sex='男'");while (rs.next()) {System.out.println(rs.getInt("id") + " " + rs.getString("name") + " " + rs.getString("sex") + " "+ rs.getString("birthday"));}// 執行這條語句時,conn對象執行了close()方法,因此會將conn對象重新添加到LinkedList集合中 DBUtils.CloseAll(rs, statement, conn);} }
    • 輸出 2 lsl 男 2017-12-12 4 winner 男 2018-08-07 9 nine 男 2018-08-07 ResultSet對象已關閉 Statement對象已關閉 Connection對象已關閉

      ?

    ?

    轉載于:https://www.cnblogs.com/BigJunOba/p/9431241.html

    總結

    以上是生活随笔為你收集整理的Java基础(三十二)JDBC(2)连接数据库的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。