【Java学习笔记】 MYSQL03 学习使用JDBC访问数据 以及 JDBC的优化和封装
通過JDBC 訪問數據
學習時間 7月11日
一、使用Java訪問數據庫
JAVA 主動 提出接口 ,各種數據庫適應 這些接口
- 接口就是 JDBC Java Database Connector
- 各種數據庫都會提供一套對應的驅動程序(JAR文件
- 即不同的數據庫都有自己對應的JAR文件
1、導入mysql對應的JAR包
2、訪問數據庫的步驟
加載驅動:涉及到反射
- Class.forName 需要捕獲異常
- 快速添加異常的快捷鍵Alt + 回車,選第二個
連接數據庫:查找db文件
-
配置url :jdbc:mysql://127.0.0.1:3306/zy_sys?useUnicode=true&characterEncoding=UTF-8&useSSL=false
ip地址,數據庫名字,編碼unicode,不使用加密
- zy_sys對應的是數據庫名稱
-
創建連接 :Connection connection = DriverManager.getConnection(url , user , password);
- 也需要異常捕獲
寫SQL語句
- 創建一個字符串存儲 SQL語句
- 建議先在DBMS中測試一次
預編譯SQL語句(判斷語法錯誤,獲取執行的對象)
- 固定語法:PreparedStatement preparedStatement = connection.prepareStatement(sql);
執行操作
獲取執行結果
-
增刪改調用方法executeUpdate():
- 返回類型int 表示受影響的條數
- 獲取執行結果只需要輸出這個返回值即可
-
查找調用方法executeQuery():
-
返回值類型是ResultSet(結果集:類似對象列表)
-
用 while 循環 遍歷結果集.
用到ResultSet.next()方法——向下移動一行,返回布爾值。默認是在空行,next一行才是第一行。舉個例子如下:
while (resultSet.next()){// 使用對應的方法獲得相應的數據類型String sno = resultSet.getString("sno");String sname = resultSet.getString("sname");int sage = resultSet.getInt("sage");// 按順序輸出結果即可System.out.println(sno + "\t" + sname + " \t" + sage);}
-
關閉操作(關閉連接,關閉接口,關閉對象) 釋放資源
- 關閉順序有大小之分,小的先關,大的后關
3、舉個例子(增刪改
package com.cykj.demo;import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException;public class Test {public static void main(String[] args) {try {// 1、加載驅動 ——涉及到反射知識點Class.forName("com.mysql.jdbc.Driver"); // Driver類 驅動String url = "jdbc:mysql://127.0.0.1:3306/zy_sys?useUnicode=true&characterEncoding=UTF-8&useSSL=false";// 2、連接數據庫String user = "root"; // 賬號String password = "root"; // 密碼Connection connection = DriverManager.getConnection(url , user , password); // 創建連接System.out.println("連接成功!");// 3、寫SQL語句String sql = "INSERT INTO zy_student(sno,sname,ssex) VALUES ('jx220501','老王',1)";// 4、預編譯PreparedStatement preparedStatement = connection.prepareStatement(sql);// 5、執行操作int re = preparedStatement.executeUpdate();// sql的增刪改都用executeUpdate() 返回類型int 表示受影響的條數// 6、獲取執行結果System.out.println(re);// 7、關閉preparedStatement.close(); // 關閉編譯connection.close(); // 關閉連接// 關閉順序有大小之分,小的先關,大的后關} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}} }4、 查找例子
package com.cykj.demo;import java.sql.*;public class Test2 {public static void main(String[] args) {try {// 1、加載驅動 ——涉及到反射知識點Class.forName("com.mysql.jdbc.Driver"); // Driver類 驅動// 2、連接數據庫String url = "jdbc:mysql://127.0.0.1:3306/zy_sys?useUnicode=true&characterEncoding=UTF-8&useSSL=false";String user = "root"; // 賬號String password = "root"; // 密碼Connection connection = DriverManager.getConnection(url , user , password); // 創建連接System.out.println("連接成功!");// 3、寫SQL語句String sql = "SELECT sno,sname,sage FROM zy_student WHERE sno LIKE 'AF%';";// 4、預編譯PreparedStatement preparedStatement = connection.prepareStatement(sql);// 5、執行操作ResultSet resultSet = preparedStatement.executeQuery(); // 查找數據庫用的是executeQuery()// 6、獲取執行結果while (resultSet.next()){// 使用對應的方法獲得相應的數據類型String sno = resultSet.getString("sno"); String sname = resultSet.getString("sname");int sage = resultSet.getInt("sage");// 按順序輸出結果即可System.out.println(sno + "\t" + sname + " \t" + sage);}// 7、關閉resultSet.close();preparedStatement.close(); // 關閉編譯connection.close(); // 關閉連接// 關閉順序有大小之分,小的先關,大的后關} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}} }===輸出結果=== AF121101 小王 22 AF121102 小紅 22 AF121103 王思思 23 AF121104 小灰 30 AF121105 小林 27 AF121106 小張 26 AF121107 小麗 32 AF121108 小花 29 AF121109 小馬 26JDBC優化
一、在預編譯時拼接字符串
-
SQL語句的拼接,有什么缺點?
- 寫法麻煩
- 不安全,留有SQL注入的風險
-
如何解決呢?
用問號?替代字符串中需要拼接的位置
- 在預編譯時加入字符串,舉個例子
- 修改后
- 簡單理解:這種方法類似挖坑和填坑
- 先挖坑:用問號?替代也要拼接的字符串
- 再填坑,利用setString()方法 插入字符串,計數從1開始
- 注意:setString會自動給這個字符串加入單引號,無需再添加
二、優化關閉操作
-
在JDBC操作中,如果編譯出現報錯,后續的關閉操作就不再執行了。這樣會導致數據庫負擔較大
- 要如何解決該問題呢?
- 利用異常關鍵字finally的特點:異常處理中finally是最后必須執行一次的,可以把關閉操作寫在這里!
- 要如何解決該問題呢?
-
具體操作如下
-
將需要關閉的對象,設置為全局變量
-
目標**:在finally語句塊里關閉對象**
-
關閉時也要加入異常捕獲,注意:每次關閉都要分別捕獲異常
-
在關閉前,也要加入一個if判斷,判斷對象不等于null,才進行關閉操作。舉個例子
try{。。。 } catch{。。。 } finally {try {if (connection != null){ // 判斷連接是否為空connection.close(); // 關閉連接}} catch (SQLException e) { // 加入關閉操作的異常捕獲e.printStackTrace();}try {if (ps != null) {ps.close();}} catch (SQLException e) {e.printStackTrace();} }
三、封裝
經過觀察發現,1、2、7三步的基本類似,可以偷懶共同的方法,可以封裝起來,甚至寫成一個類,即:
共同的代碼———> 方法 ———> 類
1、2、7三步的代碼 ———> 分別封裝成方法 ———> 放在同一個類中(工具層)
- 這種類存放在工具層,這個類就成為"工具包"
1、 工具類 Utils
- 用于存放各種封裝起來的方法,提供給其他模塊調用
2、封裝第一步和第二步 加載驅動建立連接
-
封裝1+2步
public Connection getConnection (){try {// 1、加載驅動Class.forName("com.mysql.jdbc.Driver");String url = "jdbc:mysql://127.0.0.1:3306/goods_db?" +"useUnicode=true&" +"characterEncoding=UTF-8&useSSL=false";String user = "root";String password = "root";// 2、建立連接Connection connection = DriverManager.getConnection(url,user,password);return connection; // 連接成功則返回連接} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}return null; // 連接失敗則返回空 } -
但是存在一個問題,URL,用戶名,密碼都是不固定的,這時候就需要用到配置文件*.properties” 、 xml 或 yml
- 如何使用配置文件?
3、properties配置文件的使用
-
鍵值對格式 : key=value
- 注意:等號的兩邊都不能有空格
-
具體使用步驟
-
將配置文件 拷貝到 項目工程目錄 下
-
讀取配置文件的值
-
要有對應的庫 ——> 找到對應的或對象 ——> 方法
-
Java有對應的類 Properties,實現的思路如下:
- 讀取文件 調用InputStream類 (IO流的內容 后續會接觸到
- 實例化屬性類 Properties
- 調用load(文件名)加載文件
- 取值 用getProperty(鍵名)來搜索對應的數據,返回值類型為String
-
-
舉個例子
public static void main(String[] args) {try {// 用IO讀取文件InputStream inputStream = new FileInputStream("db.properties");// 加載Properties pps = new Properties();pps.load(inputStream);// 獲取字符串String driver = pps.getProperty("driver");System.out.println(driver);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} }
在工具類中,獲取對應的驅動,url,用戶名,密碼存放在String
在執行連接數據庫時,直接調用這些字符串進行登陸即可
- 在實際應用場景中,只需要讀取一次配置文件。那么,如何只讀取一次配置文件?
- 構造函數?實例化的時候只運行一次,但是多次實例化還會再次執行
- 這里就需要用到靜態代碼塊——
- 語法:static {代碼塊}
- 在類里的靜態代碼塊,只會執行一次
- 執行的時間是在構造函數之前,且需要實例化的時候才會運行
4、封裝第七步:關閉操作
-
舉個例子
public void closeJdbc(Connection con , PreparedStatement ps , ResultSet rs){try {if (rs != null){rs.close();}} catch (SQLException e) {e.printStackTrace();}try {if (con != null){ // 判斷連接是否為空con.close(); // 關閉連接}} catch (SQLException e) { // 加入關閉操作的異常捕獲e.printStackTrace();}try {if (ps != null) {ps.close();}} catch (SQLException e) {e.printStackTrace();} }
5、調用思路
-
思路如下:
- 先將工具類實例化為全局變量 (所有需要關閉的對象也要聲明為全局變量)
- 調用工具類的方法 getConnection () 獲取 連接 Connection
- 對應的完成了第一步和第二步
- 繼續完成 寫SQL語句 預編譯 執行和獲取結果的步驟
- 在最后的finally的語句塊中調用關閉的方法closeJdbc(),關閉掉對應的對象。
- 由于關閉方法有多個對象,當不存在某個對象時,可以傳入null
6、工具類的具體案例
-
舉個例子
Connection connection = null; PreparedStatement ps = null; ResultSet resultSet = null; JdbcUtils jdbcUtils = new JdbcUtils(); connection = jdbcUtils.getConnection(); // 調用方法獲得連接 try {String sql = "SELECT * FROM tb_user WHERE userid = ? OR username = ?"; // 預編譯ps = connection.prepareStatement(sql);ps.setString(1, useridText);ps.setString(2, usernameText);resultSet = ps.executeQuery();if (resultSet.next()) {JOptionPane.showMessageDialog(null, "賬號已重復!","注意", JOptionPane.WARNING_MESSAGE);return;} else {// 賬號沒有重復 可以繼續執行操作 。。。} } catch (SQLException e) {e.printStackTrace(); } finally {jdbcUtils.closeJdbc(connection, ps, resultSet);// 如果沒有resultset,就傳入null即可 }
總結
以上是生活随笔為你收集整理的【Java学习笔记】 MYSQL03 学习使用JDBC访问数据 以及 JDBC的优化和封装的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php 获取首字母,PHP_php 获得
- 下一篇: 大量json数据解析OOM 存储数据库