JDBC API 学习
前情提要:MySQL數(shù)據(jù)庫驅(qū)動JDBC實(shí)操隨筆(附文件)_年關(guān)的博客-CSDN博客
目錄
一、DriverManager
二、ResultSet
?編輯
三、?Statement
四、做個登陸驗(yàn)證(假的-都是假的)
演示sql注入
演示PreparedStatement預(yù)編譯防止sql注入
咱們使用@Test注解進(jìn)行測試,沒有環(huán)境的自己裝一下或者改一下代碼
一、DriverManager
DriverManager在java.sql這個包里面,管理一組 JDBC 驅(qū)動程序的基本服務(wù)
先看DriverManager經(jīng)典使用場景
作用:1、管理和注冊驅(qū)動
? ? ? ? ? ? ? ? 2、創(chuàng)建數(shù)據(jù)庫連接
功能:就是類中的方法:registerDriver和getConnection 1.registerDriver注冊驅(qū)動:告訴程序該使用哪一個數(shù)據(jù)庫驅(qū)動jar static void registerDriver(Driver driver)//注冊與給定的驅(qū)動程序DriverManager寫的代碼使用: Class.forName("com.mysql.jdbc.Driver"); 通過查看源碼發(fā)現(xiàn):在com.mysql.jdbc.Driver類中存在靜態(tài)代碼塊Static {try{java.sql.DriverManager.registerDriver(new Driver);}catch (SQLException E){throw new RuntimeException("Can't register driver!");} } 注意的是:在mysql5之后的驅(qū)動jar包可以省略注冊驅(qū)動的步驟2.getConnection獲取數(shù)據(jù)庫連接方法:static Connection getConnection(String url,String username,String password)參數(shù):url:指定連接的路徑語法:jdbc:mysql://ip地址(域名):端口號/數(shù)據(jù)庫名稱例子:jdbc:mysql://localhost:3306/employee細(xì)節(jié):如果連接是本機(jī)Mysql服務(wù)器,并且默認(rèn)的端口是3306,則url可以 簡寫為:jdbc:mysql:///數(shù)據(jù)庫名二、ResultSet
從數(shù)據(jù)庫獲取返回結(jié)果集,用于查詢語句
@Testpublic void ResultSet1() throws Exception {//1、注冊驅(qū)動Class.forName("com.mysql.jdbc.Driver");String url="jdbc:mysql://192.168.5.222:3306/test";//這里的192.168.5.222:3306指的是我mysql服務(wù)器的ip如果是本機(jī)的mysql的話用下面這段//String url="jdbc:mysql://127.0.0.1:3306/test";//test指的是所需要用的數(shù)據(jù)庫系統(tǒng)中的具體某一個數(shù)據(jù)庫String username="root";String password="123456";//數(shù)據(jù)庫的賬號密碼Connection conn= DriverManager.getConnection(url,username,password);//sqlString sql="select * from sjj";//4獲取執(zhí)行sql的對象Statement stmt=conn.createStatement();//6.執(zhí)行查詢,得到ResultSetResultSet resultSet=stmt.executeQuery(sql);//處理ResultSetSystem.out.println("book_id\t|\tbook_name");System.out.println(resultSet);while(resultSet.next()) {int id = resultSet.getInt(1);String name = resultSet.getString("name");System.out.print(id +"\t\t\t");System.out.print(name +"\n");}resultSet.close();stmt.close();conn.close();}@Test/** 查詢數(shù)據(jù)將數(shù)據(jù)存放到sjj對象中* 1 定義實(shí)體類sjj* 2 查詢數(shù)據(jù),封裝到sjj* 將Account對象存到ArrayList對象中去* */public void ResultSet2() throws Exception {//1、注冊驅(qū)動Class.forName("com.mysql.jdbc.Driver");String url="jdbc:mysql://192.168.5.222:3306/test";//這里的192.168.5.222:3306指的是我mysql服務(wù)器的ip如果是本機(jī)的mysql的話用下面這段//String url="jdbc:mysql://127.0.0.1:3306/test";//test指的是所需要用的數(shù)據(jù)庫系統(tǒng)中的具體某一個數(shù)據(jù)庫String username="root";String password="123456";//數(shù)據(jù)庫的賬號密碼Connection conn= DriverManager.getConnection(url,username,password);//sqlString sql="select * from sjj";//4獲取執(zhí)行sql的對象Statement stmt=conn.createStatement();//6.執(zhí)行查詢,得到ResultSetResultSet resultSet=stmt.executeQuery(sql);//處理ResultSetSystem.out.println("book_id\t|\tbook_name");//創(chuàng)建集合存放sjj對象List<sjj> list=new ArrayList<>();System.out.println(resultSet);while(resultSet.next()) {sjj sjj=new sjj();int id = resultSet.getInt(1);String name = resultSet.getString("name");System.out.print(id +"\t\t\t");System.out.print(name +"\n");sjj.setId(id);sjj.setName(name);list.add(sjj);}System.out.println(list);resultSet.close();stmt.close();conn.close();}?這里我們需要創(chuàng)建一個和實(shí)體類來存放數(shù)據(jù)
package pojo;public class sjj {private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "sjj{" +"id=" + id +", name='" + name + '\'' +'}';} }三、?Statement
可以用于執(zhí)行DML DDL DQL語句
package JDBC_API;import org.testng.annotations.Test;import java.sql.*;//Statement public class JDbc4_Statement {/*執(zhí)行dml語句*/@Test/*測試方法*/public void testDML() throws Exception {////1、注冊驅(qū)動Class.forName("com.mysql.jdbc.Driver");String url="jdbc:mysql://192.168.5.222:3306/test";String username="root";String password="123456";Connection conn= DriverManager.getConnection(url,username,password);//sqlString sql="update sjj set id=10 where id=5";//4獲取執(zhí)行sql的對象Statement stmt=conn.createStatement();//6.執(zhí)行sqlint count=stmt.executeUpdate(sql);System.out.println(count);stmt.close();conn.close();}@Testpublic void jdbcDDL() throws Exception{//1、注冊驅(qū)動Class.forName("com.mysql.jdbc.Driver");String url="jdbc:mysql://192.168.5.222:3306/test";String username="root";String password="123456";Connection conn= DriverManager.getConnection(url,username,password);//sqlString sql="create database db2";//4獲取執(zhí)行sql的對象Statement stmt=conn.createStatement();//6.執(zhí)行sql 、、DDL語句返回值不再是數(shù)字。所以下面的方法注釋掉try {stmt.executeUpdate(sql);System.out.println("執(zhí)行成功");} catch (Exception e) {System.out.println("執(zhí)行失敗");throw new RuntimeException(e);} // if(count>0){ // System.out.println("執(zhí)行成功"); // }else { // System.out.println("執(zhí)行失敗"); // }stmt.close();conn.close();} }四、做個登陸驗(yàn)證(假的-都是假的)
咱們這里用書籍id和名字做賬號密碼測試
//做個登錄驗(yàn)證@Testpublic void ResultSet1() throws Exception {//1、注冊驅(qū)動Class.forName("com.mysql.cj.jdbc.Driver");String url="jdbc:mysql://192.168.5.222:3306/test";//這里的192.168.5.222:3306指的是我mysql服務(wù)器的ip如果是本機(jī)的mysql的話用下面這段//String url="jdbc:mysql://127.0.0.1:3306/test";//test指的是所需要用的數(shù)據(jù)庫系統(tǒng)中的具體某一個數(shù)據(jù)庫String username="root";String password="123456";//數(shù)據(jù)庫的賬號密碼Connection conn= DriverManager.getConnection(url,username,password);//接收用戶名和密碼String Username="仙逆";String pwd="6";String sql="select * from sjj where name='"+Username+"' and id="+pwd+"";System.out.println(sql);//獲取sql對象Statement stmt=conn.createStatement();//執(zhí)行sql語句ResultSet rs=stmt.executeQuery(sql);//判斷登陸是否成功if(rs.next()){System.out.println("登陸成功");}else {System.out.println("登陸失敗");}//釋放資源rs.close();stmt.close();conn.close();}?結(jié)果
select * from sjj where name='仙逆' and id=6 登陸成功=============================================== Default Suite Total tests run: 1, Passes: 1, Failures: 0, Skips: 0 ===============================================進(jìn)程已結(jié)束,退出代碼0演示sql注入
//演示sql注入@Testpublic void login_Inject() throws Exception {//1、注冊驅(qū)動Class.forName("com.mysql.cj.jdbc.Driver");String url="jdbc:mysql://192.168.5.222:3306/test";//這里的192.168.5.222:3306指的是我mysql服務(wù)器的ip如果是本機(jī)的mysql的話用下面這段//String url="jdbc:mysql://127.0.0.1:3306/test";//test指的是所需要用的數(shù)據(jù)庫系統(tǒng)中的具體某一個數(shù)據(jù)庫String username="root";String password="123456";//數(shù)據(jù)庫的賬號密碼Connection conn= DriverManager.getConnection(url,username,password);//接收用戶名和密碼String Username="xcxcxcc";//一個不存在的賬號String pwd="'' or '1'='1'";String sql="select * from sjj where name='"+Username+"' and id="+pwd+"";System.out.println(sql);//獲取sql對象Statement stmt=conn.createStatement();//執(zhí)行sql語句ResultSet rs=stmt.executeQuery(sql);//判斷登陸是否成功if(rs.next()){System.out.println("登陸成功");}else {System.out.println("登陸失敗");}//釋放資源rs.close();stmt.close();conn.close();}結(jié)果注入成功
select * from sjj where name='xcxcxcc' and id='' or '1'='1' 登陸成功=============================================== Default Suite Total tests run: 1, Passes: 1, Failures: 0, Skips: 0 ===============================================進(jìn)程已結(jié)束,退出代碼0日志
演示PreparedStatement預(yù)編譯防止sql注入
在這里說明一下,只是使用這個方法的話僅有防注入功能,如果真的通過預(yù)編譯提升性能請?jiān)谶B接url參數(shù)里設(shè)置打開!!!!!
//演示PreparedStatement預(yù)編譯防止sql注入@Testpublic void login_Inject2() throws Exception {//1、注冊驅(qū)動Class.forName("com.mysql.cj.jdbc.Driver");//useServerPrepStmts=true開啟預(yù)編譯功能String url="jdbc:mysql://192.168.5.222:3306/test?useServerPrepStmts=true";//這里的192.168.5.222:3306指的是我mysql服務(wù)器的ip如果是本機(jī)的mysql的話用下面這段//String url="jdbc:mysql://127.0.0.1:3306/test";//test指的是所需要用的數(shù)據(jù)庫系統(tǒng)中的具體某一個數(shù)據(jù)庫String username="root";String password="123456";//數(shù)據(jù)庫的賬號密碼Connection conn= DriverManager.getConnection(url,username,password);//接收用戶名和密碼String Username="xcxcxcc";//一個不存在的賬號String pwd="'' or '1'='1'";String sql="select * from sjj where name=? and id=?";System.out.println(sql);//獲取sql對象PreparedStatement pstmt=conn.prepareStatement(sql);pstmt.setString(1,Username);pstmt.setString(2,pwd);ResultSet rs=pstmt.executeQuery();//運(yùn)行時(shí)不再需要寫語句//判斷登陸是否成功if(rs.next()){System.out.println("登陸成功");}else {System.out.println("登陸失敗");}//釋放資源rs.close();pstmt.close();conn.close();}運(yùn)行結(jié)果:
select * from sjj where name=? and id=? 登陸失敗=============================================== Default Suite Total tests run: 1, Passes: 1, Failures: 0, Skips: 0 ===============================================改回來用戶名和密碼
//接收用戶名和密碼String Username="仙逆";//一個不存在的賬號String pwd="6";數(shù)據(jù)庫預(yù)編譯,自己查查吧
select * from sjj where name=? and id=? 登陸成功=============================================== Default Suite Total tests run: 1, Passes: 1, Failures: 0, Skips: 0 ===============================================進(jìn)程已結(jié)束,退出代碼0日志多了一個預(yù)編譯狀態(tài)
在這里如果我們保持語句不變的情況下更改參數(shù)進(jìn)行多次sql查詢
?數(shù)據(jù)庫將會復(fù)用曾經(jīng)的預(yù)編譯,以此減少性能開銷
總結(jié)
以上是生活随笔為你收集整理的JDBC API 学习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Outlook关闭时最小化到任务栏的完美
- 下一篇: 职场人士升职加薪必备的工作软件,总有一款