批处理JDBC语句以提高处理速度

2024-04-23 12:58

本文主要是介绍批处理JDBC语句以提高处理速度,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

批处理JDBC语句以提高处理速度

有的时候JDBC运行的不够理想,这就促使我们写一些与特定数据库相关的存储过程。作为一个替换方案,不妨试一下Statement的批处理特征,看看一次执行所有的SQL语句是否会带来速度的提升。
存储过程最简单的形式就是整个过程只包含一组SQL语句。将这些语句放到一起能容易管理也可以提高运行速度。Statement类具有包含一串SQL语句的能力,因此它允许所有的SQL语句在一个数据库会话中被执行,从而避免了向数据库进行一连串的执行调用。
使用批处理功能涉及到两个方法:
addBatch(String)方法
executeBatch方法

addBatch方法可以接受一段标准的SQL(如果你使用一个Statement)作为参数,也可以什么参数都不带(如果你使用一个PreparedStatement)。
executeBatch方法接着执行SQL语句,返回一个int型数组。这个数组包括每条语句影响到的行数。如果在一个批处理中使用是一个SELECT或者其它只返回结果的语句,那么将会产生一个SQLException异常。

下面是一个简单的java.sql.Statement的例子:

Statement stmt = conn.createStatement();
stmt.insert("DELETE FROM Users");
stmt.insert("INSERT INTO Users VALUES('rod', 37, 'circle')");
stmt.insert("INSERT INTO Users VALUES('jane', 33, 'triangle')");
stmt.insert("INSERT INTO Users VALUES('freddy', 29, 'square')");

int[] counts = stmt.executeBatch();

使用PreparedStatement会稍有不同。它只能处理一段SQL语句,但可以带很多参数。下面的是使用PreparedStatement重写的上面的例子:

      //注意我们并没有做任何删除动作

PreparedStatement stmt = conn.prepareStatement( _
"INSERT INTO Users VALUES(?,?,?)" );
User[ ] users = ...;
for(int i=0; i<users.length; i++)
{
stmt.setInt(1, users[i].getName());
stmt.setInt(2, users[i].getAge());
stmt.setInt(3, users[i].getShape());
stmt.addBatch( );
}
int[ ] counts = stmt.executeBatch();

这是处理那些不知道具体执行次数的SQL代码的一个好方法。没有批处理,如果要添加50个用户,其性能可能受到影响。如果谁写了一段添加10000个用户的脚本,其运行速度就难以忍受。增加批处理将有助于提升性能,在后一种情况里,甚至可以改善代码的可读性。

使用PreparedStatement减少开发时间

JDBC(Java Database Connectivityjava数据库连接)API中的主要的四个类之一的java.sql.Statement要求开发者付出大量的时间和精力。在使用Statement获取JDBC访问时所具有的一个共通的问题是输入适当格式的日期和时间戳:2002-02-05 20:56 或者 02/05/02 8:56 PM。通过使用java.sql.PreparedStatement,这个问题可以自动解决。一个PreparedStatement是从 java.sql.Connection对象和所提供的SQL字符串得到的,SQL字符串中包含问号(?),这些问号标明变量的位置,然后提供变量的值,最后执行语句,例如:
Stringsql = "SELECT * FROM People p WHERE p.id = ? AND p.name = ?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setInt(1,id);
ps.setString(2,name);
ResultSet rs = ps.execute();

使用PreparedStatement的另一个优点是字符串不是动态创建的。下面是一个动态创建字符串的例子:
Stringsql = "SELECT * FROM People p WHERE p.i = "+id;

这允许JVMJavaVirtual MachineJava虚拟机)和驱动/数据库缓存语句和字符串并提高性能。
PreparedStatement也提供数据库无关性。当显示声明的SQL越少,那么潜在的SQL语句的数据库依赖性就越小。
由于PreparedStatement具备很多优点,开发者可能通常都使用它,只有在完全是因为性能原因或者是在一行SQL语句中没有变量的时候才使用通常的Statement
发出查询和处理结果
在任何你想向数据库运行一个SQL语句的时候,你都需要一个Statement PreparedStatement 实例。一旦你拥有了一个Statement PreparedStatement,你就可以发出一个查询。这样将返回一个ResultSet 实例,在其内部包含整个结果。 Example 31-1 演示了这个过程。
Example 31-1. JDBC 里处理一个简单的查询
这个例子将发出一个简单的查询然后用一个 Statement打印出每行的第一个字段。
Statement st = db.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE columnfoo = 500");
while (rs.next()) {
       System.out.print("Column 1 returned ");
       System.out.println(rs.getString(1));
}
rs.close();
st.close();
这个例子将使用 PreparedStatement 发出和前面一样的查询,并且在查询中制作数值。
int foovalue = 500;
PreparedStatement st = db.prepareStatement("SELECT * FROM mytable WHERE columnfoo = ?");
st.setInt(1, foovalue);
ResultSet rs = st.executeQuery();
while (rs.next()) {
      System.out.print("Column 1 returned ");
      System.out.println(rs.getString(1));
}
rs.close();
st.close();
31.3.1. 使用 Statement PreparedStatement 接口
在使用Statement PreparedStatement接口时必须考虑下面的问题:
你可以将一个Statement PreparedStatement实例使用任意次。你可以在打开一个联接后马上创建一个Statement 实例,并且在联接的生存期里使用之。你必须记住每个Statement PreparedStatement只能存在一个 ResultSet
如果你需要在处理一个ResultSet的时候执行一个查询,你只需要创建并且使用另外一个Statement
如果你使用了 threads (线程),并且有几个使用数据库,你对每个线程必须使用一个独立的Statement。如果考虑使用线程,请参考本文档稍后的 Section 31.8 章节,因为这些内容包含一些重要的信息。
在你用完 Statement 或者 PreparedStatement 之后,你应该关闭它。
31.3.2. 使用ResultSet(结果集)接口
使用ResultSet接口时必须考虑下面的问题:
在读取任何数值的时候,你必须调用next()。如果还有结果则返回真(true),但更重要的是,它为处理准备了数据行。
JDBC 规范里,你对一个字段应该只访问一次。遵循这个规则是最安全的,不过目前 PostgreSQL 驱动将允许你对一个字段访问任意次。
一旦你结束对一个 ResultSet 的处理,你必须对之调用 close()来关闭它。
一旦你使用那个创建ResultSet Statement做另一个查询请求,当前打开的 ResultSet 实例将自动关闭。
目前的 ResultSet 是只读的。你不能通过 ResultSet 来更新数据。如果你想更新数据,那么你就需要使用普通的方法来做∶通过发出一条 SQL 更新语句。这么做是和 JDBC 规范兼容的,它并不要求驱动提供可更新的结果集的支持。

这篇关于批处理JDBC语句以提高处理速度的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/928857

相关文章

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

MySQL 中的 LIMIT 语句及基本用法

《MySQL中的LIMIT语句及基本用法》LIMIT语句用于限制查询返回的行数,常用于分页查询或取部分数据,提高查询效率,:本文主要介绍MySQL中的LIMIT语句,需要的朋友可以参考下... 目录mysql 中的 LIMIT 语句1. LIMIT 语法2. LIMIT 基本用法(1) 获取前 N 行数据(

MySQL中动态生成SQL语句去掉所有字段的空格的操作方法

《MySQL中动态生成SQL语句去掉所有字段的空格的操作方法》在数据库管理过程中,我们常常会遇到需要对表中字段进行清洗和整理的情况,本文将详细介绍如何在MySQL中动态生成SQL语句来去掉所有字段的空... 目录在mysql中动态生成SQL语句去掉所有字段的空格准备工作原理分析动态生成SQL语句在MySQL

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

mysql的基础语句和外键查询及其语句详解(推荐)

《mysql的基础语句和外键查询及其语句详解(推荐)》:本文主要介绍mysql的基础语句和外键查询及其语句详解(推荐),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋... 目录一、mysql 基础语句1. 数据库操作 创建数据库2. 表操作 创建表3. CRUD 操作二、外键

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

python之流程控制语句match-case详解

《python之流程控制语句match-case详解》:本文主要介绍python之流程控制语句match-case使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录match-case 语法详解与实战一、基础值匹配(类似 switch-case)二、数据结构解构匹

grom设置全局日志实现执行并打印sql语句

《grom设置全局日志实现执行并打印sql语句》本文主要介绍了grom设置全局日志实现执行并打印sql语句,包括设置日志级别、实现自定义Logger接口以及如何使用GORM的默认logger,通过这些... 目录gorm中的自定义日志gorm中日志的其他操作日志级别Debug自定义 Loggergorm中的

在MySQL执行UPDATE语句时遇到的错误1175的解决方案

《在MySQL执行UPDATE语句时遇到的错误1175的解决方案》MySQL安全更新模式(SafeUpdateMode)限制了UPDATE和DELETE操作,要求使用WHERE子句时必须基于主键或索引... mysql 中遇到的 Error Code: 1175 是由于启用了 安全更新模式(Safe Upd

如何提高Redis服务器的最大打开文件数限制

《如何提高Redis服务器的最大打开文件数限制》文章讨论了如何提高Redis服务器的最大打开文件数限制,以支持高并发服务,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录如何提高Redis服务器的最大打开文件数限制问题诊断解决步骤1. 修改系统级别的限制2. 为Redis进程特别设置限制