一步一步学会JDBC
文章目錄
- 一、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) |
| Connection | java程序與特定的數(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ā)中最常用的
解釋說明
- 完整的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)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tracert路由检测命令使用方法
- 下一篇: TCP-IP协议详解(2) 小喇叭开始广