SQL的注入有关问题

SQL的注入问题

原始代码:

package jdbc;

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

/**
 *
 * @author HaoWang
 */
public class SQLInject {
    public static void main(String[] args) {
        read("Tom");
        read("'or 1 or'");
    }
    public static void read(String name) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            st = conn.createStatement();
            rs = st.executeQuery("Select sid,name,sex,birthday from Students where name='"+name+"'");
            while (rs.next()) {
                System.out.println(rs.getObject(1) + "\t" + rs.getObject(2) + "\t" + rs.getObject(3) + "\t" + rs.getObject(4));
            }
        } catch (SQLException ex) {
            System.out.println(ex.toString());
        } finally {
            JdbcUtils.free(conn, st, rs);
        }
    }
}

 

产生SQL注入问题的原因:在SQL中包含特殊字符或SQL的关键字(如:' or 1 or ')时,会产生不可意料的结果。

 

 解决方案:可用PreparedStatement来解决。

 

PreperedStatement(从Statement扩展而来)相对Statement的优点:
  1.没有SQL注入的问题。
  2.Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。
  3.数据库和驱动可以对PreperedStatement进行优化(只有在相关联的数据库连接没有关闭的情况下有效)。

public static void read1(String name) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        String sql = null;
        try {
            conn = JdbcUtils.getConnection();
            sql = "Select sid,name,sex,birthday from Students where name=?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, name);
            rs = ps.executeQuery();
            while (rs.next()) {
                System.out.println(rs.getObject(1) + "\t" + rs.getObject(2) + "\t" + rs.getObject(3) + "\t" + rs.getObject(4));
            }
        } catch (SQLException ex) {
            System.out.println(ex.toString());
        } finally {
            JdbcUtils.free(conn, ps, rs);
        }
    }