PrepareStatement相对Statement的优势:
·消除SQL注入的安全漏洞
·Statement会是数据库频繁编译SQL,可能造成数据库缓冲区的溢出
·数据库和相关驱动都可以对PrepareStatement进行优化
JdbcUtils工具类:
/**
* 有关mysql数据库的工具类,单例模式SingleTon
*/
package mysql.base;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
*
* 2009-9-24 湖南大学 计算机与通信学院 计算机科学与技术专业
*
* @author 陈春晓
*
*/
public final class JdbcUtils {
private static String url = "jdbc:mysql://localhost:3306/test";
private static String username = "root";
private static String password = "xiaochun";
private static JdbcUtils instance = null;
private JdbcUtils() {
};
public static JdbcUtils getInstance() {
if (instance == null) {
synchronized (JdbcUtils.class) {
if (instance == null)
instance = new JdbcUtils();
}
}
return instance;
}
// 保证驱动只装载一次
static {
// 注册驱动,只需要一次
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 获取一个数据库连接
*
* @return Connection
* @exception SQLException
*/
public Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
/**
* 释放资源
*
* @param ResultSet
* rs
* @param Statement
* st
* @param Connection
* conn
*/
public void free(ResultSet rs, Statement st, Connection conn) {
try {
if (rs != null)
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (st != null)
st.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (conn != null)
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
测试代码:
/**
* 测试SQL注入问题,要处理这个漏洞,就需要用PreparedStatement类代替Statement
*/
package mysql.base;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
*
* 2009-9-24 湖南大学 计算机与通信学院 计算机科学与技术专业
*
* @author 陈春晓
*
*/
public class SQLInject {
/**
* @param args
* @throws SQLException
*/
public static void main(String[] args) throws SQLException {
// TODO Auto-generated method stub
read("xiali"); // 测试SQL inject安全漏洞
read1("xiali");
}
/**
* 读取数据库,使用PrepareStatement类可以消除sql注入漏洞
*
* @param name
* @throws SQLException
*/
public static void read(String name) throws SQLException {
// 有SQL inject安全漏洞
String sqlStr = "select id,name,birthday,money from user where name=?";
// System.out.println(sqlStr);
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 注册驱动,只需要一次
// Class.forName("com.mysql.jdbc.Driver");
// 建立连接
conn = JdbcUtils.getInstance().getConnection();
//long start =System.currentTimeMillis();
// 创建语句
ps = conn.prepareStatement(sqlStr);
// 添加参数
ps.setString(1, name);
// 执行语句
rs = ps.executeQuery();
// 处理结果
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("Statement:read() "+(end-start)+"ms");
} finally {
JdbcUtils.getInstance().free(rs, ps, conn);
}
}
/**
* 存在SQL 注入安全漏洞
*
* @param name
* @throws SQLException
*/
public static void read1(String name) throws SQLException {
// 有SQL inject安全漏洞
String sqlStr = "select id,name,birthday,money from user where name='" + name + "'";
// System.out.println(sqlStr);
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
// 注册驱动,只需要一次
// Class.forName("com.mysql.jdbc.Driver");
// 建立连接
conn = JdbcUtils.getInstance().getConnection();
//long start =System.currentTimeMillis();
// 创建语句
st = conn.createStatement();
// 执行语句
rs = st.executeQuery(sqlStr);
// 处理结果
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("Statement:read() "+(end-start)+"ms");
} finally {
JdbcUtils.getInstance().free(rs, st, conn);
}
}
}
分享到:
相关推荐
prepareStatement和Statement的区别 prepareStatement和Statement是 Java 中两个常用的数据库操作接口,它们都可以用来执行 SQL 语句,但是它们之间有着明显的区别。 首先,从创建时的区别开始,Statement 需要...
java数据库连接PrepareStatement
用JDBC实现Java与数据库的连接,该文件使用PrepareStatement实现。
PreparedStatement是预编译的,对于批量处理可以大大提高效率. 也叫JDBC存储过程,下面这篇文章主要给大家介绍了关于利用JDBC的PrepareStatement打印真实SQL的方法,需要的朋友可以参考借鉴,下面来一起看看吧。
数据库原理:为什么PrepareStatement性能更好更安全
In Oracle Metalink (Oracle's support site - Note ID 736273.1) I found that this is a bug in JDBC adapter (version 10.2.0.0.0 to 11.1.0.7.0) that when you call preparedStatement with more than 7 ...
该资源中包含 JDBC 连接 MySQL 完整代码、常规 select、update 语句完整代码,以及 JDBC 批量处理数据的几种不同方式完整代码,且附带 使用说明!
MySQL prepare语法: PREPARE statement_name FROM preparable_SQL_statement; /*定义*/ EXECUTE statement_name [USING @var_name [, @var_name] …]; /*执行预处理语句*/ {DEALLOCATE | DROP} PREPARE statement_...
MySQL官方将prepare、execute、deallocate统称为PREPARE STATEMENT,我习惯称其为【预处理语句】,其用法十分简单,下面话不多说,来一起看看详细的介绍吧。 示例代码 PREPARE stmt_name FROM preparable_stmt ...
JAVA连接FileMaker完整工程 包函FileMaker数据库Java连接驱动 修改工程中的FileMaker安装地址就 可以用JAVA操作FileMaker ... prepareStatement = con.prepareStatement(insertSQL); b = prepareStatement.execute();
Do you know how to prepare a cashflow statement?
android 多渠道打包,把渠道文件放入channel.txt 就行
经过了三天的时间,艾玛终于写完了。。。这次是做一个不使用框架,用最原始的方法实现了java-jsp的web应用,栗子呢包含增删改查、登陆登出、分页、事务处理和权限管理这几个web应用的基本要素,界面就做得很烂了,...
NULL 博文链接:https://beijingwo2008.iteye.com/blog/1851542
cash flow statement,主要是会计的现金流报表的准备
PrepareStatement: conn.prepareStatement(String sql); CallableStatement: conn.prepareCall(String sql); 4)执行sql语句 stmt.execute(sql); stmt.executeUpdate(sql); stmt.executeQuery(sql); pstmt.execute*...
详细的接收了Statement与PrepareStatement的区别
PreparedStatement ps=conn.prepareStatement("select * from Contact"); ResultSet rs=ps.executeQuery(); List<Contact> list = new ArrayList(); while(rs.next()){ int id = rs.getInt("id")...
一次只从数据库中查询最大maxCount条记录 ... PreparedStatement pstat = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); //最大查询到第几条记录.........
Java代码在执行conn.createStatement()和conn.prepareStatement()的时候,实际上都是相当与在数据库中打开了一个cursor。尤其是,假如你的createStatement和prepareStatement是在一个循环里面的话,就会非常轻易出现...