Java 报表和准备报表之间的差异

Java 报表和准备报表之间的差异,java,jdbc,Java,Jdbc,准备好的语句是语句的一个稍微更强大的版本,并且应该始终至少与语句一样快速和易于处理。 准备好的语句可以参数化 大多数关系数据库通过四个步骤处理JDBC/SQL查询: 解析传入的SQL查询 编译SQL查询 规划/优化数据采集路径 执行优化的查询/获取和返回数据 对于发送到数据库的每个SQL查询,语句将始终执行上述四个步骤。准备好的语句预执行上述执行过程中的步骤(1)-(3)。因此,在创建准备好的语句时,会立即执行一些预优化。其效果是在执行时减轻数据库引擎的负载 现在我的问题是,“使用Prepare

准备好的语句是语句的一个稍微更强大的版本,并且应该始终至少与语句一样快速和易于处理。
准备好的语句可以参数化

大多数关系数据库通过四个步骤处理JDBC/SQL查询:

  • 解析传入的SQL查询
  • 编译SQL查询
  • 规划/优化数据采集路径
  • 执行优化的查询/获取和返回数据
  • 对于发送到数据库的每个SQL查询,语句将始终执行上述四个步骤。准备好的语句预执行上述执行过程中的步骤(1)-(3)。因此,在创建准备好的语句时,会立即执行一些预优化。其效果是在执行时减轻数据库引擎的负载


    现在我的问题是,“使用PreparedStatement还有其他好处吗?”

    PreparedStatement
    是一种很好的防御方法(但不是万无一失的)。绑定参数值是防止进行不必要访问的一种好方法。

    没什么可添加的

    1-如果您想在循环中执行查询(超过1次),由于您提到的优化,prepared语句可以更快

    参数化查询是避免SQL注入的好方法。参数化查询仅在PreparedStatement中可用。

    的优点:

    • SQL语句的预编译和DB端缓存导致总体执行速度更快,并且能够在中重用相同的SQL语句

    • 通过引号和其他特殊字符的内置转义自动防止错误。请注意,这需要使用任何
      PreparedStatement
      setXxx()
      方法来设置值

      preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email, birthdate, photo) VALUES (?, ?, ?, ?)");
      preparedStatement.setString(1, person.getName());
      preparedStatement.setString(2, person.getEmail());
      preparedStatement.setTimestamp(3, new Timestamp(person.getBirthdate().getTime()));
      preparedStatement.setBinaryStream(4, person.getPhoto());
      preparedStatement.executeUpdate();
      
      因此,逐个串接SQL字符串中的值

      preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email) VALUES ('" + person.getName() + "', '" + person.getEmail() + "'");
      preparedStatement.executeUpdate();
      
    • 简化了SQL字符串中非标准Java对象的设置,例如,()和()。在大多数类型上,您不能像在简单的
      语句中那样“仅仅”执行
      toString()
      。您甚至可以将其重构为在循环内使用,如下面的实用程序方法所示:

      public static void setValues(PreparedStatement preparedStatement, Object... values) throws SQLException {
          for (int i = 0; i < values.length; i++) {
              preparedStatement.setObject(i + 1, values[i]);
          }
      }
      

      • 不能在声明中使用CLOB

        和:(OraclePreparedStatement)ps

        • 它更容易阅读
        • 您可以轻松地将查询字符串设置为常量

        预处理语句忽略sql注入,因此预处理语句中的安全性得到提高

        语句
        接口执行无参数的静态sql语句


        PreparedStatement
        接口(扩展语句)执行带/不带参数的预编译SQL语句

      • 对重复处决有效

      • 它是预编译的,因此速度更快

      • 它们是预编译的(一次),因此对于重复执行动态SQL(参数发生变化时)来说速度更快

      • 数据库语句缓存提高数据库执行性能

        数据库为以前执行的语句存储执行计划的缓存。这使得数据库引擎可以重用以前执行过的语句的计划。因为PreparedStatement使用参数,所以每次执行时都显示为相同的SQL,数据库可以重用以前的访问计划,从而减少处理。语句将参数“内联”到SQL字符串中,因此在DB中不会显示为相同的SQL,从而阻止缓存的使用

      • 二进制通信协议意味着更少的带宽和更快的对DB服务器的通信调用

        准备好的语句通常通过非SQL二进制协议执行。这意味着数据包中的数据更少,因此与服务器的通信速度更快。根据经验,网络操作比磁盘操作慢一个数量级,磁盘操作比内存CPU操作慢一个数量级。因此,通过网络发送的数据量的任何减少都将对整体性能产生良好的影响

      • 它们通过为提供的所有参数值转义文本来防止SQL注入

      • 它们在查询代码和参数值之间提供了更强的分离(与连接的SQL字符串相比),提高了可读性,并帮助代码维护人员快速理解查询的输入和输出

      • 在java中,可以调用getMetadata()和getParameterMetadata()分别反映结果集字段和参数字段

      • 在java中,通过setObject、setBoolean、setByte、setDate、setDouble、setDouble、setFloat、setInt、setLong、setShort、setTime、setTimestamp智能地接受java对象作为参数类型-它转换为数据库可理解的JDBC类型格式(不仅仅是toString()格式)

      • 在java中,通过setArray方法接受SQL数组作为参数类型

      • 在java中,分别通过setClob/setNClob、setBlob、setBinaryStream、setCharacterStream/setascistream/setNCharacterStream方法接受clob、blob、OutputStreams和reader作为参数“feed”

      • 在java中,允许通过setURL、setRowId、setQLXML和setNull方法为SQL数据链接、SQL ROWID、SQL XML和NULL设置特定于数据库的值

      • 在java中,从语句继承所有方法。它继承了addBatch方法,并且还允许添加一组参数值,以通过addBatch方法匹配批处理SQL命令集

      • 在java中,一种特殊类型的PreparedStatement(CallableStatement子类)允许执行存储过程—支持高性能、封装、过程编程和SQL、DB管理/维护/调整逻辑以及使用专有的DB逻辑和功能


      • 语句将用于执行静态SQL语句,它不能接受inpu
        preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email, birthdate, photo) VALUES (?, ?, ?, ?)");
        setValues(preparedStatement, person.getName(), person.getEmail(), new Timestamp(person.getBirthdate().getTime()), person.getPhoto());
        preparedStatement.executeUpdate();