GVKun编程网logo

使用不同的SQL语句批处理PreparedStatement

14

在本文中,我们将带你了解使用不同的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

使用不同的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 注入

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 批处理

7_ PreparedStatement 批处理

高春辉、王春生、朱峰:关于开源创业的 15 件小事

 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语法

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

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的相关知识,请在本站搜索。

本文标签: