20160408javaweb之JDBC ---PreparedStatement

破玉發表於2016-04-08

PreparedStatement
1.Sql注入:由於jdbc程式在執行的過程中sql語句在拼裝時使用了由頁面傳入引數,如果使用者惡意傳入一些sql中的特殊關鍵字,會導致sql語句意義發生變化,這種攻擊方式就叫做sql注入,參考使用者註冊登入案例。
2.PreparedStatement是Statement的孩子,不同的是,PreparedStatement使用預編譯機制,在建立PreparedStatement物件時就需要將sql語句傳入,傳入的過程中引數要用?替代,這個過程回導致傳入的sql被進行預編譯,然後再呼叫PreparedStatement的setXXX將引數設定上去,由於sql語句已經經過了預編譯,再傳入特殊值也不會起作用了。
3.PreparedStatement使用了預編譯機制,sql語句在執行的過程中效率比Statement要高。

 

 


SQL隱碼攻擊:
由於dao中執行的SQL語句是拼接出來的,其中有一部分內容是由使用者從客戶端傳入,所以當使用者傳入的資料中包含sql關鍵字時,就有可能通過這些關鍵字改變sql語句的語義,從而執行一些特殊的操作,這樣的攻擊方式就叫做sql注入攻擊

PreparedStatement利用預編譯的機制將sql語句的主幹和引數分別傳輸給資料庫伺服器,從而使資料庫分辨的出哪些是sql語句的主幹哪些是引數,這樣一來即使引數中帶了sql的關鍵字,資料庫伺服器也僅僅將他當作引數值使用,關鍵字不會起作用,從而從原理上防止了sql注入的問題

PreparedStatement主要有如下的三個優點:
~1.可以防止sql注入
~2.由於使用了預編譯機制,執行的效率要高於Statement
~3.sql語句使用?形式替代引數,然後再用方法設定?的值,比起拼接字串,程式碼更加優雅.

 

示例程式碼:

 

package com.dzq.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.dzq.domian.User;
import com.dzq.util.JDBCUtils;

public class MySqlUserDao2  implements UserDao{

    @Override
    public User findUserByUserName(String username) {
        
        String sql="select * from users where username=?";
        Connection conn=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try {
            conn=JDBCUtils.getConn();
            ps=conn.prepareStatement(sql);
            ps.setString(1, username);
            rs=ps.executeQuery();
            if(rs.next()){
                User user=new User();
                user.setId(rs.getInt("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                user.setNickname(rs.getString("nickname"));
                user.setEmail(rs.getString("email"));
                return user;
            }else{
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            JDBCUtils.close(rs, ps, conn);
        }
    }

    @Override
    public void addUser(User user) {
        String sql="insert into users values (null,?,?,?,?)";
        Connection conn=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try {
            conn=JDBCUtils.getConn();
            ps=conn.prepareStatement(sql);
            ps.setString(1, user.getUsername());
            ps.setString(2, user.getPassword());
            ps.setString(3, user.getNickname());
            ps.setString(4, user.getEmail());
            //int count=stat.executeUpdate(sql);
            int count=ps.executeUpdate();
            
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            JDBCUtils.close(rs, ps, conn);
        }
        
}
        

    @Override
    public User findUserByUNAndPWD(String username, String password) {
        
        String sql="select * from users where username=? and password=?";
        Connection conn=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try {
            conn=JDBCUtils.getConn();
            ps=conn.prepareStatement(sql);
            ps.setString(1, username);
            ps.setString(2, password);
            rs=ps.executeQuery();
            if(rs.next()){
                User user=new User();
                user.setId(rs.getInt("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                user.setNickname(rs.getString("nickname"));
                user.setEmail(rs.getString("email"));
                return user;
            }else{
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            JDBCUtils.close(rs, ps, conn);
        }
    }

}

 

相關文章