JDBC性能技巧

合集下载

JDBC批处理与性能

JDBC批处理与性能

使用JDBC进行批处理•java•数据库l业务场景:当需要向数据库发送一批SQL语句执行时,应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率。

l实现批处理有两种方式,第一种方式:•Statement.addBatch(sql)l执行批处理SQL语句•executeBatch()方法:执行批处理命令•clearBatch()方法:清除批处理命令Connection conn = null;Statement st = null;ResultSet rs = null;try {conn = JdbcUtil.getConnection();String sql1 = "insert into user(name,password,email,birthday)values('kkk','123','abc@','1978-08-08')";String sql2 = "update user set password='123456' where id=3";st = conn.createStatement();st.addBatch(sql1); //把SQL语句加入到批命令中st.addBatch(sql2); //把SQL语句加入到批命令中st.executeBatch();} finally{JdbcUtil.free(conn, st, rs);}l采用Statement.addBatch(sql)方式实现批处理:•优点:可以向数据库发送多条不同的SQL语句。

•缺点:•SQL语句没有预编译。

•当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句。

例如: Insert into user(name,password) values(‘aa’,’111’); Insert into user(name,password) values(‘bb’,’222’);Insert into user(name,password) values(‘cc’,’333’);Insert into user(name,password) values(‘dd’,’444’);l实现批处理的第二种方式:•PreparedStatement.addBatch()conn = JdbcUtil.getConnection(); String sql = "insert into user(name,password,email,birthday) values(?,?,?,?)";st = conn.prepareStatement(sql);for(int i=0;i<50000;i++){st.setString(1, "aaa" + i);st.setString(2, "123" + i);st.setString(3, "aaa" + i + "@");st.setDate(4,new Date(1980, 10, 10));st.addBatch();if(i%1000==0){st.executeBatch();st.clearBatch();}}st.executeBatch();l采用PreparedStatement.addBatch()实现批处理•优点:发送的是预编译后的SQL语句,执行效率高。

JDBC技术和数据库连接池专题(转载)

JDBC技术和数据库连接池专题(转载)

JDBC基础知识一、采用JDBC访问数据库的基本步骤:A.载入JDBC驱动程序B.定义连接URLC.建立连接D.创建Statement对象E.执行查询或更新F.结果处理G.关闭连接二、载入JDBC驱动程序:1.为了使代码尽可能地灵活,我们要避免对类名的引用进行硬编码(hard-coding),因此我们可以采用从Properties文件中载入驱动程序的方法,也可以使用在服务器中配置数据源(DataSource)的方法来避免在代码中硬编码2.在开发过程中要保证CLASSPATH设定中包括驱动程序JAR文件所在的路径。

在WEB 服务器上部署时要将JAR文件放在Web应用的WEB-INF/lib目录下。

如果多个Web应用使用相同的数据库驱动程序可以将JAR文件放置在服务器使用的公共目录<%CATALINA_HOME%>\common\lib中三、定义连接URL:载入JDBC驱动程序之后,必须指定数据库服务器位置。

指向数据库的URL所使用的协议是:jdbc:子协议,并且载入服务器的主机名、端口、数据库名(或引用)。

如:Oracle 的连接URL:jdbc:oracle:thin:@192.168.0.71:1521:UMV2jdbc:oracle:采用Oracle驱动程序thin:指连接服务器所采用的模式@192.168.0.71:服务器的地址1521:服务器的监听端口UMV2:数据库名四、建立连接:1.一个数据库连接(Connection)可以通过其自身的getMetaData()来获取它的自身信息2.默认情况下一个数据库的连接是自动提交模式的(auto-commit),也就是说每当一个SQL语句被执行后其改变结果都会被自动提交,如果auto-commit模式被关闭,那么方法commit()必须被显式调用以提交改变结果,否则的话所有对数据库操作的结果都不会被保存五、创建Statement对象:在同一时间下,每个Statement对象只能打开一个ResultSet对象。

JDBC中日期时间的处理技巧

JDBC中日期时间的处理技巧

JDBC中日期时间的处理技巧在JDBC中处理日期时间是非常常见的需求,因为数据库中的许多数据都与日期和时间有关。

以下是一些处理日期时间字段的技巧:1. 日期时间的存储格式:在数据库中日期时间字段通常使用DATE、TIME、TIMESTAMP类型来存储。

在Java中,日期时间可以使用java.sql.Date、java.sql.Time、java.sql.Timestamp类分别表示。

通常数据库中使用TIMESTAMP类型来存储日期时间,因为它包含日期和时间信息。

2. 获取当前日期时间:可以使用new Date(来获取当前日期时间,new Date(会返回系统当前的日期时间。

如果只需要日期可以使用java.sql.Date currentDate = new Date(System.currentTimeMillis(),如果只需要时间可以使用java.sql.Time currentTime = newTime(System.currentTimeMillis()。

3. 将日期时间转换为字符串:在Java中可以使用SimpleDateFormat类将日期时间转换为字符串。

例如,可以使用以下代码将日期时间格式化为"yyyy-MM-dd HH:mm:ss"的字符串:```javaSimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-ddHH:mm:ss");String formattedDate = sdf.format(new Date();``````javaSimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Date date = sdf.parse("2024-01-01");```5. 插入和查询日期时间字段:在JDBC中插入和查询日期时间字段时需要使用PreparedStatement,并通过setDate(、setTime(、setTimestamp(方法将Date对象传入。

Java数据库连接:JDBC的基本使用与优化技巧

Java数据库连接:JDBC的基本使用与优化技巧

Java数据库连接:JDBC的基本使用与优化技巧引言:在当今信息化时代,数据库的应用已经无处不在。

而作为Java开发者,我们经常需要与数据库进行交互,以实现数据的存储、检索和处理。

Java数据库连接(JDBC)是一种用于在Java应用程序和数据库之间建立连接的API。

本文将介绍JDBC的基本使用和一些优化技巧,以帮助读者更好地理解和应用JDBC。

一、JDBC的基本使用1. 导入JDBC相关的包在使用JDBC之前,我们首先需要导入相关的包。

在Java中,JDBC相关的类和接口位于java.sql和javax.sql包中。

我们可以通过以下语句导入这些包:import java.sql.*;import javax.sql.*;2. 加载数据库驱动程序在使用JDBC之前,我们需要加载数据库驱动程序。

不同的数据库有不同的驱动程序,我们需要根据使用的数据库选择合适的驱动程序。

例如,如果我们使用的是MySQL数据库,可以通过以下语句加载MySQL的驱动程序:Class.forName("com.mysql.jdbc.Driver");3. 建立数据库连接加载驱动程序后,我们可以通过以下语句建立与数据库的连接:Connection connection = DriverManager.getConnection(url, username, password);其中,url是数据库的URL,username是用户名,password是密码。

连接成功后,我们可以通过Connection对象执行SQL语句。

4. 执行SQL语句在JDBC中,我们可以通过Statement对象执行SQL语句。

例如,我们可以通过以下语句执行一个查询语句:Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery("SELECT * FROM table_name");其中,table_name是要查询的表的名称。

jdbc防止sql注入的方法

jdbc防止sql注入的方法

jdbc防止sql注入的方法
JDBC是Java编程语言的一种应用程序接口,用于访问各种数据库。

在使用JDBC时,我们需要注意防止SQL注入攻击。

SQL注入攻
击是一种常见的安全问题,它利用不安全的输入校验机制,将恶意SQL代码注入到应用程序中,从而破坏数据库的完整性和机密性。

以下是一些防止SQL注入攻击的方法:
1. 使用预编译语句:预编译语句是一种预处理SQL语句的方法,它可以将SQL语句编译成可执行的二进制码,并在执行时提供参数。

预编译语句可以防止SQL注入攻击,因为它会将用户输入的参数转义,并在执行之前进行检查。

2. 使用参数化查询:参数化查询是一种将SQL语句和参数分离
的方法,它可以避免用户输入的值被当作代码执行。

参数化查询可以防止SQL注入攻击,因为它会对输入的参数进行验证和转义,并将它们作为参数传递给SQL语句。

3. 过滤用户输入:输入过滤是一种验证用户输入的方法,它可
以检查输入是否符合预期格式,并将输入中的特殊字符转义。

输入过滤可以防止SQL注入攻击,因为它可以检测和删除任何尝试注入恶意代码的特殊字符。

4. 使用安全的编程技巧:编写安全的代码是防止SQL注入攻击
的关键,例如在开发过程中使用变量而不是拼接字符串、不从用户输入中构建SQL查询等。

总之,防止SQL注入攻击是JDBC编程中的一个重要问题,需要
开发人员采取各种方法来保护应用程序和数据库的安全。

JDBC连接Oracle数据库之十大技巧

JDBC连接Oracle数据库之十大技巧

JDBC连接Oracle数据库之十大技巧JDBC连接Oracle数据库之十大技巧JDBC连接Oracle数据库之十大技巧java数据库连接(jdbc)api是一系列能够让java编程人员访问数据库的接口,各个开发商的接口并不完全相同。

在使用多年的oracle公司的jdbc后,我积累了许多技巧,这些技巧能够使我们更好地发挥系统的性能和实现更多的功能。

1、在客户端软件开发中使用thin驱动程序在开发java软件方面,oracle的数据库提供了四种类型的驱动程序,二种用于应用软件、applets、servlets等客户端软件,另外二种用于数据库中的java存储过程等服务器端软件。

在客户机端软件的开发中,我们可以选择oci驱动程序或thin驱动程序。

oci驱动程序利用java本地化接口(jni),通过oracle客户端软件与数据库进行通讯。

thin驱动程序是纯java驱动程序,它直接与数据库进行通讯。

为了获得最高的性能,oracle建议在客户端软件的开发中使用oci驱动程序,这似乎是正确的。

但我建议使用thin驱动程序,因为通过多次测试发现,在通常情况下,thin驱动程序的性能都超过了oci驱动程序。

2、关闭自动提交功能,提高系统性能在第一次建立与数据库的连接时,在缺省情况下,连接是在自动提交模式下的。

为了获得更好的性能,可以通过调用带布尔值false参数的connection类的setautocommit()方法关闭自动提交功能,如下所示:conn.setautocommit(false);值得注意的是,一旦关闭了自动提交功能,我们就需要通过调用connection类的commit()和rollback()方法来人工的方式对事务进行管理。

3、在动态sql或有时间限制的命令中使用statement对象在执行sql命令时,我们有二种选择:可以使用preparedstatement对象,也可以使用statement对象。

jdbc setparameter替换参数

jdbc setparameter替换参数

JDBC(Java Database Connectivity)是Java语言访问数据库的标准接口。

在使用JDBC操作数据库时,经常需要向SQL语句中传入参数,而JDBC提供了多种方式来动态设置参数,其中最常用的方式就是使用PreparedStatement的setXXX()方法来替换参数。

1. PreparedStatement简介PreparedStatement是JDBC中的一个重要接口,它继承自Statement接口,用于执行带有参数的SQL语句。

与Statement相比,PreparedStatement的主要优点在于它可以有效地防止SQL注入攻击,并且可以通过setXXX()方法来动态设置参数,提高了SQL语句的可读性和安全性。

2. setXXX()方法PreparedStatement接口中定义了一系列的setXXX()方法,用于设置不同类型的参数。

setInt(int parameterIndex, int x)用于设置整型参数,setString(int parameterIndex, String x)用于设置字符串参数,以此类推。

3. 替换参数的步骤动态设置参数的一般步骤如下:- 构造SQL语句,使用问号(?)作为占位符表示参数位置。

- 调用Connection的prepareStatement()方法创建PreparedStatement对象。

- 调用PreparedStatement的setXXX()方法设置参数。

- 调用PreparedStatement的executeXXX()方法执行SQL语句。

4. 示例代码下面是一个简单的示例代码,演示了如何使用PreparedStatement的setXXX()方法替换参数:```javaString sql = "SELECT * FROM user WHERE id = ?"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setInt(1, 1);ResultSet rs = pstmt.executeQuery();```在这个示例中,首先构造了一个带有参数的SQL语句,然后调用PreparedStatement的setInt()方法设置参数,最后执行SQL语句并获取结果集。

JDBC中日期时间的处理技巧

JDBC中日期时间的处理技巧
Java中用类java.util.Date对日期/时间做了封装,此类提供了对年、月、日、时、分、秒、毫秒以及时区的控制方法,同时也提供一些工具方法,比如日期/时间的比较,前后判断等。
java.util.Date中采用一个long型的数来保存日期/时间,它表示从格林威治时间1970年1月1日00点00分00秒至今的毫秒数。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = sdf.format(utilDate);
这样也可以达到最终目的,但是有点问题,java.sql.Timestamp是继承java.util.Date的,因此format的时候直接传入timeStamp即可,没有必要临时创建一个utilDate。像下面这样就可以了:
熟悉oracle的人都知道,TO_Date是oracle里的函数,其他数据库没有,即使有也很可能不一样。那么这段代码只能用在oracle上,如果换成其他数据库,程序就无法执行了。
如果采用PreparedStatement,代码是这样:
Connection conn;//前面的步骤略
PreparedStatement pstmt = conn.prepareStatement("insert into tab ( begin_date ) values( ?)");
pstmt.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt.execute();
可以看出来,这段代码与数据库无关,只要是支持标准sql的数据库都没有问题。

如何实现jdbc性能优化

如何实现jdbc性能优化

jdbc程序的性能主要由两个因素决定,一是数据库本身的性质,另一个是与数据库相对独立的jdbc应用程序接口(api)的使用.这里说的是如何正确使用jdbc编程接口,以获得更好的性能.jdbc主要优化有:1.选择正确的jdbc驱动程序2.Connention的优化使用连接池来管理Connection对象3.Statement的优化使用批量更新等4.Result的优化正确的从数据库中get数据等(1)选择正确的jdbc驱动程序:1 jdbc-odbc 桥2 本地api-部分 java驱动3 jdbc网路协议-纯java驱动4 jdbc本地协议最好选择 jdbc网路协议-纯java驱动效率比较高但需要第三方软件的支持比如corba weblogic属于这种类型(2)优化Connection对象:1.设置适当的参数 DriverManager.getConnection(String url,Properties props);例如: Properties props=new Properties();pro ps.put(“user”,”wuwei”);props.put(“password”,”wuwei”);props.put(“defaultRowPrefectch”,”30″);props.put(“dufaultBatchValue”,”5″);Connectioncon=DriverManager.getConnection(“/forum/images/smiles/icon_surprised.gif border=0>racle:thin:@hosts String”,props);对象可以通过设置setDefaultRowPrefetch(int) 和 setDefaultBatchValue(int) 两个参数类优化连接2.使用连接池可以自己写一个连接池这样程序的灵活性强,便于移植.apache项目开发了一套非常通用而表现非常稳定的对象池设计了自己的连接池后在客户端调用建立对象public Object makeObject() throws Exception{Class.forName(“oracle.jdbc.driver.OracalDriver”);return DriverManager.getConnection(“url”,”username”,”password”);}销毁对象时用public void destroyObject(Object obj) throws Exception{((Connection)obj.close());}注意几点对象池里有没有回收机制,对象池里有机有容量限制,对象池里有多少个闲置对象(可以释放)3.控制事务的提交最好手动提交事务,不但可以可以保证数据原子性,而且对新能提高留下余地.try{connection.setAutoCommint(false);// 代码用PreparedStatement 性能比Statementh好.mit();connection.setAutoCommit(true);}catch(SQLException e){}finally{//代码if(connection!=null){connection.close();}}4.适当的选择事务的隔离级别 TRANSACTION_READ_UNCOMMITED 性能最高TRANSACTION_READ_COMMITED 快TRANSACTION_REFEATABLE_READ 中等RANSACTION_SERIALIZABLE 慢(3)Statement 优化jdbc3个接口用来处理sql的执行,是Statement PreparedStatement CallableStatement提供适当的Statement接口批量执行sql从数据库批量获取数据PreparedStatement 比Statement性能要好主要体现在一个sql语句多次重复执行的情况PreparedStatemnt只编译解析一次而Statement每次编译一次.批量修改数据库Statement 提供了方法addBatch(String)和executeBatch()调用方法为stmt.addBatch(“isnert…..”); stmt.addBatch(“update…..”)stmt.executeBatch();也可以用PreparedStatement从而更好的提高性能.pstmt=conn.preparedStatement(“insert into test_table(……) values(….?)”);pstmt.setString(1,”aaa”);pstmt.addBatch();pstmt.setString(1,”bbb”);pstmt.addBatch();…..pstmt.executeBatch();批量地从数据库中取数据.通过setFetchSize()和getFectchSize()方法来设定和查看这个参数.这个参数对体统的性能影响比较大.这个参数太小会严重地降低程序地性能.Connection Statement ResultSet都有这个参数,他们对性能地影响顺序是: ResultSet———Statement———Connection(4)优化ResultSet.体现在以下几个方面批量读取数据.合理设置ResultSet的getFetchSize()和setFetchSize()方法中的参数使用正确的get和set方法使用整数而不是字段名作为参数性能比较高,例如 setInt(1,100);setString(2,”aaaa”);比setInt(“id”,”100″);setString(“name”,”aaaa”);性能好设置适当的滚动方向.有3个方向FETCH_FORWORD,FETCH_REVERSE FETCH_UNKNOWN单向滚动性能比较高.其他方面的性能优化及时显示的关闭Connection Statement ResultSet其中Connection可以用Connetion Pool处理.使用数据库系统的强大查询功能去组织数据.这样程序运行是和数据库服务的交互次数少,数据库返回给程序的记录条数少的多,所以性能有很大的提高.。

JDBC性能优化方案

JDBC性能优化方案

JDBC性能优化⽅案最近⽤到了利⽤JDBC查询Oracle数据库。

可是查询效率不尽⼈意。

研究了⼀下JDBC⽅⾯能够优化的地⽅,在这⾥跟⼤家分享⼀下。

1.设置最优的预取值defaultRowPrefetch:预取条数默认值defaultBatchValue:触发查询操作的批量请求值这两个參数的默认值都是10。

我们能够通过添加这两个參数值来降低数据库请求以提⾼查询效率,当然详细值⼤⼩要视详细情况⽽定。

2.通过连接池获取连接创建连接的代价⾮常⼤,通过连接池获取连接可省去创建连接时间。

3.选择合适的Statement接⼝(共同拥有三种)Statement:仅仅⽀持静态sqlPreparedStatement:⽀持动态输⼊參数的sql, 由于其预编译的sql具有可重⽤性,可极⼤地避免Oracle对sql的(应解析和软解析)解析时间,提⾼查询速度CallableStatement:专门针对存储过程,使⽤它能享受到全部存储过程带来的优势,但也包含存储过程带来的劣势如Java程序可移植性查,依赖数据库等4.设置检索时的批量值Statement.getFetchSize(); 获取⼀次检索的批量值Statement.setFetchSize(30); 设置批量值传统情况下,设置FetchSize值对检索⼤数据表时性能的提升是⾮常明显的。

原因是jdbc驱动默认每次仅仅检索10条记录(传到client的应该是⼀个游标),假设我们要检索100条数据,那么就须要client和server端进⾏10次⽹络往返才⼲所有传输完成。

每次⽹络间传输都会耗掉⼀些时间,⽐⽅採⽤TCP/IP协议的话。

要建⽴连接握⼿及额外的协议头尾开销等,这样势必会影响client的响应。

⾄于JDBC为何要设计这么⼩的数。

有⼈说是为了避免jvm out of memory 问题。

详细性能能提⾼多少,请參考:当然,FetchSize并⾮越⼤越好。

⾄于原因请參考:5.设置ResultSet的批量值ResultSet.getFetchSize(); 获取默认批量值ResultSet.setFetchSize(50); 设置批量值处理⼤数据时可显著提⾼处理速度6.设置ResultSet合适的处理⽅向ResultSet.getFetchDirection(); 获取默认值ResultSet.setFetchDirection(FETCH_REVERSE);设置合适的值7.从ResultSet获取数据时有两种⽅式, rs.getObject(int column_index) 和 rs.getObject(String column_label)rs.getObject(int column_index):这样的⽅式直接依据索引从rs对象中取出。

jdbc实验心得

jdbc实验心得

JDBC实验心得1. 介绍JDBC(Java Database Connectivity)是Java语言访问数据库的标准API。

通过JDBC,可以实现Java程序与各种关系型数据库的连接与交互。

在本次实验中,我深入学习了JDBC的使用方法,并通过实际操作,对JDBC在开发中的重要性有了更深刻的认识。

本文将从以下几个方面详细探讨我在实验中的心得体会:•JDBC的基本概念及原理•JDBC连接数据库的步骤•实际操作中遇到的问题及解决方法•JDBC在开发中的应用场景•实验的收获和不足之处2. JDBC的基本概念及原理2.1 JDBC的作用和优势JDBC是Java语言连接数据库的标准接口。

它使得Java程序能够通过标准的数据库操作语句与数据库进行交互,实现数据的存储和查询等功能。

JDBC的优势在于它能够提供跨平台的数据库访问能力,而不依赖于特定的数据库或操作系统。

2.2 JDBC的工作原理JDBC的工作原理可以分为以下几个步骤:1.加载数据库驱动程序:在使用JDBC之前,需要先加载相应数据库的驱动程序。

通过Class.forName()方法加载驱动类,这个类实现了Java SQL接口规范。

2.建立数据库连接:通过DriverManager类的getConnection()方法,传入数据库URL、用户名和密码等参数,来建立与数据库的连接。

连接成功后,将返回一个Connection对象。

3.创建执行SQL语句的Statement对象:通过Connection对象的createStatement()方法,可以创建一个用于执行SQL语句的Statement对象。

4.执行SQL语句:使用Statement对象的executeQuery()或executeUpdate()方法,可以执行查询或更新操作。

5.处理查询结果或更新结果:当执行查询语句后,可以使用ResultSet对象来遍历查询结果集;当执行更新语句后,可以使用int值表示受影响的行数。

jdbc连接池参数

jdbc连接池参数

jdbc连接池参数jdbc连接池参数的设置是在进行数据库连接时非常重要的一部分,它可以有效地管理连接的创建和销毁,提高数据库访问的性能和效率。

下面将介绍一些常用的jdbc连接池参数及其作用。

1. 初始化连接数(initialSize):指定连接池在启动时初始化的连接数。

通过设置适当的初始连接数,可以在系统启动时预先创建一定数量的数据库连接,以便后续的数据库操作能够迅速得到响应。

2. 最小空闲连接数(minIdle):指定连接池中保持的最小空闲连接数。

当连接池中的连接数低于该值时,连接池会自动创建新的连接。

3. 最大空闲连接数(maxIdle):指定连接池中保持的最大空闲连接数。

当连接池中的连接数超过该值时,多余的连接会被销毁。

4. 最大连接数(maxActive):指定连接池中允许的最大连接数。

当连接池中的连接数达到该值时,后续的连接请求将被阻塞,直到有空闲连接可用。

5. 连接超时时间(maxWait):指定从连接池获取连接的最大等待时间。

当连接池中的连接都被占用时,新的连接请求将等待一段时间,如果超过设定的超时时间,将抛出连接超时的异常。

6. 验证连接的有效性(testOnBorrow):指定在从连接池中获取连接时,是否对连接进行有效性验证。

通过设置该参数,可以避免从连接池中获取到无效的连接。

7. 检测空闲连接的间隔时间(timeBetweenEvictionRunsMillis):指定检测空闲连接的时间间隔。

连接池会定期检测空闲连接的有效性,并且销毁无效的连接。

8. 连接的最大生存时间(maxAge):指定连接的最大生存时间。

如果连接在该时间段内没有被使用,连接池将会自动销毁该连接。

以上是一些常用的jdbc连接池参数,通过合理地设置这些参数,可以提高数据库访问的性能和效率。

在实际应用中,需要根据具体的情况进行调整和优化,以满足系统的需求。

jdbc properties参数

jdbc properties参数

jdbc properties参数【原创版】目录1.JDBC 概述2.JDBC properties 参数的作用3.JDBC properties 参数的分类4.常用 JDBC properties 参数介绍5.JDBC properties 参数的设置方法6.总结正文一、JDBC 概述JDBC(Java Database Connectivity,Java 数据库连接)是 Java 中用于连接和操作数据库的一种技术标准。

它提供了一组用于访问关系型数据库的接口,可以使 Java 程序员在不关心具体数据库类型的情况下进行数据库操作。

二、JDBC properties 参数的作用在 JDBC 编程中,我们需要配置一些参数来连接数据库,这些参数被称为 JDBC properties 参数。

它们用于设置数据库连接的各种属性,例如数据库 URL、用户名、密码等。

通过设置 JDBC properties 参数,我们可以轻松地切换不同的数据库。

三、JDBC properties 参数的分类JDBC properties 参数主要分为以下几类:1.数据库连接参数:如数据库 URL、用户名、密码等。

2.数据库驱动参数:如驱动类名、驱动库路径等。

3.数据库连接池参数:如连接池大小、最大连接数等。

4.其他参数:如自动提交、事务隔离级别等。

四、常用 JDBC properties 参数介绍1.数据库连接参数- 数据库 URL:用于指定数据库的地址和端口,格式为:jdbc:数据库类型://主机名:端口/数据库名。

- 用户名:用于登录数据库的用户名。

- 密码:用于登录数据库的密码。

2.数据库驱动参数- 驱动类名:用于指定连接数据库所使用的驱动类名称。

- 驱动库路径:用于指定驱动类所在的 jar 文件路径。

3.数据库连接池参数- 连接池大小:用于指定连接池中的最大连接数。

- 最大连接数:用于指定连接池中最多允许的并发连接数。

DM7 JDBC性能监控使用

DM7 JDBC性能监控使用

提交次数 回滚次数
sql 编号 sql 语句 执行次数 执行时间总和 最长执行时间 在事务中执行的次数(非自动提交) 出错次数 更新行数总和 获取行数总和 正在执行数 最大并发数 执行时间分布 执行+结果集获取时间和的分布 结果集获取行数分布 更新行数分布
ExecHisto 是一个长度为 8 的数组,每个元素表示执行时间在相应区间内的次数,区间 如下,单位 ms: 0-1; 1-10; 10-100; 100-1000; 1000-10000; 10000-100000; 100000-1000000; 1000000 以上; ExecRsHisto 区间与 Exe个元素表示结果集获取行数在相应区间内的 次数,区间如下: 0-1; 1-10; 10-100; 100-1000; 1000-10000; 10000 以上;
2、输出到监控文件使用测试
以 100 库的 benchmarksql tpcc 测试为例,配置 props.dm: driver=dm.jdbc.driver.DmDriver conn=jdbc:dm://223.254.17.235:5239?statEnable=true&statDir=/mppdata/ybl/jdbclog&statFlus hFreq=120&statSlowSqlCount=10&statHighFreqSqlCount=10&statMaxSqlCount=10000&statSqlR emoveMode=eldest user=BENCHMARKSQL password=123456789
SQL 监控-------显示具体监控信息
点击具体的 SQL 语句,会显示该 SQL 的详细监控信息:

使用springjdbc遇到的一个性能问题

使用springjdbc遇到的一个性能问题

使⽤springjdbc遇到的⼀个性能问题使⽤JdbcTemplate的queryForList⽅法,返回特别慢,40多万结果集耗时超过6分钟。

双核CPU,占⽤率始终在50%,内存逐渐增长⾄2G左右。

进⾏debug跟进去看,看到jdbcTemplate调⽤jdbc返回ResultSet只⽤了30秒左右,之后就⼀直耗在extractData⽅法⾥。

该⽅法是⽤默认的RowMapper,先取得MetaData然后根据这个去⽣成Map。

对⽐⽅法:1. 使⽤纯jdbc对⽐,⼿⼯码代码,直接调⽤Map的put⽅法逐个⽣成Map并填充数据。

同样的sql,耗时40多秒,最后内存2G,其中根据ResultSet⽣成List<Map<String, Object>>的过程不超过10s。

2. 改⽤jdbcTemplate的public <T> List<T> query(String sql, RowMapper<T> rowMapper)⽅法,T填⼊Map<String, Object>,这样就跟queryForList⽅法返回值⼀样了,然后⾃⼰实现RowMapper,直接⽤Map的put⽅法填充数据。

实验结果跟直接⽤纯jdbc效率相同。

3. 使⽤纯jdbc,⾃⼰写⼀个实体类,把resultSet⾥的数据循环填⼊对象放到List⾥。

耗时40多秒,最后内存1.5G。

说明还是会省⼀点内存的。

但是性能提升有限。

结论:⽬前建议结果集较⼤时,最好使⽤public <T> List<T> query(String sql, RowMapper<T> rowMapper)⽅法替代qeuryForList⽅法,这样效率会有所提⾼。

未来估计jdbcTemplate的queryForList效率也会提升到相似⽔平。

jdbc connection configuration使用方法

jdbc connection configuration使用方法

jdbc connection configuration使用方法JDBC Connection Configuration使用方法简介JDBC Connection Configuration是用于在Java应用程序中连接数据库的配置工具。

本文将详细介绍各种方法和使用技巧。

方法一:使用DriverManager•使用()方法加载数据库驱动程序•使用()方法获取数据库连接对象示例代码:("");Connection connection = ("jdbc: "username", "password");方法二:使用DataSource•使用DataSource为JDBC提供连接池管理功能•创建DataSource对象并配置连接参数•调用()方法获取数据库连接对象示例代码:DataSource dataSource = new BasicDataSource(); ((BasicDataSource) dataSource).setUrl("jdbc: ((BasicDataSource) dataSource).setUsername("username"); ((BasicDataSource) dataSource).setPassword("password");Connection connection = ();方法三:使用JNDI(Java Naming and Directory Interface)•在应用服务器中配置数据源•使用JNDI获取数据库连接对象示例代码:Context context = new InitialContext();DataSource dataSource = (DataSource) ("java:/comp/env/jd bc/mydb");Connection connection = ();方法四:使用连接池•使用连接池管理数据库连接•创建连接池对象并配置连接参数•调用连接池的getConnection()方法获取连接对象示例代码:ComboPooledDataSource dataSource = new ComboPooledD ataSource();("");("jdbc:("username");("password");Connection connection = ();方法五:使用连接池框架•使用第三方连接池框架管理数据库连接•配置连接池参数并进行初始化•调用连接池的getConnection()方法获取连接对象示例代码(使用HikariCP连接池):HikariConfig config = new HikariConfig();("jdbc:("username");("password");HikariDataSource dataSource = new HikariDataSource(confi g);Connection connection = ();总结本文介绍了多种JDBC Connection Configuration的使用方法,包括使用DriverManager、DataSource、JNDI、连接池以及连接池框架。

jdbc驱动深度优化

jdbc驱动深度优化
有点优势 瞬间爆发有优势
Dal层 连接创建 TAF,MTS
1.23ms 100ms(140) 支持
0.98ms 20ms(1000) 不支持
查询超时
ps.setQueryTImeout(); 防止查询阶段因为扫表引起的慢查询导致整个系统和 DB处于阻塞状态。 设臵之后timeout线程检查超时并调用ps.cancel(),抛 出sql异常,oracle中的信息为“ORA-01013: 用户请求 取消当前的操作”。
返回记录 0 0 0 0 0 0 0 0 0
执行时间 (ms) 1.5875 2.0468 2.6656 0.1898 0.3431 1.2609 1.6344 1.6687 1.6266
Fetchsize造成的OOM
不要忘了每个ps都会开辟一个内存区,由于存在 pscache,也就是说连接池中的每个connection可能具 备上百个ps,每个ps中的内存缓冲区大小是由表中字 段大小决定的,例如: 每条纪录定义:10k,fetchsize:50 ,pscache:100, 连接池max值:30, • 连接池个数:2极端情况下,内存占用 会达到:2*10K*50*100*30*2=6GB 不单如此由于占用内存过高,还可能引起频繁的full gc
通过fetchsize提升性能

数据库 ORACLE ORACLE ORACLE ORACLE ORACLE ORACLE ORACLE ORACLE ORACLE
连接方式 oci oci oci oci oci oci thin thin thin
PSCACHE 支持 支持 支持 支持 支持 支持 支持 支持 支持
Oracle软硬解析
第一种情况下,DB每次都会该查询语句进行语法检查、语 意分析、生存执行计划、计划优化,这里我们称之为硬解 析。 第二种情况下,DB只会进行一次编译,并将查询计划发放 入共享池,以便后续可以重用这个查询计划,这里我们称 之为软解析。 在使用硬解析过程中oracle为了保证共享池中数据结构不被 串改和脏读,会长时间的使用串行处理,那么硬解析的数 量越多,DB的性能下降将越快。

JDBC优化与批量处理技巧

JDBC优化与批量处理技巧

JDBC优化与批量处理技巧JDBC(Java Database Connectivity)是Java语言中用于访问关系型数据库的接口,也是Java EE中常用的数据访问方式之一。

在Java EE应用开发中,JDBC是必备的技能之一。

在使用JDBC时,需要注意代码的执行效率和效果。

本文主要介绍JDBC的优化和批量处理技巧,以提高代码的执行效率和效果。

一、JDBC优化技巧1.1 使用PreparedStatement代替Statement在使用JDBC时,有两种方式用于执行SQL语句,即Statement和PreparedStatement。

在执行单条语句时,两者的效果差不多。

但是在执行大量语句时,PreparedStatement的效率比Statement更高。

这是因为PreparedStatement能够预编译SQL语句,而Statement无法预编译。

预编译SQL语句可以减少数据库的负担,提高代码执行效率。

下面是一个使用PreparedStatement的例子:```javaPreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE name = ?");ps.setString(1, "John");ResultSet rs = ps.executeQuery();```1.2 使用连接池连接池是一种基于数据库连接池技术的优化方式,可以避免在每次执行数据库操作时都要重新连接数据库的问题。

使用连接池可以有效地减少数据库的负荷和资源消耗。

Java EE中提供了多种连接池技术,例如Apache DBCP、C3P0等。

下面是一个使用C3P0连接池的例子:```javaComboPooledDataSource ds = new ComboPooledDataSource();ds.setDriverClass("com.mysql.jdbc.Driver");ds.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");ds.setUser("user");ds.setPassword("pwd");Connection conn = ds.getConnection();```1.3 批量操作在Java EE应用中,经常需要执行批量操作,例如批量插入数据、批量删除数据等。

追求JDBC on Oracle最佳性能?如何才好?

追求JDBC on Oracle最佳性能?如何才好?

代码里是写了关闭游标,但 存在还没执行就跑到异常处 理里去的可能。
Jdbc1性能案例2:对策
try { Finally中调用关闭游标, ...... TRY块结束后总会执行 rset = pstmt.executeQuery(); ...... rset.close(); } catch (SQLException e) { e.printStackTrace(); } finally { if (pstmt != null) try {pstmt.close();} catch (SQLException e) {...} }
Jdbc性能案例1:结果
• •
响应时间: 150ms 吞吐量: 300tps
• CPU方面Sys和User都很高
Jdbc1性能案例1:对策
conn = ds.getConnection(userid, password); for (i = 0; i < 1000000; i++) { pstmt = conn.prepareStatement("SELECT name FROM employees WHERE id = " + i); rset = pstmt.executeQuery(); ...... } conn.close();
Other tips:Set AutoCommit Off
关闭自动commit,在应用真正需要的时候commit, 即维护了必要的事务又减少了log file sync等待
Connection.setAutoCommit(false);
Other tips:批量Insert
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); Connection conn = DriverManager.getConnection ("jdbc:oracle:oci8:@","scott","tiger"); PreparedStatement ps = conn.prepareStatement ("insert into dept values (?, ?,?)"); //Change batch size for this statement to 3 ((OraclePreparedStatement)ps).setExecuteBatch (3); ps.setInt (1, 23); ps.setString (2, "Sales"); ps.setString (3, "USA"); ps.executeUpdate (); //JDBC queues this for later execution ps.setInt (1, 24); ps.setString (2, "Blue Sky"); ps.setString (3, "Montana"); ps.executeUpdate (); //JDBC queues this for later execution ps.setInt (1, 25); ps.setString (2, "Applications"); ps.setString (3, "India"); ps.executeUpdate (); //The queue size equals the batch value of 3 //JDBC sends the requests to the // database ps.setInt (1, 26); ps.setString (2, "HR"); ps.setString (3, "Mongolia"); ps.executeUpdate (); //JDBC queues this for later execution ((OraclePreparedStatement)ps).sendBatch (); //JDBC sends the queued request …………………..
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

JDBC 性能技巧阅读原文:/articles/article.tss?l=JDBCPerformanceApril 2004介绍开发一个注重性能的JDBC 应用程序不是一件容易的事. 当你的代码运行很慢的时候JDBC 驱动程序并不会抛出异常告诉你.本系列的性能提示将为改善JDBC 应用程序的性能介绍一些基本的指导原则,这其中的原则已经被许多现有的JDBC 应用程序编译运行并验证过。

这些指导原则包括:∙正确的使用数据库MetaData 方法∙ 只获取需要的数据∙ 选用最佳性能的功能∙ 管理连接和更新 以下这些一般性原则可以帮助你解决一些公共的JDBC 系统的性能问题.正确使用数据库Metadata 方法因为通过ResultSet 对象生成的Metadata 方法与其它的JDBCB 方法相比是较慢的, 经常的使用它们将会削弱系统的的性能. 本节的指导原则将帮助你选择和使用meatdata 时优化系统性能.少用Metadata 方法与其它的JDBC 方法相比, 由ResultSet 对象生成的metadata 对象的相对来说是很慢的. 应用程序应该缓存从ResultSet 返回的metadata 信息,避免多次不必要的执行这个操作. John Goodson 是一名JDBC 专家组成员,也是DataDirect Technologies 公司的副总裁.几乎没有哪一个JDBC应用程序不用到metadata,虽然如此,你仍可以通过少用它们来改善系统性能. 要返回JDBC规范规定的结果集的所有列信息, 一个简单的metadata的方法调用可能会使JDBC驱动程序去执行很复杂的查询甚至多次查询去取得这些数据. 这些细节上的SQL语言的操作是非常消耗性能的.应用程序应该缓存这些metadata信息. 例如, 程序调用一次getTypeInfo方法后就将这些程序所依赖的结果信息缓存. 而任何程序都不大可能用到这些结果信息中的所有内容,所以这些缓存信息应该是不难维护的.避免null参数在metadata的方法中使用null参数或search patterns是很耗时的. 另外, 额外的查询会导致潜在的网络交通的增加. 应尽可能的提供一些non-null的参数给metadata方法.因为metadata的方法很慢, 应用程序要尽可能有效的调用它们. 许多应用程序只传递少量的non-null参数给这些方法.例如:应该这样:在第一个getTables()的调用中, 程序可能想知道表'WSTable'是否存在. 当然, JDBC驱动程序会逐个调用它们并且会解译不同的请求. JDBC驱动程序会解译请求为: 返回所有的表, 视图, 系统表, synonyms, 临时表, 或存在于任何数据库类别任何Schema中的任何别名为'WSTable'的对象.第二个getTables()的调用会得到更正确的程序想知道的内容. JDBC驱动程序会解译这个请求为: 返回当前数据库类别中所有存在于'johng'这个schema中的所有表.很显然, JDBC驱动程序处理第二个请求比处理第一个请求更有效率一些.有时, 你所请求信息中的对象有些信息是已知的. 当调用metadata方法时, 程序能传送到驱动程序的的任何有用信息都可以导致性能和可靠性的改善.使用'哑元'(dummy)查询确定表的特性要避免使用getColumns()去确定一个表的特性. 而应该使用一个‘哑元’查询来使用getMetadata()方法.请考虑这样一个程序, 程序中要允许用户选取一些列. 我们是否应该使用getColumns()去返回列信息给用户还是以一个'哑元'查询来调用getMetadata()方法呢?案例 1: GetColumns 方法案例 2: GetMetadata 方法在这两个案例中, 一个查询被传送到服务器. 但在案例1中, 查询必须被预储和执行, 结果的描述信息必须确定(以传给getColumns()方法), 并且客户端必须接收一个包含列信息的结果集. 在案例2中, 只要准备一个简单的查询并且只用确定结果描述信息. 很显然, 案例2执行方式更好一些.这个讨论有点复杂, 让我们考虑一个没有本地化支持prepared statement的DBMS服务器. 案例1的性能没有改变, 但案例2中, 因为'哑元'查询必须被执行而不是被预储使得它的性能增强了一些. 因为查询中的WHERE子句总是为FALSE, 查询在不用存取表的数据情况的下会生成没有数据的结果集. 在这种情况下,第二种方式当然比第一种方式好一些.总而言之,总是使用ResultSet的metadata方法去获取列信息,像列名,列的数据类型,列的数据精度和长度等. 当要求的信息无法从ResultSet的metadata中获取时才去用getColumns()方法(像列的缺省值这些信息等).获取需要的数据要有效的获取数据,就只需返回你需要的数据, 以及很多用效的方法. 本节的指导原则将帮助你使用JDB获取数据时优化系统性能.获取长数据如非必要, 应用程序不应请求长的数据, 因为长的数据通过网络传输会非常慢和消耗资源.大多数用户并不想看到大堆的数据. 如果用户不想处理这些长数据, 那么程序应能够再次查询数据库, 在SELECT子句中指定需要的列名. 这种方式允许一般用户获取结果集而不用消耗昂贵的网络流量.虽然最好的方式是不要将长数据包括在SELECT子句的列名中,但还是有一些应用程序在发送查询给JDBC驱动程序时并没有在SELECT子句中明确指出列名(确切一点, 有些程序发送这样的查询: select * from <table name> ...). 如果SELECT子句的列名中包含长数据, 许多JDBC驱动程序必须在查询时重新获取数据, 甚至在ResultSet中这些长数据并没有被程序用到. 在可能情况下,开发者应该试着去实现一种不需获取所有列数据的方法.例如,看以下的JDBC代码:要记住JDBC驱动程序没有知觉. 当查询被执行时它不知道哪些列是程序所要的. 驱动程序只知道应用程序能请求任意的列. 当JDBC驱动程序处理 rs.next()请求时, 它可能会跨过网络从数据库服务器至少返回一行结果. 在这种情况下, 每个结果行会包含所有的列数据–如果Employees表有一列包含员工相片的话它也会被包含在结果里面. 限制SELECT子句的列名列表并且只包含有用的列名,会减少网络流量及更快的查询性能.另外,虽然getClob()和getBlob()方法可以允许应用程序去如何控制获取长数据, 但开发者必须认识到在许多情况下, JDBC驱动程序缺少真正的LOB定位器的支持. 像这种情况下,在暴露getClob和getBlob方法给开发者之前驱动程序必须经过网络获取所有的长数据.减少获取的数据量有时必须要获取长数据. 这时, 要注意的是大多数用户并不想在屏幕上看到100k甚至更多的文字.要减少网络交通和改善性能, 通过调用setMaxRows(), SetMaxFieldSize及SetFetchSize()方法, 你可以减少取获取的数据量. 另一种方式是减少数据的列数. 如果驱动程序允许你定义packet的大小, 使用最小的packet尺寸会适合你的需要.记住: 要小心的返回只有你需要的行和列数据. 当你只需要2列数据而你却返回的5列数据时,性能会降低–特别是不需要的行中包含有长数据时.选择合适的数据类型接收和发送某些数据可能代价昂贵. 当你设计一个schema时, 应选择能被最有效地处理的数据类型. 例如, 整型数就比浮点数或实数处理起来要快一些. 浮点数的定义是按照数据库的内部规定的格式, 通常是一种压缩格式. 数据必须被解压和转换到另外种格式, 这样它才能被数据的协议处理.获取ResultSet由于数据库系统对可滚动光标的支持有限, 许多JDBC驱动程序并没有实现可滚动光标. 除非你确信数据库支持可滚动光标的结果集, 否则不要调用st()和rs.getRow()方法去找出数据集的最大行数. 因为JDBC驱动程序模拟了可滚动光标, 调用st()导致了驱动程序透过网络移到了数据集的最后一行.取而代之, 你可以用ResultSet遍历一次计数或者用SELECT查询的COUNT函数来得到数据行数.通常情况下,请不要写那种依赖于结果集行数的代码, 因为驱动程序必须获取所有的数据集以便知道查询会返回多少行数据.选用JDBC对象和方法本节的指导原则将帮助你在选用JDBC的对象和方法时哪些会有最好的性能.在存储过程中使用参数标记作为参数当调用存储过程时, 应总是使用参数标记(?)来代替字面上的参数. JDBC驱动能调用数据库的存储过程, 也能被其它的SQL查询执行, 或者直接通过远程进程调用(RPC)的方式执行. 当你将存储过程作为一个SQL查询执行时, 数据库要解析这个查询语句, 校验参数并将参数转换为正确的数据类型.要记住, SQL语句总是以字符串的形式送到数据库, 例如, “{call getCustName (12345)}”. 在这里, 即使程序中将参数作为整数赋给了getSustName, 而实现上参数还是以字符串的形式传给了服务器. 数据库会解析这个SQL查询, 并且根据metadata来决定存储过程的参数类型, 然后分解出参数"12345", 然后在最终将存储过程作为一个SQL查询执行之前将字串'12345’转换为整型数.按RPC方式调用时, 之前那种SQL字符串的方式要避免使用. 取而代之, JDBC 驱动会构造一个网络packet, 其中包含了本地数据类型的参数,然后执行远程调用.案例 1在这个例子中, 存储过程不能最佳的使用RPC. 数据库必须将这作为一个普通的语言来进行解析,校验参数类型并将参数转换为正确的数据类型,最后才执行这个存储过程.案例 2在这个例子中, 存储过程能最佳的执行RPC. 因为程序避免了字面的的参数,使用特殊的参数来调用存储过程, JDBC驱动能最好以RPC方式直接来执行存储过程. SQL语言上的处理在这里被避免并且执行也得到很大的改善.使用Statement而不是PreparedStatement对象JDBC驱动的最佳化是基于使用的是什么功能. 选择PreparedStatement还是Statement取决于你要怎么使用它们. 对于只执行一次的SQL语句选择Statement是最好的. 相反, 如果SQL语句被多次执行选用PreparedStatement 是最好的.PreparedStatement的第一次执行消耗是很高的. 它的性能体现在后面的重复执行. 例如, 假设我使用Employee ID, 使用prepared的方式来执行一个针对Employee表的查询. JDBC驱动会发送一个网络请求到数据解析和优化这个查询. 而执行时会产生另一个网络请求. 在JDBC驱动中,减少网络通讯是最终的目的. 如果我的程序在运行期间只需要一次请求, 那么就使用Statement. 对于Statement, 同一个查询只会产生一次网络到数据库的通讯.对于使用PreparedStatement池的情况下, 本指导原则有点复杂. 当使用PreparedStatement池时, 如果一个查询很特殊, 并且不太会再次执行到, 那么可以使用Statement. 如果一个查询很少会被执行,但连接池中的Statement池可能被再次执行, 那么请使用PreparedStatement. 在不是Statement池的同样情况下, 请使用Statement.使用PreparedStatement的Batch功能Update大量的数据时, 先Prepare一个INSERT语句再多次的执行, 会导致很多次的网络连接. 要减少JDBC的调用次数改善性能, 你可以使用PreparedStatement的AddBatch()方法一次性发送多个查询给数据库. 例如,让我们来比较一下下面的例子.例 1: 多次执行Prepared Statement例 2: 使用Batch在例 1中, PreparedStatement被用来多次执行INSERT语句. 在这里, 执行了100次INSERT操作, 共有101次网络往返. 其中,1次往返是预储statement, 另外100次往返执行每个迭代. 在例2中, 当在100次INSERT操作中使用addBatch()方法时, 只有两次网络往返. 1次往返是预储statement, 另一次是执行batch命令. 虽然Batch命令会用到更多的数据库的CPU周期, 但是通过减少网络往返,性能得到提高. 记住, JDBC的性能最大的增进是减少JDBC驱动与数据库之间的网络通讯.选择合适的光标类型选择适用的光标类型以最大限度的适用你的应用程序. 本节主要讨论三种光标类型的性能问题.对于从一个表中顺序读取所有记录的情况来说, Forward-Only型的光标提供了最好的性能. 获取表中的数据时, 没有哪种方法比使用Forward-Only型的光标更快. 但不管怎样, 当程序中必须按无次序的方式处理数据行时, 这种光标就无法使用了.对于程序中要求与数据库的数据同步以及要能够在结果集中前后移动光标, 使用JDBC的Scroll-Insensitive型光标是较理想的选择. 此类型的光标在第一次请求时就获取了所有的数据(当JDBC驱动采用'lazy'方式获取数据时或许是很多的而不是全部的数据)并且储存在客户端. 因此, 第一次请求会非常慢, 特别是请求长数据时会理严重. 而接下来的请求并不会造成任何网络往返(当使用'lazy'方法时或许只是有限的网络交通) 并且处理起来很快. 因为第一次请求速度很慢, Scroll-Insensitive型光标不应该被使用在单行数据的获取上. 当有要返回长数据时, 开发者也应避免使用Scroll-Insensitive型光标, 因为这样可能会造成内存耗尽. 有些Scroll-Insensitive型光标的实现方式是在数据库的临时表中缓存数据来避免性能问题, 但多数还是将数据缓存在应用程序中.Scroll-Sensitive型光标, 有时也称为Keyset-Driven光标, 使用标识符, 像数据库的ROWID之类. 当每次在结果集移动光标时, 会重新该标识符的数据.因为每次请求都会有网络往返, 性能可能会很慢. 无论怎样, 用无序方式的返回结果行对性能的改善是没有帮助的.现在来解释一下这个, 来看这种情况. 一个程序要正常的返回1000行数据到程序中. 在执行时或者第一行被请求时, JDBC驱动不会执行程序提供的SELECT语句. 相反, 它会用键标识符来替换SELECT查询, 例如, ROWID. 然后修改过的查询都会被驱动程序执行,跟着会从数据库获取所有1000个键值. 每一次对一行结果的请求都会使JDBC驱动直接从本地缓存中找到相应的键值, 然后构造一个包含了'WHERE ROWID=?'子句的最佳化查询, 再接着执行这个修改过的查询,最后从服务器取得该数据行.当程序无法像Scroll-Insensitive型光标一样提供足够缓存时,Scroll-Sensitive型光标可以被替代用来作为动态的可滚动的光标.使用有效的getter方法JDBC提供多种方法从ResultSet中取得数据, 像getInt(), getString(), 和getObject()等等. 而getObject()方法是最泛化了的, 提供了最差的性能。

相关文档
最新文档