1. 程式人生 > >SQL注入,PreparedStatement和Statement

SQL注入,PreparedStatement和Statement

程式碼區

還是一個工具類

程式碼:

package cn.itcats.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

//工具類 一個例項都不會有
public final class JdbcUtils {
// 優點修改的時候只需改這一處 私有對你以後類的演化有好處
private static String url = "jdbc:mysql://localhost:3306/test";
private static String user = "root";
private static String password = "123456";
private JdbcUtils() {

}

static {//放入靜態程式碼塊 只執行一次
try {// 優化的目的註冊驅動只能進行一次
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(e);
}

}
public static Connection getConnection() throws SQLException{
return DriverManager.getConnection(url, user, password);
}

public static void free(ResultSet rs,Statement st,Connection conn) {
try {
if(rs!=null)
rs.close();
}catch(SQLException e){
e.printStackTrace();
}finally {
try {
if(st!=null)
st.close();
}catch(SQLException e){
e.printStackTrace();
}finally {
if(conn!=null)
try {
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}

}

在這裡我給        PreparedStatement   和   Statement   執行的時間做了比較      PreparedStatement  寫法的優點較多

程式碼僅供參考:

package cn.itcats.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SQLInject {//C建立 R讀取 U更新 D刪除
public static void main(String[] args) throws Exception{
read1("Jack");
System.out.println("********************************");
read("Jack");
}

static void read1(String name) throws SQLException {
Connection conn = null;
/*
* 與Statement區別 程式修改引入PreparedStatement介面 做一些預處理 特殊字元過濾 系統的優化
* 解決SQl注入的問題
* 在不考慮SQl注入問題基礎上 sql語句執行次數越多 那麼PrepareStatement 效率較高(只有在資料庫連線沒有關閉的條件下)
*/
PreparedStatement ps = null;
ResultSet rs = null;
try {
//2建立連線 最耗時
conn = JdbcUtils.getConnection();
//3建立語句 不能用拼字串的方式 很不安全
long start1 = System.currentTimeMillis(); //毫秒
String sql = "select id,name,birthday,money from user where name=?"; //and id=?and....
ps = conn.prepareStatement(sql);
ps.setString(1, name);
// 1,name 第一個問號替換 name
//4執行語句
System.out.println(sql);
rs = ps.executeQuery(); // 構造的時候已經給他了寫不寫sql都一樣 不需要寫sql

//5處理結果
while(rs.next()) { //行遍歷
System.out.println( //四列 程式碼靈活性提高了
rs.getObject("id") + "\t" + rs.getObject("name") + "\t" +
rs.getObject("birthday") + "\t" + rs.getObject("money"));
}
long end1 = System.currentTimeMillis();
System.out.println("read1 " + (end1 - start1));


} finally {
JdbcUtils.free(rs, ps, conn);

}

}
static void read(String name) throws SQLException {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
//2建立連線
conn = JdbcUtils.getConnection();
//3建立語句
long start = System.currentTimeMillis();
st = conn.createStatement();
//4執行語句
String sql = "select id,name,birthday,money from user where name='"
+ name + "'";

rs = st.executeQuery(sql);
//建議不要*不然會都查出來 可讀性不好 寫列名 維護成本低

//5處理結果
while(rs.next()) { //行遍歷
System.out.println( //四列 程式碼靈活性提高了
rs.getObject("id") + "\t" + rs.getObject("name") + "\t" +
rs.getObject("birthday") + "\t" + rs.getObject("money"));
}
long end = System.currentTimeMillis();
System.out.println("read " + (end - start));


} finally {
JdbcUtils.free(rs, st, conn);

}
}
}