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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JDBC使用详解

發布時間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JDBC使用详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引言

JDBC(Java DataBase Connectivity)是Java連接數據庫的的方法;其實本質就是SUN公司定制的一套接口,這樣就可以實現Java和各種不同數據庫間的連接,如下圖:

注:本文使用IDEA示范,數據庫使用的是MySQL數據庫

IDEA導入數據庫連接Jar包步驟

首先我們要先有對應的MySQL數據庫連接驅動jar包,沒有的可以評論區找我要
正常創建一個IDEA項目,如圖:

接下來就按圖操作導入jar包;

這樣我就創建了一個名為lib的文件夾,然后把 mysql-connector-java-8.0.16.jar 粘貼到lib目錄下;
如圖:

最后一步把jar包導入到項目中,即右鍵該jar包,再點擊Add as Library;


這樣就導入jar包了;
接下來就是JDBC的基本操作;

JDBC編程操作

JDBC在Java代碼中可以總結為五個操作步驟:

  • 注冊驅動(確定連接的數據庫)
  • 獲取連接(打開JVM進程和數據庫進程之間的通道)
  • 獲取數據庫操作對象(可以用來執行sql語句)
  • 執行SQL語句(如果是select查詢語句那么需要處理查詢結果)
  • 釋放資源(關閉第二步開啟的進程通道)
  • 我自己先創建了一個test02數據庫,其中一個表為t_user,如圖:

    下面就來展示一下使用JDBC實現連接數據庫的登錄操作(存在問題):

    package jdbctest01;import java.sql.*; import java.util.HashMap; import java.util.Map; import java.util.Scanner;/*模擬實現用戶登錄功能存在SQL注入問題,不安全; */ public class JdbcTest01 {public static void main(String[] args) {// 初始化界面Map<String, String> userLoginInfo = initUI();// 驗證用戶名和密碼boolean loginSuccess = login(userLoginInfo);System.out.println(loginSuccess ? "登錄成功" : "登錄失敗");}/*** 驗證用戶名和密碼* @param userLoginInfo 用戶登錄信息* @return false表示失敗, true表示成功*/private static boolean login(Map<String, String> userLoginInfo) {boolean loginSuccess = false; // 標記String loginName = userLoginInfo.get("loginName"); // 獲取用戶名String password = userLoginInfo.get("password"); // 獲取登錄密碼// JDBC代碼Connection connection = null;Statement statement = null;ResultSet resultSet = null;try {// 注冊驅動Class.forName("com.mysql.cj.jdbc.Driver");// 獲取連接connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test02?serverTimezone=UTC", "root", "020216");// 獲取數據庫操作對象statement = connection.createStatement();// 執行sql語句String sql = "select * from t_user where loginName = '"+ loginName +"' and loginPwd = '"+ password +"'";resultSet = statement.executeQuery(sql);// 處理結果集if (resultSet.next()) {loginSuccess = true;}} catch (ClassNotFoundException | SQLException e) {e.printStackTrace();} finally {// 釋放資源(按順序釋放)if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (statement != null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}return loginSuccess;}/*** 初始化用戶界面* @return 用戶輸入的用戶名和密碼等登錄信息*/private static Map<String, String> initUI() {Scanner scan = new Scanner(System.in);// 輸入用戶名;System.out.print("用戶名:");String userName = scan.nextLine();// 輸入密碼;System.out.print("密碼:");String password = scan.nextLine();// 放入mapMap<String, String> userLoginInfo = new HashMap<>();userLoginInfo.put("loginName", userName);userLoginInfo.put("password", password);return userLoginInfo;} }

    這樣就實現了一個登錄功能


    但是這樣存在SQL注入問題,SQL注入可以自己搜集資料了解一下,簡而言之就是不安全,我示范一下:

    可以看到,張三密碼是200002,但是我卻可以通過SQL注入語句1' or '1'='1登錄成功,這樣就存在著很大的問題;
    為了解決SQL注入問題,可以使用如下方法:
    代碼如下:

    package jdbctest01;import java.sql.*; import java.util.HashMap; import java.util.Map; import java.util.Scanner;/* 解決SQL注入問題*/ public class JdbcTest02 {public static void main(String[] args) {Map<String, String> userLoginInfo = initUI();boolean loginSuccess = login(userLoginInfo);System.out.println(loginSuccess ? "登錄成功" : "登錄失敗");}private static boolean login(Map<String, String> userLoginInfo) {boolean loginSuccess = false;String userName = userLoginInfo.get("userName");String password = userLoginInfo.get("password");Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;// JDBC代碼try {// 注冊驅動Class.forName("com.mysql.cj.jdbc.Driver");// 獲取鏈接connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test02?serverTimezone=UTC", "root", "020216");// 獲取數據操作對象(這里就不同了)?是占位符String sql = "select * from t_user where loginName = ? and loginPwd = ?";preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1, userName); // 設置第一個占位符?為usernamepreparedStatement.setString(2, password); // 設置第二個占位符?為password// 執行sql語句resultSet = preparedStatement.executeQuery();// 處理結果集if (resultSet.next()) {loginSuccess = true;}} catch (ClassNotFoundException | SQLException e) {e.printStackTrace();} finally {// 釋放資源if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (preparedStatement != null) {try {preparedStatement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}return loginSuccess;}private static Map<String, String> initUI() {Scanner scan = new Scanner(System.in);System.out.print("請輸入用戶名:");String userName = scan.nextLine();System.out.print("請輸入密碼:");String password = scan.nextLine();Map<String, String> userLoginInfo = new HashMap<>();userLoginInfo.put("userName" , userName);userLoginInfo.put("password", password);return userLoginInfo;} }

    SQL注入失敗:

    可以發現主要區別是獲取數據庫操作對象時不再使用Statement,而使用PreparedStatement,這樣就可以解決SQL注入問題;所以實際情況下,使用PreparedStatement會更多,還有占位符操作,也很簡單,代碼中有注釋,自己嘗試一下就明白了;代碼可以多看幾遍找找區別;

    這就是JDBC最基礎的操作,其實就是這幾個固定步驟,實在不理解先記住就行了,之后用多了就會明白了;

    接下來我們將JDBC的一些操作進行封裝;

    自定義JDBC工具類

    在這里我們將注冊、連接、關閉操作封裝起來,構成一個工具類;
    代碼有詳細注釋;

    package jdbctest01.mytest;import java.sql.*;/*JDBC工具類,簡化JDBC編程 */ public class DBUtil {/*** 工具類中的構造方法是私有的* 因為工具類中的方法都是靜態的,直接通過類名去調即可。*/private DBUtil(){}/*** 靜態代碼塊,類加載的時候執行* 把 注冊驅動 程序的代碼放在靜態代碼塊中,避免多次獲取連接對象時重復調用*/static {try {Class.forName("com.mysql.cj.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}}// 獲取連接public static Connection getConnection() throws SQLException {return DriverManager.getConnection("jdbc:mysql://localhost:3306/test02?serverTimezone=UTC", "root", "020216");}// 關閉方法public static void close(Connection connection, Statement statement, ResultSet resultSet) {if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (statement != null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}} }

    這個操作也可以自己實現一下,并不難;
    這里值得一提的就是注冊驅動放到了靜態代碼塊中,這樣就在保證調用的同時避免重復調用;

    CRUD操作

    對于數據庫的操作其實最常用的還是增刪改查,但是每次都重寫代碼實在是復雜,所以這里同樣可以自己封裝一個增刪改查操作;這里還是使用之前的test02數據庫,這里是對bank表進行的操作;bank表如圖:

    接下來是我自己封裝的一個增刪改查操作代碼(這里使用了DBUtil工具類):

    package jdbctest01.mytest;import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List;// 針對一個表嘗試封裝增刪改查操作 public class CRUD {/*** 實現給bank表增加數據的操作* @param num 主鍵值* @param user 用戶名* @param money 存款數目* @return 返回值為執行sql的數目* @throws SQLException DBUtil.getConnection()的異常處理*/public static int add(int num, String user, int money) throws SQLException {Connection connection = null;PreparedStatement preparedStatement = null;// 注冊驅動并獲取鏈接connection = DBUtil.getConnection();// 獲取數據操作對象String sql = "insert into bank(num, user, money)values(?, ?, ?)";preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1, num); // 第一個占位符?為numpreparedStatement.setString(2, user); // 第二個占位符?為userpreparedStatement.setInt(3, money); // 第三個占位符?為money// 執行sql語句int count = preparedStatement.executeUpdate(); // 執行insert語句// 釋放資源DBUtil.close(connection, preparedStatement, null);return count;}/*** 實現bank表的刪除操作* @param num 主鍵值* @return 返回執行sql的數目* @throws SQLException DBUtil.getConnection()的異常處理*/public static int delete(int num) throws SQLException {Connection connection = null;PreparedStatement preparedStatement = null;connection = DBUtil.getConnection();String sql = "delete from bank where num = ?";preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1, num);int count = preparedStatement.executeUpdate(); // 執行delete語句DBUtil.close(connection, preparedStatement, null);return count;}/*** 實現對bank指定數據的更新* @param num 主鍵值* @param user 用戶名* @param money 存款數目* @return 返回執行sql的數目* @throws SQLException DBUtil.getConnection()的異常處理*/public static int update(int num, String user, int money) throws SQLException {Connection connection = null;PreparedStatement preparedStatement = null;connection = DBUtil.getConnection();String sql = "update bank set user = ?, money = ? where num = ?";preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1, user);preparedStatement.setInt(2, money);preparedStatement.setInt(3, num);int count = preparedStatement.executeUpdate(); // 執行update語句DBUtil.close(connection, preparedStatement, null);return count;}/*** 實現對bank表中對應數據的查詢* @param num 主鍵值* @return 返回ResultSet值,對應的查詢結果* @throws SQLException DBUtil.getConnection()的異常處理*/@Deprecatedpublic static ResultSet select(int num) throws SQLException {Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;connection = DBUtil.getConnection();String sql = "select * from bank where num = ?";preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1, num);resultSet = preparedStatement.executeQuery(); // 執行select語句if (resultSet.next()) {System.out.println("num:" + resultSet.getInt("num") +" user:" + resultSet.getString("user") + " money:" + resultSet.getInt("money"));}DBUtil.close(connection, preparedStatement, resultSet);return resultSet;}/*** 實現對bank表中對應數據的查詢* @param num 主鍵值* @return 返回一個Bank類型對象* @throws SQLException DBUtil.getConnection()的異常處理*/public static Bank selectElem(int num) throws SQLException {Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;Bank bank = new Bank();connection = DBUtil.getConnection();String sql = "select * from bank where num = ?";preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1, num);resultSet = preparedStatement.executeQuery(); // 執行select語句if (resultSet.next()) {bank.setNum(resultSet.getInt("num"));bank.setUser(resultSet.getString("user"));bank.setMoney(resultSet.getInt("money"));}DBUtil.close(connection, preparedStatement, resultSet);return bank;} }

    這里也要注意到一點:當執行select查詢語句時,使用的是executeQuery()方法,而增刪改都是使用的executeUpdate()方法;

    總結

    JDBC其實并沒有多少東西,其實總的就是那幾步操作,可能剛一接觸會有點懵,習慣就好了;
    這里還是想提一下:代碼只是參考,我希望你可以通過我的代碼了解到操作方法,可以自己去創建一個數據庫嘗試;
    當然有問題或者想要相關資源評論區可以留言,希望這篇文章可以給你帶來幫助!!!

    總結

    以上是生活随笔為你收集整理的JDBC使用详解的全部內容,希望文章能夠幫你解決所遇到的問題。

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