文章目錄
- 一,JDBC 練習
- --1,利用jdbc給user表中,添加一個用戶的資訊
- --2,模擬用戶登錄
- 二,SQL攻擊
- --1,概述
- --2,改造用戶登錄
- --3,練習: 用新的傳輸器查詢
- 三,優化: 提供jdbc的工具類
- --1,創建工具類
- --2,使用工具類(用新的傳輸器新增)
- --3,改造上面的練習(修改資源釋放的代碼)
- 四,作業
一,JDBC 練習
–1,利用jdbc給user表中,添加一個用戶的資訊
package cn.tedu.jdbc;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.Statement;
//寫jdbc的代碼,向user表里的添加一條資料
public class Test3 {
public static void main(String[] args) throws Exception {
//1,注冊驅動
Class.forName("com.mysql.jdbc.Driver");
//2,獲取連接
String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
Connection c = DriverManager.getConnection(url, "root", "root");
//3,獲取傳輸器
Statement s = c.createStatement();
//4,執行SQL(SQL陳述句中的字串可以用"" 或者 '')
//executeUpdate()用來執行增刪改的SQL,回傳對資料庫的影響行數
//executeQuery()用來執行查詢的SQL,回傳一個結果集物件ResultSet
int rows = s.executeUpdate("insert into user values(null,\"tony\",'1234')");
//5,處理結果集--增刪改的SQL沒有結果集,省略....
//6,釋放資源
s.close();
c.close();
System.out.println("資料入庫成功!");
}
}
–2,模擬用戶登錄
package cn.tedu.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
//寫jdbc的代碼,模擬用戶登錄的程序
//本質上,就是拿到用戶在瀏覽器輸入的賬號和密碼,利用jdbc,去查庫
public class Test4 {
public static void main(String[] args) throws Exception {
//1,注冊驅動
Class.forName("com.mysql.jdbc.Driver");
//2,獲取連接
String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
Connection c = DriverManager.getConnection(url, "root", "root");
//3,獲取傳輸器
Statement s = c.createStatement();
//4,執行SQL
// String sql = "SELECT * FROM USER WHERE NAME='jack' AND pwd='123456'";
//動態的拼接SQL陳述句
System.out.println("請輸入賬號: ");
String a = new Scanner(System.in).nextLine();
System.out.println("請輸入賬密碼: ");
String b = new Scanner(System.in).nextLine();
//動態資料,如果在中間,按照 "+???+"
String sql = "SELECT * FROM USER WHERE NAME='"+a+"' AND pwd='"+b+"'";
ResultSet r = s.executeQuery(sql);
//5,處理結果集(根據用戶名和密碼去查,只會查出來一條記錄)
if(r.next()){//如果查到了資料,才表示庫里有這個用戶資訊
System.out.println("恭喜您,登錄成功~~");
}else{//如果沒查到資料,
System.out.println("請重新輸入....");
}
//6,釋放資源
r.close();
s.close();
c.close();
//1,問題:當用戶輸入特殊值: jack'#時,甚至不需要密碼也能登錄
//2,產生的原因:#在SQL中表示注釋的意思,相當于后面的條件被注釋掉了...
//SELECT * FROM USER WHERE NAME='jack'#' AND pwd='123456'
//現象叫SQL攻擊/SQL注入,本質上就是因為SQL陳述句中出現了特殊符號#
//導致了,SQL語意發生改變
//3,哪里出現的問題?Statement傳輸器不安全,低效
//4,解決方案?使用新的傳輸器PreparedStatement代碼現有的Statement
}
}
二,SQL攻擊
–1,概述
1,問題:當用戶輸入特殊值: jack’#時,甚至不需要密碼也能登錄
2,產生的原因:#在SQL中表示注釋的意思,相當于后面的條件被注釋掉了…
SELECT * FROM USER WHERE NAME=‘jack’ #’ AND pwd=‘123456’
現象叫SQL攻擊/SQL注入,本質上就是因為SQL陳述句中出現了特殊符號#,導致了,SQL語意發生改變
3,哪里出現的問題?Statement傳輸器不安全,低效
4,解決方案?使用新的傳輸器PreparedStatement代碼現有的Statement
5,PreparedStatement工具,安全,高效.而且SQL寫法簡潔.
PreparedStatement把特殊符號#當做普通文本字符在使用,沒有注釋的意思了
–2,改造用戶登錄
package cn.tedu.jdbc;
import java.sql.*;
import java.util.Scanner;
//寫jdbc的代碼,模擬用戶登錄的程序
//本質上,就是拿到用戶在瀏覽器輸入的賬號和密碼,利用jdbc,去查庫
//1,問題:當用戶輸入特殊值: jack'#時,甚至不需要密碼也能登錄
//2,產生的原因:#在SQL中表示注釋的意思,相當于后面的條件被注釋掉了...
//SELECT * FROM USER WHERE NAME='jack'#' AND pwd='123456'
//現象叫SQL攻擊/SQL注入,本質上就是因為SQL陳述句中出現了特殊符號#
//導致了,SQL語意發生改變
//3,哪里出現的問題?Statement傳輸器不安全,低效
//4,解決方案?使用新的傳輸器PreparedStatement代碼現有的Statement
//5,PreparedStatement工具,安全,高效.而且SQL寫法簡潔.
//PreparedStatement把特殊符號當做普通文本字符在使用,沒有注釋的意思了
public class Test4 {
public static void main(String[] args) throws Exception {
//1,注冊驅動
Class.forName("com.mysql.jdbc.Driver");
//2,獲取連接
String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
Connection c = DriverManager.getConnection(url, "root", "root");
// Statement s = c.createStatement();
// String sql = "SELECT * FROM USER WHERE NAME='"+a+"' AND pwd='"+b+"'";
System.out.println("請輸入賬號: ");
String a = new Scanner(System.in).nextLine();
System.out.println("請輸入賬密碼: ");
String b = new Scanner(System.in).nextLine();
//新的傳輸器,執行的SQL有新寫法--sql骨架
String sql = "SELECT * FROM USER WHERE NAME=? AND pwd=?";
//3,獲取 新的傳輸器--安全,高效
PreparedStatement s = c.prepareStatement(sql);
//給SQL系結引數
s.setString(1,a);//給第一個問號,設定a的值
s.setString(2,b);//給第二個問號,設定b的值
//4,執行SQL陳述句
ResultSet r = s.executeQuery();
//5,處理結果集(根據用戶名和密碼去查,只會查出來一條記錄)
if(r.next()){//如果查到了資料,才表示庫里有這個用戶資訊
System.out.println("恭喜您,登錄成功~~");
}else{//如果沒查到資料,
System.out.println("請重新輸入....");
}
//6,釋放資源
r.close();
s.close();
c.close();
}
}
–3,練習: 用新的傳輸器查詢
package cn.tedu.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
//利用新的傳輸器,查詢部門編號為1的資料
public class Test5 {
public static void main(String[] args) throws Exception {
//1,注冊驅動
Class.forName("com.mysql.jdbc.Driver");
//2,獲取連接
String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
Connection c = DriverManager.getConnection(url, "root", "root");
//3,獲取傳輸器,并執行SQL骨架
String sql="select * from dept where deptno = ?";
PreparedStatement s = c.prepareStatement(sql);
//設定SQL的引數--是指給第幾個問號,設定什么值
s.setObject(1,1);
//4,執行SQL
ResultSet r = s.executeQuery();//執行查詢的SQL
//5,決議結果集
while(r.next()){
Object deptno = r.getObject(1);//獲取第1列的值
Object dname = r.getObject(2);//獲取第2列的值
Object loc = r.getObject(3);//獲取第3列的值
System.out.println(""+deptno+dname+loc);
}
//6,釋放資源
r.close();
s.close();
c.close();
}
}
三,優化: 提供jdbc的工具類
–1,創建工具類
package cn.tedu.jdbc;
import java.sql.*;
//充當了jdbc的工具類,抽取一些共性代碼
public class JDBCUtils {
/**
* 釋放資源
* @param r 結果集
* @param s 傳輸器
* @param c 連接器
*/
static public void close(ResultSet r, PreparedStatement s,Connection c){
if(r != null){//防止了空指標例外
try {
r.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {//就是怕close()執行失敗導致發生了例外,進行了catch
r = null;//手動置空,等著GC進行垃圾回收
}
}
if(s != null) {//防止空指標例外
try {
s.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {//就是怕close()執行失敗導致發生了例外,進行了catch
s = null;//手動置空,等著GC進行垃圾回收
}
}
if(c != null) {//防止空指標例外
try {
c.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {//就是怕close()執行失敗導致發生了例外,進行了catch
c = null;//手動置空,等著GC進行垃圾回收
}
}
}
/**
* 獲取資料庫的連接
* @return 將給呼叫者回傳一個和資料庫連接的物件Connection
* @throws Exception
* static:保證資源在記憶體中,貯存的時間長.只會加載一次節省記憶體
* public:工具類可以被所有人使用,最大的訪問權限方便呼叫來呼叫
*/
static public Connection get() throws Exception{
//1,注冊驅動
Class.forName("com.mysql.jdbc.Driver");
//2,獲取連接
String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
Connection c = DriverManager.getConnection(url, "root", "root");
//把獲取到的資料庫的連接,回傳給呼叫者
return c;
}
}
–2,使用工具類(用新的傳輸器新增)
package cn.tedu.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
//利用新的傳輸器結合著工具類,新增一個用戶資訊
public class Test6 {
public static void main(String[] args) throws Exception {
//1,利用工具類,來獲取資料庫的連接
Connection c = JDBCUtils.get();
//2,獲取傳輸器,執行SQL
String sql="insert into user values(null,?,?)";
PreparedStatement p = c.prepareStatement(sql);
//給SQL系結引數
p.setObject(1,"jerry");
p.setObject(2,"123");
//3,執行SQL
p.executeUpdate();//執行增刪改的SQL,回傳一個影響行數(通常不處理)
//4,釋放資源
p.close();
c.close();
}
}
–3,改造上面的練習(修改資源釋放的代碼)
package cn.tedu.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
//利用新的傳輸器結合著工具類,新增一個用戶資訊
public class Test6 {
public static void main(String[] args) {
//擴大變數的作用范圍:為了讓try catch finally都能用
Connection c = null;
PreparedStatement p = null;
try {
//1,利用工具類,來獲取資料庫的連接
c = JDBCUtils.get();
//2,獲取傳輸器,執行SQL
String sql="insert into user values(null,?,?)";
p = c.prepareStatement(sql);
//給SQL系結引數
p.setObject(1,"jerry");
p.setObject(2,"123");
//3,執行SQL
p.executeUpdate();//執行增刪改的SQL,回傳一個影響行數(通常不處理)
}catch (Exception e){
System.out.println("資料插入失敗!!");
}finally {//保證一定會被執行的代碼
//利用工具類close完成釋放資源(新增業務,沒有結果集,傳入null就可以了)
JDBCUtils.close(null,p,c);
}
}
}
四,作業
1, 把JDBCUtils工具類,理解著敲兩遍
2, 把最后一個性練習敲三遍
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/404031.html
標籤:其他
