JDBC——批处理和防止SQL注入问题

  • 时间:
  • 来源:互联网
  • 文章标签:

1.批处理

(1)批处理的概念

所谓的批处理指的是一次性向数据库之中发出多条操作命令一起执行。 需要向数据库发送多条sql语句时, 为了提升执行效率, 可以采用JDBC的批处理机制.

(2)批处理的方法

  • addBatch(String sql) :Statement类的方法, 调用该方法可以将sql语句添加到Statement对象的命令列表中。执行批处理时将一次性的把这些sql语句发送给数据库进行处理
  • addBatch(): PreparedStatement类的方法, 调用该方法可以将预编译的sql语句添加到PreparedStatement对象的命令列表中。执行批处理时将一次性的把这些sql语句发送给数据库进行处理
  • executeBatch():把Statement对象或PreparedStatement对象命令列表中的所有sql语句发送给数据库进行处理.
  • clearBatch(): 清空当前sql命令列表.

(3)批处理的实际操作

public class BatchTest {
	@Test
	public void statementBatch() {
		Connection conn = null;
		Statement st = null;
		String sql_1 = "insert into test(name, age) values('miao', 24)";
		String sql_2 = "insert into test(name, age) values('xie', 22)";
		String sql_3 = "insert into test(name, age) values('wang', 21)";
		String sql_4 = "update test set name='java' where id=1";
 
		try {
			//工具包来连接数据库
			conn = JdbcUtils.getConnection();
			st = conn.createStatement();
			st.addBatch(sql_1);
			st.addBatch(sql_2);
			st.addBatch(sql_3);
			st.addBatch(sql_4);
			//执行所有的sql语句
			st.executeBatch();
			//清空sql命令列表
			st.clearBatch();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			JdbcUtils.release(null, st, conn);
		}
	}
 
	@Test
	public void preparedStatementBatch() {
		Connection conn = null;
		PreparedStatement st = null;
		String sql = "insert into test(name, age) values(?, ?)";
 
		try {
			conn = JdbcUtils.getConnection();
			//通过只打开一个连接
			st = conn.prepareStatement(sql);
			for (int i = 0; i < 10002; i++) {
				st.setString(1, "student_" + i);
				st.setInt(2, i);
				st.addBatch();
				// 需要防止Preparedstatement对象中的命令列表包含过多的待处理sql语句
				// 而造成outOfMemory错误
				if (i % 500 == 0) {
					st.executeBatch();
					st.clearBatch();
				}
			}
			// 将剩下的未处理命令发送给数据库
			st.executeBatch();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			//关闭连接,释放资源
			//resultSet.close();
        	//statement.close();
        	//connection.close();
			JdbcUtils.release(null, st, conn);
		}
	}
}

注意 不要一次性向命令列表中添加数量过多的sql语句, 防止出现outOfMemory错误.

(4)总结

Statement.addBatch(String sql) 来实现批处理的话,可以批处理不同的sql语句, 但是这些sql语句没有进行预编译,执行效率不高。 且需要列出每一个sql语句。而PreparedStatement.addBatch() 只能应用在类型相同参数不同的sql语句中, 此种形式的批处理经常用于在同一个表中批量插入数据, 或批量更新表的数据.

2.防止SQL注入问题

(1)什么是SQL注入

指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

任何一个基于SQL语言的数据库都可能被攻击,很多开发人员在编写Web应用程序时未对从输入参数、Web表单、cookie等接受到的值进行规范性验证和检测,通常会出现SQL注入漏洞。

(2)怎么防止SQL注入

A.使用PreparedStatement来代替Statement来执行SQL语句

java防SQL注入,最简单的办法是杜绝SQL拼接。使用PreparedStatement来代替Statement来执行SQL语句,其后只是输入参数,SQL注入攻击手段将无效,这是因为PreparedStatement不允许在不同的插入时间改变查询的逻辑结构

B.采用正则表达式将包含有 单引号,分号和注释符号的语句给替换掉来防止SQL注入,

......
public static String TransactSQLInjection(String str){
	return str.replaceAll(".*([';]+|(--)+).*", " ");
}
userName=TransactSQLInjection(userName);
password=TransactSQLInjection(password);
String sql="select * from users where username='"+userName+"' and password='"+password+"' "
Statement sta = conn.createStatement();
ResultSet rs = sta.executeQuery(sql);
......

C.使用Hibernate框架的SQL注入防范

Hibernate是目前使用最多的ORM框架,在Java Web开发中,很多时候不直接使用JDBC,而使用Hibernate来提高开发效率。

(3)总结

如今在进行项目开发时已经很少使用原生的jdbc了,大多数都用功能强大的框架去完成,他们帮我们简化了很多操作,如获取数据库连接、封装结果集、SQL预编译(可以防止SQL注入)

本文链接http://www.taodudu.cc/news/show-1781930.html