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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

一步一步学会JDBC

發(fā)布時(shí)間:2023/12/10 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一步一步学会JDBC 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

      • 一、JDBC基本知識(shí)
      • 二、java中與JDBC相關(guān)的接口
      • 三、JDBC編程的步驟
        • 1.步驟總覽
        • 2.重點(diǎn)說下前三步
          • 2.1注冊(cè)驅(qū)動(dòng)
          • 2.2.獲取Connection連接:DriverManager.getConnection方法
          • 2.3.獲取數(shù)據(jù)庫操作對(duì)象:通過Connection接口中的方法創(chuàng)建對(duì)象
        • 3.JDBC完整的6步
      • 四.封裝工具類
      • 五、總結(jié)

一、JDBC基本知識(shí)

是什么

  • 英文全稱:Java DataBase Connectivity(java語言連接數(shù)據(jù)庫)
  • 是sun公司制定一套規(guī)范,一套接口

為什么要有JDBC(接口)

  • 因?yàn)槊恳粋€(gè)數(shù)據(jù)庫的底層實(shí)現(xiàn)原理不一樣,恰恰符合面向接口編程,下面解釋

JDBC接口的調(diào)用者與實(shí)現(xiàn)者

  • 調(diào)用者:java程序員,調(diào)用這個(gè)接口就可以連接數(shù)據(jù)庫并進(jìn)行操作,而不管連接的是哪一個(gè)數(shù)據(jù)庫
  • 實(shí)現(xiàn)者:各大數(shù)據(jù)庫廠家,如:MySQL,SQL Sever,Oracle等等,該公司的程序員編寫程序?qū)崿F(xiàn)JDBC接口

一圖搞懂JDBC接口

驅(qū)動(dòng):各大數(shù)據(jù)庫廠家實(shí)現(xiàn)JDBC接口的實(shí)現(xiàn)類也叫驅(qū)動(dòng),也就是jar包,需要java程序員到官網(wǎng)上下載

二、java中與JDBC相關(guān)的接口

相關(guān)的接口與類位于java.sql包下,

接口解釋
DriverMannger類管理一組JDBC驅(qū)動(dòng)程序,用于注冊(cè)驅(qū)動(dòng)
Connectionjava程序與特定的數(shù)據(jù)庫連接
Statement用于數(shù)據(jù)庫操作
PreparedStatement用于數(shù)據(jù)庫操作,Statement的子接口,下文寫區(qū)別
ResultSet數(shù)據(jù)庫查詢返回的結(jié)果集

java與數(shù)據(jù)庫的連接與操作靠這幾個(gè)接口(類)就可以實(shí)現(xiàn),并且調(diào)用前一個(gè)接口的方法可以生成,下一個(gè)類的對(duì)象,是層層遞進(jìn)的關(guān)系

三、JDBC編程的步驟

1.步驟總覽

2.重點(diǎn)說下前三步

后三步的代碼背后沒有多少內(nèi)容,所以先暫時(shí)放放

2.1注冊(cè)驅(qū)動(dòng)
  • 告訴java程序,即將要連接的是哪個(gè)品牌的數(shù)據(jù)庫

導(dǎo)入MySQL的jar包(驅(qū)動(dòng))
右擊項(xiàng)目---->Open Module Settings

找到j(luò)ar包點(diǎn)擊ok即可

代碼注冊(cè)驅(qū)動(dòng)

/*** @author Think-Coder* @data 2020/5/5 15:11*/ import java.sql.*; public class JDBCTest03 {public static void main(String[] args){try{//1.注冊(cè)驅(qū)動(dòng)常用方式//為什么常用:因?yàn)閰?shù)是一個(gè)字符串,字符串可以寫道xxx.properties文件中Class.forName("com.mysql.jdbc.Driver");}catch(Exception e){e.printStackTrace();}} }

com.mysql.jdbc.Driver類源碼

public class Driver extends NonRegisteringDriver implements java.sql.Driver {public Driver() throws SQLException {}static {try {//這個(gè)方法是注冊(cè)MySQL驅(qū)動(dòng)的DriverManager.registerDriver(new Driver());} catch (SQLException var1) {throw new RuntimeException("Can't register driver!");}} }

整個(gè)注冊(cè)驅(qū)動(dòng)方法驅(qū)動(dòng)在static靜態(tài)代碼塊中,當(dāng)執(zhí)行Class.forName(“com.mysql.jdbc.Driver”);時(shí)會(huì)加載com.mysql.jdbc.Driver類,此時(shí)static靜態(tài)代碼塊執(zhí)行,便會(huì)注冊(cè)驅(qū)動(dòng)了

2.2.獲取Connection連接:DriverManager.getConnection方法
  • 表示JVM的進(jìn)程和數(shù)據(jù)庫進(jìn)程之間的通道打開了
  • 進(jìn)程通信,重量級(jí)的,使用完一定要關(guān)閉

方法參數(shù)需要提供

url(統(tǒng)一資源定位符)如:jdbc:mysql://127.0.0.1:3306/selfprojjdbc:mysql:// 協(xié)議127.0.0.1 IP地址3306 端口號(hào)selfproj 數(shù)據(jù)庫名賬號(hào):root密碼:123456

代碼如下:

conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/selfproj?characterEncoding=utf8","root","123456");

getConnection方法中是三個(gè)字符串參數(shù),可以放在外部配置文件中
當(dāng)更改數(shù)據(jù)庫時(shí),只要更改外部配置文件就搞定,不需要重新啟動(dòng)服務(wù),這個(gè)很重要
咱們記住一條規(guī)律
只要參數(shù)是字符串,用戶需要?jiǎng)討B(tài)變化的,都可以寫在外部配置文件中

2.3.獲取數(shù)據(jù)庫操作對(duì)象:通過Connection接口中的方法創(chuàng)建對(duì)象

創(chuàng)建Statement對(duì)象,通過Connection接口的createStatement()方法

try {//1.注冊(cè)驅(qū)動(dòng)Class.forName("com.mysql.jdbc.Driver");//2.獲取鏈接conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/selfproj?useUnicode=true&characterEncoding=utf8","root","123456");//3.獲取數(shù)據(jù)庫操作對(duì)象stmt = conn.createStatement();//4.執(zhí)行sql//存在sql注入問題//假如此時(shí)userName="張三",userPwd="張三'or'1'='1"//通過字符串拼接將sql關(guān)鍵字or拼接進(jìn)去//String sql="select * from user where name='張三' and pwd ='張三'or'1'='1'"//不需要正確的用戶名及密碼就能此時(shí)就能進(jìn)入系統(tǒng)String sql = "select * from user where name='"+userName+"'and pwd ='"+userPwd+"'";//以上正好完成了sql語句的拼接//以下代碼的含義是,發(fā)送sql語句給DBMS,DBMS進(jìn)行sql編譯rs = stmt.executeQuery(sql);if(rs.next()){loginSucess = true;}}catch (Exception e) {e.printStackTrace();}

因?yàn)榇嬖赟QL注入問題,平時(shí)開發(fā)基本不用Statement對(duì)象,所以沒有貼完整得代碼

3.JDBC完整的6步

接下來會(huì)寫一個(gè)用戶登錄完整的代碼
將JDBC的6步完全融合進(jìn)去,使用了PreparedStatement對(duì)象,操作數(shù)據(jù)庫,是開發(fā)中最常用的

public class JDBCTest08 {public static void main(String[] args) {//初始化一個(gè)界面Map<String,String> userLoginInfo = initUI();//驗(yàn)證用戶名和密碼boolean loginSucess = false;try {loginSucess = login(userLoginInfo);} catch (Exception e) {e.printStackTrace();}System.out.println(loginSucess?"登錄成功":"登錄失敗");}//用戶登錄的方法public static boolean login(Map<String,String> userLoginInfo){//打標(biāo)記boolean loginSucess = false;Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;//單獨(dú)定義變量String userName = userLoginInfo.get("loginName");String userPwd = userLoginInfo.get("loginPwd");try {//1.注冊(cè)驅(qū)動(dòng)Class.forName("com.mysql.jdbc.Driver");//2.獲取鏈接conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/selfproj?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT", "root", "123456");//3.獲取數(shù)據(jù)庫預(yù)編譯PreparedStatement對(duì)象//sql語句框子,一個(gè)?代表一個(gè)占位符String sql = "select * from test where id=? and pwd=?";//程序執(zhí)行到此,會(huì)發(fā)送sql語句框子給DBMS,然后DBMS進(jìn)行sql語句的預(yù)先編譯//此時(shí)sql語句中沒有用戶輸入的值,很好的解決了sql注入問題ps = conn.prepareStatement(sql);//給?占位符傳值ps.setString(1, userName);ps.setString(2, userPwd);//4.執(zhí)行sqlrs = ps.executeQuery();//5.處理返回的結(jié)果集// rs為返回的結(jié)果集if (rs.next()) {loginSucess = true;}}catch (Exception e){e.printStackTrace();} finally {//6.釋放資源if (rs != null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if (ps != null) {try {ps.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}return loginSucess;}//用戶輸入的方法private static Map<String, String> initUI() {Scanner s = new Scanner(System.in);System.out.println("用戶名:");String loginName = s.nextLine();System.out.println("密碼:");String loginPwd = s.nextLine();Map<String,String> userLoginInfo = new HashMap<>();userLoginInfo.put("loginName",loginName);userLoginInfo.put("loginPwd",loginPwd);return userLoginInfo;} }

解釋說明

  • 完整的JDBC編程6步就寫完了,JDBC編程6步是針對(duì)于查詢的
  • 對(duì)于增刪改的,是不需要第5步的,因?yàn)闆]有返回查詢結(jié)果集
  • 使用增刪改時(shí),只需將第4步ps.executeQuery()變?yōu)閜s.executeUpdate()就可以了,代碼我就不寫了,哈哈

下面對(duì)比Statement對(duì)象和PreparedStatement對(duì)象

  • 1.Statement存在sql注入問題,PreparedStatement解決了sql注入問題。
  • 2.PreparedStatement執(zhí)行效率高,編譯一次執(zhí)行多次,因?yàn)橄嗤膕ql語句不會(huì)再編譯
    • 而Statement編譯一次執(zhí)行一次,因?yàn)榛旧蟬ql語句不會(huì)相同
  • 3.PreparedStatement會(huì)在編譯階段做類型檢查

總結(jié):開發(fā)場景中99%使用PreparedStatement對(duì)象,在需要SQL注入的業(yè)務(wù)場景中使用Statement

四.封裝工具類

注冊(cè)驅(qū)動(dòng)、連接數(shù)據(jù)庫和釋放連接經(jīng)常使用可以封裝到工具類中

public class DBUtil {/** 工具類中的構(gòu)造方法都是私有的* 因?yàn)楣ぞ哳惍?dāng)中的方法是靜態(tài)的,不需要new對(duì)象,直接采用類名調(diào)用* */private DBUtil(){}//靜態(tài)代碼塊在類加載時(shí)執(zhí)行,并且只執(zhí)行一次static {try {Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}}/** 獲取數(shù)據(jù)庫連接對(duì)象* */public static Connection getConnection()throws Exception{return DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/selfproj?useUnicode=true&characterEncoding=utf8","root","123456");}/** 關(guān)閉資源* */public static void close(Connection conn, Statement ps, ResultSet rs){if (rs != null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if (ps != null) {try {ps.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}} }

使用工具類,實(shí)現(xiàn)模糊查詢

public static void main(String[] args) {Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {//使用工具類獲取連接conn=DBUtil.getConnection();//獲取預(yù)編譯的數(shù)據(jù)庫操作對(duì)象String sql = "select * from user where pwd like ?";ps = conn.prepareStatement(sql);//實(shí)現(xiàn)查詢密碼第二位是2的ps.setString(1,"_2%");rs=ps.executeQuery();while(rs.next()){System.out.println(rs.getString("pwd"));}} catch (Exception e) {e.printStackTrace();}finally {//使用工具類釋放資源DBUtil.close(conn,ps,rs);}}

五、總結(jié)

JDBC是一套讓各個(gè)數(shù)據(jù)庫廠家實(shí)現(xiàn)的接口,通過調(diào)用這些接口,實(shí)現(xiàn)java程序連接數(shù)據(jù)庫,很好體現(xiàn)面向接口編程的特點(diǎn)

總結(jié)

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

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