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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JDBC技术详解

發(fā)布時間:2023/12/10 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JDBC技术详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 1 綜述
  • 2 JDBC相關(guān)概念
    • 2.1 什么是JDBC
    • 2.2 JDBC有什么用
    • 2.3 數(shù)據(jù)庫驅(qū)動
    • 2.4 JDBC架構(gòu)
      • 2.4.1 雙層結(jié)構(gòu)
      • 2.4.2 三層架構(gòu)
  • 3 JDBC常用接口
    • 3.1 Driver接口
    • 3.2 Connection接口
    • 3.3 Statement接口
    • 3.4 ResultSet接口
  • 4 JDBC使用方法
    • 4.1 下載jar包
    • 4.2 導(dǎo)入jar包
    • 4.3 JDBC使用步驟
    • 4.4 使用代碼示例
      • 4.4.1 插入更新操作
  • 5 封裝提取工具類
  • 6 SQL注入
    • 6.1 sql注入演示
    • 6.2 PreparedStatement使用示例
  • 7 JDBC操縱事務(wù)
  • 8 批處理

1 綜述

本文檔主要對JDBC進(jìn)行詳細(xì)說明,包括JDBC的相關(guān)概念、架構(gòu)說明、工作原理、常用接口以及具體的使用方法等。

2 JDBC相關(guān)概念

2.1 什么是JDBC

JDBC英文名為:Java Data Base Connectivity(Java數(shù)據(jù)庫連接)

官方解釋它是Java編程語言和廣泛的數(shù)據(jù)庫之間獨(dú)立于數(shù)據(jù)庫的連接標(biāo)準(zhǔn)的Java API,根本上說JDBC是一種規(guī)范,它提供的接口,一套完整的,允許便捷式訪問底層數(shù)據(jù)庫。可以用JAVA來寫不同類型的可執(zhí)行文件:JAVA應(yīng)用程序、JAVA Applets、Java Servlet、JSP等,不同的可執(zhí)行文件都能通過JDBC訪問數(shù)據(jù)庫,又兼?zhèn)浯鎯Φ膬?yōu)勢。簡單說它就是JAVA與數(shù)據(jù)庫的連接的橋梁或者插件,用JAVA代碼就能操作數(shù)據(jù)庫的增刪改查、存儲過程、事務(wù)等。

2.2 JDBC有什么用

我們用JAVA就能連接到數(shù)據(jù)庫;創(chuàng)建SQL或者M(jìn)YSQL語句;執(zhí)行SQL或MYSQL的查詢數(shù)據(jù)庫;查看和修改結(jié)果記錄。

2.3 數(shù)據(jù)庫驅(qū)動

我們安裝好數(shù)據(jù)庫之后,我們的應(yīng)用程序也是不能直接使用數(shù)據(jù)庫的,必須要通過相應(yīng)的數(shù)據(jù)庫驅(qū)動程序,通過驅(qū)動程序去和數(shù)據(jù)庫打交道。其實(shí)也就是數(shù)據(jù)庫廠商的JDBC接口實(shí)現(xiàn),即對Connection等接口的實(shí)現(xiàn)類的jar文件。

下載地址:https://mvnrepository.com/artifact/mysql/mysql-connector-java

2.4 JDBC架構(gòu)

分為雙層架構(gòu)和三層架構(gòu)。

2.4.1 雙層結(jié)構(gòu)

  • 作用:此架構(gòu)中,Java Applet 或應(yīng)用直接訪問數(shù)據(jù)源。
  • 條件:要求 Driver 能與訪問的數(shù)據(jù)庫交互。
  • 機(jī)制:用戶命令傳給數(shù)據(jù)庫或其他數(shù)據(jù)源,隨之結(jié)果被返回。
  • 部署:數(shù)據(jù)源可以在另一臺機(jī)器上,用戶通過網(wǎng)絡(luò)連接,稱為 C/S配置(可以是內(nèi)聯(lián)網(wǎng)或互聯(lián)網(wǎng))。

2.4.2 三層架構(gòu)

3 JDBC常用接口

3.1 Driver接口

Driver接口由數(shù)據(jù)庫廠家提供,作為java開發(fā)人員,只需要使用Driver接口就可以了。在編程中要連接數(shù)據(jù)庫,必須先裝載特定廠商的數(shù)據(jù)庫驅(qū)動程序,不同的數(shù)據(jù)庫有不同的裝載方法。如:

  • 裝載MySql驅(qū)動:
Class.forName("com.mysql.jdbc.Driver");
  • 裝載Oracle驅(qū)動:
Class.forName("oracle.jdbc.driver.OracleDriver");

3.2 Connection接口

Connection與特定數(shù)據(jù)庫的連接,在連接上下文中執(zhí)行sql語句并返回結(jié)果。DriverManager.getConnection(url, user, password)方法建立在JDBC URL中定義的數(shù)據(jù)庫Connection連接上。

  • 連接MySql數(shù)據(jù)庫:
Connection conn = DriverManager.getConnection("jdbc:mysql://host:port/database", "user", "password");
  • 連接Oracle數(shù)據(jù)庫:
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@host:port:database", "user", "password");
  • 連接SqlServer數(shù)據(jù)庫:
Connection conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://host:port; DatabaseName=database", "user", "password");

常用方法:

  • createStatement():創(chuàng)建向數(shù)據(jù)庫發(fā)送sql的statement對象。
  • prepareStatement(sql) :創(chuàng)建向數(shù)據(jù)庫發(fā)送預(yù)編譯sql的PrepareSatement對象。
  • prepareCall(sql):創(chuàng)建執(zhí)行存儲過程的callableStatement對象。
  • setAutoCommit(boolean autoCommit):設(shè)置事務(wù)是否自動提交。
  • commit() :在鏈接上提交事務(wù)。
  • rollback() :在此鏈接上回滾事務(wù)。

3.3 Statement接口

用于執(zhí)行靜態(tài)SQL語句并返回它所生成結(jié)果的對象。

三種Statement類:

  • Statement:由createStatement創(chuàng)建,用于發(fā)送簡單的SQL語句(不帶參數(shù))。
  • PreparedStatement :繼承自Statement接口,由preparedStatement創(chuàng)建,用于發(fā)送含有一個或多個參數(shù)的SQL語句。PreparedStatement對象比Statement對象的效率更高,并且可以防止SQL注入,所以我們一般都使用PreparedStatement。
  • CallableStatement:繼承自PreparedStatement接口,由方法prepareCall創(chuàng)建,用于調(diào)用存儲過程。
  • 常用Statement方法:

    • execute(String sql):運(yùn)行語句,返回是否有結(jié)果集
    • executeQuery(String sql):運(yùn)行select語句,返回ResultSet結(jié)果集。
    • executeUpdate(String sql):運(yùn)行insert/update/delete操作,返回更新的行數(shù)。
    • addBatch(String sql) :把多條sql語句放到一個批處理中。
    • executeBatch():向數(shù)據(jù)庫發(fā)送一批sql語句執(zhí)行。

    3.4 ResultSet接口

    ResultSet提供檢索不同類型字段的方法,常用的有:

    • getString(int index)、getString(String columnName):獲得在數(shù)據(jù)庫里是varchar、char等類型的數(shù)據(jù)對象。
    • getFloat(int index)、getFloat(String columnName):獲得在數(shù)據(jù)庫里是Float類型的數(shù)據(jù)對象。
    • getDate(int index)、getDate(String columnName):獲得在數(shù)據(jù)庫里是Date類型的數(shù)據(jù)。
    • getBoolean(int index)、getBoolean(String columnName):獲得在數(shù)據(jù)庫里是Boolean類型的數(shù)據(jù)。
    • getObject(int index)、getObject(String columnName):獲取在數(shù)據(jù)庫里任意類型的數(shù)據(jù)。
    • 等還有其他的獲取類型方法。

    ResultSet還提供了對結(jié)果集進(jìn)行滾動的方法:

    • next():移動到下一行
    • Previous():移動到前一行
    • absolute(int row):移動到指定行
    • beforeFirst():移動resultSet的最前面。
    • afterLast():移動到resultSet的最后面。

    注意:使用后依次關(guān)閉對象及連接:ResultSet → Statement → Connection。

    4 JDBC使用方法

    4.1 下載jar包

    上面以及展示下載地址,下載合適的版本即可。

    4.2 導(dǎo)入jar包

  • 在項(xiàng)目下建立lib文件夾
  • 將jar包復(fù)制到文件夾中
  • 將文件夾添加為Library
  • 4.3 JDBC使用步驟

    使用JDBC的步驟:

  • 加載JDBC驅(qū)動程序
  • 構(gòu)造數(shù)據(jù)庫鏈接信息
  • 建立數(shù)據(jù)庫連接Connection
  • 創(chuàng)建執(zhí)行SQL的語句Statement對象
  • 使用Statement對象執(zhí)行SQL
  • 處理執(zhí)行結(jié)果ResultSet
  • 釋放資源
  • 4.4 使用代碼示例

    package com.wzh.demo01;import java.sql.*;public class JdbcDemo01 {public static void main(String[] args) throws ClassNotFoundException, SQLException {// 1 加載JDBC驅(qū)動程序Class.forName("com.mysql.jdbc.Driver");// 2 構(gòu)造數(shù)據(jù)庫鏈接信息(以MySql為例)String url = "jdbc:mysql://localhost:3306/test_go?useUnicode=true&characterEncoding=utf8&useSSL=true";String username = "root";String pwd = "root";// 3 建立數(shù)據(jù)庫連接ConnectionConnection connection = DriverManager.getConnection(url, username, pwd);// 4 創(chuàng)建執(zhí)行SQL的語句Statement對象Statement statement = connection.createStatement();// 5 使用Statement對象執(zhí)行SQLString sql = "select * from user";ResultSet resultSet = statement.executeQuery(sql);// 6 處理執(zhí)行結(jié)果ResultSetwhile (resultSet.next()) {System.out.println("id=" + resultSet.getObject("id"));System.out.println("name=" + resultSet.getObject("name"));System.out.println("birthday=" + resultSet.getObject("birthday"));}// 7 釋放資源 (注意關(guān)閉順序)resultSet.close();statement.close();connection.close();} }

    4.4.1 插入更新操作

    String sql = "insert into user(name,birthday) value ('hao','2021-06-28')"; int i = statement.executeUpdate(sql); if(i>0){System.out.println("插入數(shù)據(jù)成功"); }String sql1 = "update user set name='nn' where id = 2"; int i1 = statement.executeUpdate(sql1); if(i1 > 0){System.out.println("更新數(shù)據(jù)成功"); }

    5 封裝提取工具類

  • 在src目錄下新建db.properites用于保存數(shù)據(jù)庫配置信息;
  • driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/test_go?useUnicode=true&characterEncoding=utf8&useSSL=true username=root password=root
  • 新建utils包,再新建JdbcUtils.java文件,寫入如下代碼
  • package com.wzh.demo02.utils;import java.io.InputStream; import java.sql.*; import java.util.Properties;public class JdbcUtils {private static String driver = null;private static String url = null;private static String username = null;private static String password = null;static {try {InputStream is = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");Properties properties = new Properties();properties.load(is);driver = properties.getProperty("driver");url = properties.getProperty("url");username = properties.getProperty("username");password = properties.getProperty("password");// 1 驅(qū)動只用加載一次Class.forName(driver);} catch (Exception e) {e.printStackTrace();}}// 獲取鏈接public static Connection getConnection() throws SQLException {return DriverManager.getConnection(url, username, password);}// 釋放資源public static void release(Connection conn, Statement st, ResultSet rs) throws SQLException {if (rs != null) {rs.close();}if (st != null) {st.close();}if (conn != null) {conn.close();}} }
  • 后可在主函數(shù)使用
  • package com.wzh.demo02;import com.wzh.demo02.utils.JdbcUtils;import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;public class Test {public static void main(String[] args) {Connection conn = null;Statement st = null;ResultSet rs = null;try {conn = JdbcUtils.getConnection();st = conn.createStatement();// 新增String sql_i = "insert into user(name,birthday) value ('張三','2021-06-28')";int i = st.executeUpdate(sql_i);if (i > 0) {System.out.println("插入成功");}// 修改String sql_u = "update user set name='李四' where id = 3";int i1 = st.executeUpdate(sql_u);if (i1 > 0) {System.out.println("更新數(shù)據(jù)成功");}// 刪除String sql_d = "delete from user where id = 3";int i2 = st.executeUpdate(sql_d);if (i2 > 0) {System.out.println("刪除成功");}// 查找String sql_q = "select * from user";rs = st.executeQuery(sql_q);while (rs.next()){System.out.println(rs.getString("name"));}} catch (Exception e) {e.printStackTrace();} finally {try {JdbcUtils.release(conn, st, rs);} catch (SQLException e) {e.printStackTrace();}}} }

    6 SQL注入

    詳細(xì)可觀看此篇博文:https://www.cnblogs.com/myseries/p/10821372.html

    6.1 sql注入演示

    package com.wzh.demo02;import com.wzh.demo02.utils.JdbcUtils;import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;public class Sql注入 {public static void main(String[] args) {//正常使用//login("hao", "123456");// 此時為sql注入login(" 'or '1=1","123456");}public static void login(String username, String password) {Connection conn = null;Statement st = null;ResultSet rs = null;try {conn = JdbcUtils.getConnection();st = conn.createStatement();String sql_login = "select * from user where name='" + username + "' and password='" + password + "'";rs = st.executeQuery(sql_login);if (rs.next()) {System.out.println("登錄成功");}else{System.out.println("登錄失敗");}} catch (Exception e) {e.printStackTrace();} finally {try {JdbcUtils.release(conn, st, rs);} catch (SQLException e) {e.printStackTrace();}}}}

    由上可知Statement是不安全的,PreparedStatement可以防止SQL注入。效率更高。

    6.2 PreparedStatement使用示例

    package com.wzh.demo02;import com.wzh.demo02.utils.JdbcUtils;import java.sql.*;public class JdbcDemo03 {public static void main(String[] args) {Connection conn = null;PreparedStatement st = null;ResultSet rs = null;try {conn = JdbcUtils.getConnection();// 區(qū)別:先寫sql// 使用 ? 占位符代替參數(shù)String sql_i = "insert into user(name,birthday) value (?,?)";st = conn.prepareStatement(sql_i); // 預(yù)編譯sql,// 手動給參數(shù)賦值st.setString(1, "lisi");st.setDate(2, new java.sql.Date(new java.util.Date().getTime()));int i = st.executeUpdate();if (i > 0) {System.out.println("插入成功");}} catch (Exception e) {e.printStackTrace();} finally {try {JdbcUtils.release(conn, st, rs);} catch (SQLException e) {e.printStackTrace();}}} }

    此種方式可以避免sql注入。

    7 JDBC操縱事務(wù)

    事務(wù)的四大特性:

    • 原子性(Atomictiy):不可再分割
    • 一致性(Consistency):數(shù)據(jù)前后一致,總量保持不變
    • 隔離性(Isolation):多個事務(wù)互不干擾
    • 持久性(Durability):一旦提交不可逆,持久化到數(shù)據(jù)庫

    事務(wù)的隔離級別:

  • 讀未提交(Read Uncommitted):最低級別,存在臟讀、幻讀、不可重復(fù)讀問題;
  • 讀已提交(Read Committed):可避免臟讀情況發(fā)生;
  • 可重復(fù)讀(Repeatable Read):可避免臟讀、不可重復(fù)讀情況的發(fā)生;
  • 序列化(Serializable):可避免臟讀、不可重復(fù)讀、幻讀情況的發(fā)生。(串行化)
  • 隔離性問題:

    • 臟讀:一個事務(wù)讀取了另一個沒有提交的事務(wù)數(shù)據(jù)
    • 不可重復(fù)讀:在同一個事務(wù)內(nèi),相同的語句讀取出來的數(shù)據(jù)不一致
    • 幻讀:在一個事務(wù)內(nèi),讀取到別的數(shù)據(jù)插入的數(shù)據(jù),導(dǎo)致前后讀出來的數(shù)據(jù)結(jié)果條數(shù)不一致。
    package com.wzh.demo02;import com.wzh.demo02.utils.JdbcUtils;import java.sql.*;public class JdbcTransaction {public static void main(String[] args) {Connection conn = null;PreparedStatement st = null;ResultSet rs = null;try {conn = JdbcUtils.getConnection();// 關(guān)閉自動提交 并且會自動開啟事務(wù)conn.setAutoCommit(false);String sql1 = "update user set money = money - 100 where id = 1";st = conn.prepareStatement(sql1);st.executeUpdate();String sql2 = "update user set money = money + 100 where id = 2";st = conn.prepareStatement(sql2);st.executeUpdate();// 業(yè)務(wù)完畢 提交事務(wù)conn.commit();} catch (Exception e) {try {conn.rollback();} catch (SQLException e1) {e1.printStackTrace();}e.printStackTrace();} finally {try {JdbcUtils.release(conn, st, rs);} catch (SQLException e) {e.printStackTrace();}}} }

    修改事務(wù)隔離級別

    conn = JdbcUtils.getConnection(); conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);//避免臟讀 conn.setAutoCommit(false);

    8 批處理

    package com.wzh.demo02;import com.wzh.demo02.utils.JdbcUtils;import java.sql.*;public class JdbcDemo04 {public static void main(String[] args) {Connection conn = null;Statement st = null;ResultSet rs = null;try {conn = JdbcUtils.getConnection();conn.setAutoCommit(false); //設(shè)為手動提交long start = System.currentTimeMillis();st = conn.createStatement();for (int i = 0; i < 100; i++) {st.addBatch("insert into user (name,birthday) values ('hao'" + i + ",'2021-06-28')");}st.executeBatch();conn.commit(); //提交事務(wù)long end = System.currentTimeMillis();System.out.println("插入100條數(shù)據(jù),耗時(ms):" + (end - start));} catch (Exception e) {e.printStackTrace();} finally {try {JdbcUtils.release(conn, st, rs);} catch (SQLException e) {e.printStackTrace();}}} }

    以上基本就是jdbc基本的使用方式,后續(xù)會再專門寫一篇關(guān)于數(shù)據(jù)庫連接池技術(shù)c3p0,dbcp與druid的使用。

    總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。