20160408javaweb之JDBC ---PreparedStatement
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); } } }