在Java中,结合使用setXXX

系列方法,可以为不同数据类型的绑定变量进行赋值,从而大大优化了SQL 语句的性能。

没有使用绑定变量是使用Oracle数据库的应用系统性能问题主要原因和可伸缩性的主要障碍,Oracle的共享池的操作方法就决定开发人员应该使用绑定变量,如果想要Oracle运行速度减慢,甚至完全中止,就可以拒绝使用绑定变量。

在SQL语句中,绑定变量是一个占位符。例如,为了查询员工号为123的员工的信息,可以查询:1)select * from emp where

empno=123;另外,也可以查询:2)select * from emp where

empno=:empno。

在一个典型的OLTP系统中,查询员工123一次,可能再也不会查询,以后将查询员工456,员工789等。如果像语句1)中那样使用硬编码量(常量),那么每次查询都是一个新查询,即在数据库共享池中以前没有过的查询。每次查询必须经过分析、限定(名称解析)、安全检查、优化等等,简单地说,执行的每条语句在每次执行时都将必须经过编译。

在第二个查询2)中使用了绑定变量:empno,它的值在查询执行时提供。查询经过一次编译后,查询方案将存储在共享池中,可以用来检索和重用。在性能和可伸缩性方面,这两者的差异是巨大的,甚至是惊人的。

从上所述,很明显看出,分析一个带有硬编码量的语句将比重用一条已分析过的查询方案花费更长的时间和消耗更多的资源,不明显的是前者将减少系统所能支持的用户数量。很明显,部分原因是由于增加资源消耗量,但更主要的因素是在解析sql语句的过程中对共享池中锁存器(latch)的争用。

通过下面的两个小程序我们可以看出其中的差别,其中程序NoBind.java没有使用绑定变量,程序UseBind.java使用了绑定变量。

程序NoBind.java:

// You need to import the java.sql package to use

JDBC

import java.sql.*;

import oracle.jdbc.*;

// We import java.io to be able to use the i/o

Class

import java.io.*;

class NoBind

{

public static void main(String args[])

throws SQLException, IOException

{

// Load the Oracle JDBC driver

DriverManager.registerDriver(new

oracle.jdbc.OracleDriver());

Connection conn =

DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:

demo","scott","tiger");

// Create a statement

Statement stmt =

conn.createStatement();

for(int i=1;i<=5;i++)

{

ResultSet rset = stmt.executeQuery("select hisal

from salgrade where grade="+i);

while (rset.next())

{

System.out.println(rset.getString(1));

}

// close the result set

rset.close();

}

// close the statement and connect

stmt.close();

conn.close();

}

}

程序UseBind.java:

// You need to import the java.sql package to use

JDBC

import java.sql.*;

import oracle.jdbc.*;

// We import java.io to be able to use the i/o

Class

import java.io.*;

class UseBind

{

public static void main(String args[])

throws SQLException, IOException

{

// Load the Oracle JDBC driver

DriverManager.registerDriver(new

oracle.jdbc.OracleDriver());

Connection conn =

DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:

demo","scott","tiger");

// Create a PreparedStatement

PreparedStatement pstmt =

conn.prepareStatement("select hisal from salgrade where

grade=?");

for (int i=1;i<=5;i++)

{

// use the setXX() method

pstmt.setInt (1,i);

ResultSet rset = pstmt.executeQuery();

while (rset.next())

{

System.out.println(rset.getString(1));// print the first

column

}

// close the result set

rset.close();

}

// close the statement and connect

pstmt.close();

conn.close();

}

}

上面两个程序都是通过scott/tiger登录,从salgrade表中检索5条数据,然后在终端上打印出来,不同之处在于第一个程序使用硬编码量,通过拼字符串的方式来构造sql语句,第二个程序使用了绑定变量,先使用一个占位符代替实际数值,然后再通过setInt()方法给占位符赋值。

执行程序NoBind.java后,通过查询v$sql视图可以发现,Oracle解析了5条不同的sql语句,如下:

SQL> select sql_text from v$sql where

sql_text like 'select hisal from%';

SQL_TEXT

-------------------------------------------------------------------------------

select hisal from salgrade where grade=1

select hisal from salgrade where grade=4

select hisal from salgrade where grade=2

select hisal from salgrade where grade=5

select hisal from salgrade where grade=3

刷新共享池,然后再执行程序UseBind.java后,通过查询v$sql视图可以发现,Oracle只解析了1条sql语句,如下:

SQL> select sql_text from v$sql where

sql_text like 'select hisal from%';

SQL_TEXT

-------------------------------------------------------------------------------

select hisal from salgrade where grade=:1

通过上述测试可以看出,通过使用绑定变量,应用程序提交的相似的sql语句的执需要解析一次,就可以重复使用,这非常有效,这也是Oracle数据库要求使用的工作方式。不仅使用较少的资源,而且可以减少锁存(latch)时间,降低锁存(latch)次数,这将提高应用系统性能,并且大大提高可伸缩性。

参考资料:《Expert one-on-one Oracle》,Thomas

kyte.

java sql绑定_在JAVA 源程序中编写SQL语句时使用ORACLE 绑定变量相关推荐

  1. java绑定变量怎么加_在JAVA 源程序中编写SQL语句时使用ORACLE 绑定变量

    在JAVA中的SQL 语句的编写方面,没有使用ORACLE 绑定变量,很大程度上降低了数据库的性能,表现在两个方面: 1.SQL语句硬分析(Hard Parse)太多,严重消耗CPU资源,延长了SQL ...

  2. python解析sql文件_如何从Python中解析sql文件?

    是否有任何方法可以从Python中执行.SQL文件中的某些SQL命令,而不是文件中的所有SQL命令?假设我有以下.sql文件:DROP TABLE IF EXISTS `tableA`; CREATE ...

  3. sql 会话_在特定会话中禁用SQL Server中的触发器

    sql 会话 This article will focus on the various ways to disable triggers in SQL Server so they won't i ...

  4. mysql workbench 执行sql文件_向mysql workbench中导入.sql文件

    mysql workbench用的不多,前段时间装了一下,然后用了一下,感觉操作比dbdesigner4要更人性化一点.其中二个方面做了改进,让我觉得很爽. 第一,就是端口可以修改了,以前就是定死33 ...

  5. java基础知识点_「Java面试题/知识点精华集」20000+字的Java基础知识篇(2020最新版) !

    " 本文已经收录进我的 79K Star 的 Java 开源项目 JavaGuide:https://github.com/Snailclimb/JavaGuide (「Java学习+面试指 ...

  6. shell脚本中编写SQL中 以传参(${accdate})的方式 动态:求 前12个月的日期和求 前一周(7天的日期)

    shell脚本中 编写SQL中 以传参(${accdate})的方式 动态 求 前12个月的日期 CAST(CAST(DATE_FORMAT(DATE_SUB(from_unixtime(unix_t ...

  7. 如何在Ruby中编写switch语句

    如何在Ruby中编写switch语句? #1楼 案例...当 在Chuck的答案中添加更多示例: 带参数: case a when 1puts "Single value" whe ...

  8. 如何在 Go 中编写 Switch 语句

    如何在 Go 中编写 Switch 语句 目录 在 Go 中导入包 理解 Go 中包的可见性 如何在 Go 中编写条件语句 如何在 Go 中编写 Switch 语句 如何在 Go 中构造 for 循环 ...

  9. 「每周译Go」如何在 Go 中编写 Switch 语句

    目录 在 Go 中导入包 理解 Go 中包的可见性 如何在 Go 中编写条件语句 如何在 Go 中编写 Switch 语句 如何在 Go 中构造 for 循环 在循环中使用 Break 和 Conti ...

最新文章

  1. Java数组传参sql_Java中如何传一个数组作为筛选条件操作数据库(sql中foreach的使用)...
  2. linux中的FTP服务配置详解
  3. HDU 6170-正则表达式
  4. Oracle下载汇聚
  5. 重磅发布 | 30+ 阿里巴巴云原生「顶流」,给你一堂《云原生技术实践公开课》
  6. Helm V3 新版本发布
  7. java架构师学习笔记
  8. 【原】概率论——第一章第1节
  9. 马赛克,克星,真来了!
  10. shell结合expect写的批量scp脚本工具
  11. c++ map初始化_Go学习每日一问(18)-map元素查找
  12. python django项目实例_最新Django项目实战-从零开发NB的任务平台python视频学习教程...
  13. 走近汇编理解与内核编程
  14. gin -get请求的小示例1-Handle处理GET请求
  15. jquery中object对象循环遍历的方法
  16. imx6ull设备树
  17. 【计算机组成原理之存储系统】超级详细
  18. Qt 给文本添加删除线 text-decoration
  19. Ipad上选择专业好用的思维导图软件
  20. 学习USART自闭实录(stm32F411RE)Stm32cubemx

热门文章

  1. hp打印机一直显示正在打印中_苹果Mac出现新bug HP打印机驱动被标为恶意软件
  2. 学生成绩预测模型_每日排行榜|四川省大学生金融科技建模大赛 10.9
  3. 将txt_path下的指定文件夹中的图片合在一起
  4. f4v格式视频转换成MP4格式的方法
  5. 解决Windows版Git出现templates not found的问题
  6. dnf最新开的服务器,DNF新玩法赛季服务器详解
  7. php mysql问答系统_PHP+MYSQL问答系统V3.7
  8. 入门指南:菜鸟如何学习数据分析?
  9. 移动物联网卡助力社区管理,提升居民安全性与幸福感
  10. 面试时被问到什么是面向对象OOP?看这篇就够了