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);
}
} }

20160408javaweb之JDBC ---PreparedStatement的更多相关文章

  1. Type mismatch: cannot convert from java.sql.PreparedStatement to com.mysql.jdbc.PreparedStatement

    Connection.prepareStatement()函数出错,提示: Type mismatch: cannot convert from java.sql.PreparedStatement ...

  2. 关于Mysql数据库longblob格式数据的插入com.mysql.jdbc.PreparedStatement.setBinaryStream(ILjava/io/InputStream;J)V问题分析

    当数据库字段为blob类型时 ,我们如果使用PreparedStatement中的setBinaryStream(int,InputStream,int)方法需要注意 在向blob字段类型中插入数据时 ...

  3. mysql数据库插入数据获取自增主键的三种方式(jdbc PreparedStatement方式、mybatis useGeneratedKeys方式、mybatis selectKey方式)

    通常来说对于mysql数据库插入数据获取主键的方法是采用selectKey的方式,特别是当你持久层使用mybatis框架的时候. 本文除此之外介绍其它两种获取主键的方式. 为了方便描述我们先建一张my ...

  4. Method com/mysql/jdbc/PreparedStatement.isClosed()Z is abstract 报错解决

    java.lang.AbstractMethodError: Method com/mysql/jdbc/PreparedStatement.isClosed()Z is abstract ----- ...

  5. JDBC PreparedStatement Statement

    参考:预编译语句(Prepared Statements)介绍,以MySQL为例 1. 背景 本文重点讲述MySQL中的预编译语句并从MySQL的Connector/J源码出发讲述其在Java语言中相 ...

  6. JDBC/PreparedStatement

      JDBC是Java数据库连接技术的简称,提供连接各种常用数据库的能力     JDBC  AP 是Sun公司提供的I 内容:供程序员调用的接口,集成在Java.sql和javax.sql包中, 如 ...

  7. 关于JDBC PreparedStatement

    PreparedStatement的执行步骤: 1. 向数据库服务器发送SQL语句,数据库对SQL进行解析和优化(conn.preparedStatement(sql)) 2. 向数据库发送绑定的参数 ...

  8. JavaEE JDBC PreparedStatement

    PreparedStatement @author ixenos PreparedStatement工作原理 注意:虽然mysql不支持PreparedStatement优化,但依然有预编译的实现! ...

  9. JDBC——PreparedStatement执行SQL的对象

    Statement的子接口,预编译SQL,动态SQL 功能比爹强大 用来解决SQL注入的 预编译SQL:参数使用?作为占位符,执行SQL的时候给?赋上值就可以了 使用步骤: 1.导入驱动jar包 复制 ...

随机推荐

  1. Java Socket 异常 Connection reset

    最近使用Java做Socket客户端,与C的Socket服务端交互.遇到问题:现象是可以从服务端接受小数据,但是如果接受大数据,总是遇到Connection reset的异常:如果把服务端和客户端放到 ...

  2. spring(6)--注解式控制器

    6.1.注解式控制器简介 一.Spring2.5之前,我们都是通过实现Controller接口或其实现来定义我们的处理器类.已经@Deprecated.   二.Spring2.5引入注解式处理器支持 ...

  3. UVa 11752 - The Super Powers 数学

    请看这个说明http://blog.csdn.net/u014800748/article/details/45914353 #define _CRT_SECURE_NO_WARNINGS #incl ...

  4. 成功安装mysql(mysql-5.5.32-winx64.msi)后,为何服务管理器里找不到MYSQL服务名?

    解决方案: 1.打开cmd,切换到mysql的bin目录下 2. D:\Program Files\MySQL5.1\bin>mysqld.exe -install 成功后会出现:Service ...

  5. linux驱动程序之电源管理之linux的电源管理架构(3)

    设备电源管理 Copyright (c) 2010 Rafael J. Wysocki<rjw@sisk.pl>, Novell Inc. Copyright (c) 2010 Alan ...

  6. Java笔记(四)……常量与变量

    常量 常量表示不会改变的数值. Java中常量的分类: 整数常量:所有整数 小数常量:所有小数 布尔型常量:较为特有,只有两个数值,true false 字符常量:将一个数字字母或者符号用单引号(' ...

  7. 关于学习Scala语言的一些感悟

    进入话题! 我们知道哈,Spark源码采用Scala语言编写,那么阅读Spark源码之前,是否一定先学Scala呢? 我个人认为,不必,只要我们有一些java或c++编写语言的基础,就可以看Spaar ...

  8. 打开链接(C# / 默认浏览器)

    System.Diagnostics.Process.Start("http://www.baidu.com/");

  9. Altium Designer 多通道设计

    转chenzelin2009的csdn博客:http://blog.csdn.net/chenzelin2009/article/details/5751251# Altium Designer的多图 ...

  10. [Git]git常用命令总结

    git clone url 将远程库复制到本地 git status 查看本地库的状态 git add filename.filetype 将库中被修改的文件标记为添加状态 git diff 查看库中 ...