Java基础(三十二)JDBC(2)连接数据库
一、連接數(shù)據(jù)庫的過程
連接數(shù)據(jù)庫的過程:加載數(shù)據(jù)庫驅(qū)動程序,不過只需在第一次訪問數(shù)據(jù)庫時(shí)加載一次,然后在每次訪問數(shù)據(jù)庫時(shí)創(chuàng)建一個(gè)Connection實(shí)例,然后執(zhí)行操作數(shù)據(jù)庫的SQL語句,并返回執(zhí)行結(jié)果,最后在完成此次操作時(shí)銷毀前面創(chuàng)建的Connection實(shí)例,釋放與數(shù)據(jù)庫的連接。
1.加載JDBC驅(qū)動程序
// 加載數(shù)據(jù)庫驅(qū)動類,加載失敗拋出ClassNotFoundException異常Class.forName(Driver);2.創(chuàng)建數(shù)據(jù)庫連接
// 創(chuàng)建一個(gè)數(shù)據(jù)庫連接對象,創(chuàng)建失敗會拋出SQLException異常Connection conn = DriverManager.getConnection(Url, User, Password);3.創(chuàng)建一個(gè)Statement對象
// 通過Connection示例創(chuàng)建Statement實(shí)例Statement statement = conn.createStatement();4.執(zhí)行SQL語句并獲得查詢結(jié)果
// 通過Statement實(shí)例執(zhí)行SQL語句并返回執(zhí)行結(jié)果ResultSet rs = statement.executeQuery("select * from user");5.關(guān)閉連接釋放資源
在每次訪問數(shù)據(jù)庫后,應(yīng)該按照下面的順序,及時(shí)銷毀這些實(shí)例,釋放它們占用的所有資源。
rs.close();statement.close();conn.close();?
二、Statement實(shí)例的三種類型
Statement接口中,執(zhí)行executeQuery方法可以返回查詢結(jié)果到結(jié)果集中,執(zhí)行executeUpdate方法可以插入、刪除或者修改數(shù)據(jù)庫記錄,并返回一個(gè)int型數(shù)值,表示影響數(shù)據(jù)庫記錄的條數(shù)。
Statement實(shí)例分為三種類型:Statement實(shí)例、(繼承自Statement)PreparedStatement實(shí)例和(繼承自PreparedStatement)CallableStatement實(shí)例。
(1)Statement實(shí)例是最簡單的Statement實(shí)例,只能用來執(zhí)行靜態(tài)的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")); // 打印:1rs_queue.close();
?? ??? ??? ?statement.close()
(2)PreparedStatement實(shí)例增加了執(zhí)行動態(tài)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實(shí)例增加了執(zhí)行數(shù)據(jù)庫存儲過程的功能
首先在MySQL中創(chuàng)建一個(gè)存儲過程并測試:
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對象調(diào)用存儲過程:
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();
?
三、標(biāo)準(zhǔn)JDBC程序設(shè)計(jì)
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 { // 創(chuàng)建一個(gè)數(shù)據(jù)庫連接對象,創(chuàng)建失敗會拋出SQLException異常Connection conn = DriverManager.getConnection(Url, User, Password);// 通過Connection示例創(chuàng)建Statement實(shí)例Statement statement = conn.createStatement();// 通過Statement實(shí)例執(zhí)行SQL語句并返回執(zhí)行結(jié)果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標(biāo)準(zhǔn)代碼設(shè)計(jì)? 實(shí)際工程中使用JDBC的標(biāo)準(zhǔn)寫法
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{//讀取配置文件,加載數(shù)據(jù)庫相關(guān)信息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()+"加載驅(qū)動失敗!");}}public static Connection getConnection(){try {connection = DriverManager.getConnection(url, userName, password);} catch (SQLException e) {// TODO Auto-generated catch blockSystem.out.println(e.toString()+"數(shù)據(jù)庫連接失敗!");}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標(biāo)準(zhǔn)工程寫法?
四、JDBC連接池
? 實(shí)際工程中應(yīng)該考慮下面的問題:建立數(shù)據(jù)庫連接需要開銷,因?yàn)閿?shù)據(jù)庫連接是有限的資源,如果用戶要離開應(yīng)用一段時(shí)間,那么他占用的連接就不應(yīng)該保持打開狀態(tài);另一方面,每次查詢都獲取連接并在隨后關(guān)閉它的代價(jià)也是相當(dāng)高的。
解決上述問題的方法時(shí)建立數(shù)據(jù)庫連接池(pool),這意味著數(shù)據(jù)庫連接在物理上并為關(guān)閉,而是保留在一個(gè)隊(duì)列中并被反復(fù)重用。
連接池的使用對程序員來說是完全透明的,可以通過獲取數(shù)據(jù)源并調(diào)用getConnection方法來得到連接池中的連接。使用完連接后,需要調(diào)用close()方法,該方法不再物理上關(guān)閉連接,而是只告訴連接池已經(jīng)使用完該連接,將Connection對象返回到LinkedList對象中。
1.編寫連接池需要實(shí)現(xiàn)java.sql.DataSource接口
2.創(chuàng)建LinkedList對象,并創(chuàng)建“最小連接數(shù)”個(gè)Connection對象并將這些對象添加到LinkedList對象中
3.重寫getConnection方法,使用動態(tài)代理技術(shù)管理連接池中的Connection對象
4.封裝getConnection()方法和release()方法
示例代碼
- 配置文件jdbc.properties
- 連接池類ConnectionPool
} }
- 封裝的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 {// 得到數(shù)據(jù)庫連接對象Connection conn = DBUtils.getConnection();// 數(shù)據(jù)庫操作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"));}// 執(zhí)行這條語句時(shí),conn對象執(zhí)行了close()方法,因此會將conn對象重新添加到LinkedList集合中 DBUtils.CloseAll(rs, statement, conn);} }
- 輸出 2 lsl 男 2017-12-12
4 winner 男 2018-08-07
9 nine 男 2018-08-07
ResultSet對象已關(guān)閉
Statement對象已關(guān)閉
Connection對象已關(guān)閉
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/BigJunOba/p/9431241.html
總結(jié)
以上是生活随笔為你收集整理的Java基础(三十二)JDBC(2)连接数据库的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ACE(Adaptive Communi
- 下一篇: Java线程池理解及用法