在本文中,我们将带你了解使用不同的SQL语句批处理PreparedStatement在这篇文章中,同时我们还将给您一些技巧,以帮助您实现更有效的5.用preparedStatement防止SQL注入、
在本文中,我们将带你了解使用不同的SQL语句批处理PreparedStatement在这篇文章中,同时我们还将给您一些技巧,以帮助您实现更有效的5. 用 preparedStatement 防止 SQL 注入、7_ PreparedStatement 批处理、Java PreparedStatement抱怨execute()上的SQL语法、java sql sqlexception prepared statement needs to be re prepared。
本文目录一览:- 使用不同的SQL语句批处理PreparedStatement
- 5. 用 preparedStatement 防止 SQL 注入
- 7_ PreparedStatement 批处理
- Java PreparedStatement抱怨execute()上的SQL语法
- java sql sqlexception prepared statement needs to be re prepared
使用不同的SQL语句批处理PreparedStatement
我想知道Java是否有可能
String A = "UPDATE blah set x=? y=? z=?"
String B = "UPDATE blah set a=? b=? c=? d=?"
我想有一个准备好的声明,主要是为了提高速度,其次是为了提高安全性。我希望能够填写A的绑定变量,执行A,B的绑定变量并执行B,然后提交整个事务。有没有更好的方法可以做到这一点?
5. 用 preparedStatement 防止 SQL 注入
1. 用 Statement 会被 SQL 注入,因为 Statement 的 sql 语句是拼写的,所以在执行的时候传入的值会对 sql 语句造成很严重的影响,改变原本 sql 的执行条件
/**
* SQL 注入.
*/
@Test
public void testSQLInjection() {
String username = "a'' OR PASSWORD = ";
String password = " OR ''1''=''1";
String sql = "SELECT * FROM users WHERE username = ''" + username
+ "'' AND " + "password = ''" + password + "''";
System.out.println(sql);
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
connection = JDBCTools.getConnection();
statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
if (resultSet.next()) {
System.out.println("登录成功!");
} else {
System.out.println("用户名和密码不匹配或用户名不存在. ");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.releaseDB(resultSet, statement, connection);
}
}
2. 使用 PreparedStatement 将有效的解决 SQL 注入问题。因为 sql 语句是预编译的,有固定的格式,不会改变原有执行条件
/**
* 使用 PreparedStatement 将有效的解决 SQL 注入问题.
*/
@Test
public void testSQLInjection2() {
String username = "a'' OR PASSWORD = ";
String password = " OR ''1''=''1";
String sql = "SELECT * FROM users WHERE username = ? "
+ "AND password = ?";
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = JDBCTools.getConnection();
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, username);
preparedStatement.setString(2, password);
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
System.out.println("登录成功!");
} else {
System.out.println("用户名和密码不匹配或用户名不存在. ");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.releaseDB(resultSet, preparedStatement, connection);
}
}
7_ PreparedStatement 批处理

PreparedStatement 批处理
什么是批处理?
当我们有多条 sql 语句需要发送到数据库执行的时候,有两种发送方式,一种是执行一条发送一条 sql 语句给数据库,另一个种是发送一个 sql 集合给数据库,也就是发送一个批 sql 到数据库。普通的执行过程是:每处理一条数据,就访问一次数据库;而批处理是:累积到一定数量,再一次性提交到数据库,减少了与数据库的交互次数,所以效率会大大提高,很显然两者的数据库执行效率是不同的,我们发送批处理 sql 的时候数据库执行效率要高
statement 语句对象实现批处理有如下问题
缺点:采用硬编码效率低,安全性较差。
原理:硬编码,每次执行时相似 SQL 都会进行编译
PreparedStatement + 批处理
优点:语句只编译一次,减少编译次数。提高了安全性(阻止了 SQL 注入)
原理:相似 SQL 只编译一次,减少编译次数
注意: 需要设置批处理开启 & rewriteBatchedStatements=true
package com.msb.test4;
import java.sql.*;
/**
* @Author: Ma HaiYang
* @Description: MircoMessage:Mark_7001
*/
public class TestBatch {
private static String driver ="com.mysql.cj.jdbc.Driver";
private static String url="jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useServerPrepStmts=true&cachePrepStmts=true&&rewriteBatchedStatements=true";
private static String user="root";
private static String password="root";
public static void main(String[] args) {
testAddBatch();
}
// 定义一个方法,向部门表增加1000条数据
public static void testAddBatch(){
Connection connection = null;
PreparedStatement preparedStatement=null;
try{
Class.forName(driver);
connection = DriverManager.getConnection(url, user,password);
String sql="insert into dept values (DEFAULT ,?,?)";
preparedStatement = connection.prepareStatement(sql);//这里已经传入SQL语句
//设置参数
for (int i = 1; i <= 10663; i++) {
preparedStatement.setString(1, "name");
preparedStatement.setString(2, "loc");
preparedStatement.addBatch();// 将修改放入一个批次中
if(i%1000==0){
preparedStatement.executeBatch();
preparedStatement.clearBatch();// 清除批处理中的数据
}
}
/*
* 整数数组中的元素代表执行的结果代号
* SUCCESS_NO_INFO -2
* EXECUTE_FAILED -3
* */
/*int[] ints = */
preparedStatement.executeBatch();
preparedStatement.clearBatch();
}catch (Exception e){
e.printStackTrace();
}finally {
if(null != preparedStatement){
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(null != connection){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
Java PreparedStatement抱怨execute()上的SQL语法
这真让我发疯……我在这里做错了什么?
ArrayList<String> toAdd = new ArrayList<String>();toAdd.add("password");try{ PreparedStatement pStmt = conn.prepareStatement("ALTER TABLE testTable ADD ? varchar(100)"); for (String s : toAdd) { pStmt.setString(1, s); pStmt.execute(); }} catch (SQLException e) { e.printStackTrace();}
结果是…
02:59:12,885错误[STDERR]
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:您的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册以获取正确的语法,以在第1行的“
password” varchar(100)”附近使用
但…
ArrayList<String> toAdd = new ArrayList<String>();toAdd.add("password");try{ Statement stmt = conn.prepareStatement(); for (String s : toAdd) { stmt.execute("ALTER TABLE testTable ADD "+s+" varchar(100)"); }} catch (SQLException e) { e.printStackTrace();}
完美运行…直接在MySQL命令行客户端直接输入文本也是如此。
mysql> alter table testTable add stringGoesHere varchar(100);Query OK, 1 row affected (0.23 sec)Records: 1 Duplicates: 0 Warnings: 0
我究竟做错了什么?
答案1
小编典典在MySQL手册明确表示,?
(参数标记)是唯一,不列名绑定的数据值。
参数标记只能用于应显示数据值的地方,而不能用于SQL关键字,标识符等。
因此,您将不得不使用第二种方法。
java sql sqlexception prepared statement needs to be re prepared
java sql sqlexception prepared statement needs to be re prepared
遇到上边的异常。已经搜遍了,没有找到解决方案。
求助各位
今天关于使用不同的SQL语句批处理PreparedStatement的讲解已经结束,谢谢您的阅读,如果想了解更多关于5. 用 preparedStatement 防止 SQL 注入、7_ PreparedStatement 批处理、Java PreparedStatement抱怨execute()上的SQL语法、java sql sqlexception prepared statement needs to be re prepared的相关知识,请在本站搜索。
本文标签: