`

处理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.getName());
stmt.setInt(2, users.getAge());
stmt.setInt(3, users.getShape());
stmt.addBatch( );
}
int[ ] counts = stmt.executeBatch();

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



使用PreparedStatement减少开发时间

JDBC(Java Database Connectivity,java数据库连接)的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;


这允许JVM(JavaVirtual Machine,Java虚拟机)和驱动/数据库缓存语句和字符串并提高性能。

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 规范兼容的,它并不要求驱动提供可更新的结果集的支持。





• SQLServer和嵌入式SQL  07.10.03  from whli88 
• 一劳永逸的数据库编码解决方案  07.08.28  from fondofbeyond 
• sql server的数据库的jdbc驱动程序与数据库的连接  07.07.17  from N_once 
• SQL语句学习_雨情相乐  07.06.28  from oice 
• 使用SQL TRACE 实用工具和TKPROF  07.05.11  from dazheng 

分享到:
评论

相关推荐

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

    作为一个替代方案,可以试试使用Statement 的批量处理特性看看能否同时执行所有的SQL以提高速度。 存储过程的最简单的形式就是包含一系列SQL语句的过程,将这些语句放在一起便于在同一个地方管理也可以提高速度。...

    JDBC的批量处理语句

    JDBC批量处理问题~~提高更新处理速度~~

    论文研究-可重用Java数据库操作组件的设计和实现.pdf

    它封装了注册和载入JDBC驱动程序、建立数据库连接、运行Structured Query Language(SQL)语句及处理查询结果集、查询结果集的分页显示操作,简化了Java DataBase Connectivity(JDBC)代码的编写,通过编写SQL语句,...

    建立JSP操作以提高数据库访问的效率

    虽然呆板的一面仍然存在,然而无论它包含多少缺点,JSP能够为Web程序设计者提供很多东西,尤其是与数据库的输入和输出操作与数据的处理。通过JSP来进行数据库访问不需要太多的引导。问题是如何使开发者能够接受Web...

    网上体育商城的设计与实现毕业设计答辩PPT.pptx

    Hibernate框架的主要优点是:比起JDBC,Hibernate没有很多复杂的SQL语句需要书写。使用Hibernate框架,没有必要在JDBC中完成所有不必要的繁琐工作;域对象与关系数据库的高效映射。因此,没有必要集中精力管理数据库...

    支持多数据库的ORM框架ef-orm.zip

    但是这些SQL语句并不是直接传送给JDBC驱动的,而是 有着一个数据库方言层,经过方言层处理的SQL语句,就具备了在当前数据库上正确操作的能力。这相当于提供了一种能跨数据库操作的SQL语言。(E-SQL) E-SQL不但解决了...

    java面试题

    答:索引可以提高对数据库中数据的检索,缺点是减慢了数据录入速度,同时也增加了数据库的尺寸大小。 什么是事务?什么是事锁? 答:事务就是被绑定在一起,作为一个逻辑单元执行的SQL语句。如果任何一个操作失败,...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    为了增加系统的吞吐量,提高并发处理客户请求数量,系统采用了IBM服务器作为主机。在数据库处理方面,不需要在数据层借助存储过程及数据库服务器端函数封装过多的业务逻辑,因此数据库系统采用相对精巧的MySQL[6]。...

    java 面试题 总结

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    超级有影响力霸气的Java面试题大全文档

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    JAVA面试题最全集

    请用java写二叉树算法,实现添加数据形成二叉树功能,并以先序的方式打印出来. 43.请写一个java程序实现线程连接池功能? 44.给定一个C语言函数,要求实现在java类中进行调用。 45.如何获得数组的长度? 46....

    java面试800题

    Q0060 JDBC批量更新的作用和用法 "提高执行效率。减少执行时间。 Statement sm = cn.createStatement(); sm.addBatch(sql1); sm.addBatch(sql2); ... sm.executeBatch() 或者 PreparedStatement ps = ...

Global site tag (gtag.js) - Google Analytics