介绍
在本文中,我将显示一个示例,说明如何使用Oracle支持的JDBC批量插入功能,这些功能特定于Oracle。
有关为什么可能希望一般使用批量插入的更多详细信息,例如,在某些情况下需要考虑性能,请参阅Joormana Brahma于2015年4月12日发表的JCG文章“ JDBC Batch Insert Example ”。
Brahma女士提供了3个示例,说明如何使用MySQL在JDBC中完成此功能,但是我在本文中展示的特定于Oracle的方式可以看作是她的第二个示例与第三个示例之间的交叉,例如,PreparedStatement之间的混合和批处理批次。
Oracle安装程序
为了利用本例中显示的支持JDBC批量插入的Oracle特定功能,您首先需要在Oracle数据库中创建几个用户定义的类型。
第一种类型映射到表中要批量插入的记录,第二种类型映射到第一种类型的变量数组。 换句话说,您可以将第一种类型视为表中的一行,而第二种类型只是这些行的数组。
您将使用支持JDBC批量操作的Oracle特定功能将这个数组批量插入表中,本文将对此进行演示。
因此,在此示例中创建的第一件事是Oracle中的表( 请参见下面的清单1 )。
DROP TABLE "SYSTEM"."EMPLOYEE";
CREATE TABLE "SYSTEM"."EMPLOYEE" ( "FIRST_NAME" VARCHAR2(20 BYTE), "LAST_NAME" VARCHAR2(20 BYTE),"EMP_NO" NUMBER, "JOIN_DATE" DATE)
TABLESPACE "SYSTEM" ;
清单1.用于创建“ Employee”表的DDL
该表是HR模式中Employees表的简化版本,Oracle在Application Express中将其用作示例。 请注意,清单1中的示例是由System用户创建的-对于实际使用而言并不现实,但是在这里满足我们的目的就足够了,例如,除了varchar2之外,在数字和日期等字段中还混合了SQL类型。
接下来,我们需要创建一个用户定义的类型,该类型映射到该表中的行( 请参见下面的清单2 ),例如,请注意,它与清单1中的Employee表中的字段具有直接关系。
create or replace
TYPE t_type AS OBJECT (first_name varchar2(20),last_name varchar2(20),emp_no number,join_date date
);
清单2.创建“ t_type
”对象的PL / SQL
然后,我们需要创建另一个用户定义的类型,该类型映射到第一个类型的变量数组( 请参见下面的清单3 )。
create or replace
type tb_t_type
as varray (1000000) of t_type;
清单3.创建“ tb_t_type
”对象的PL / SQL
请注意,此处定义的数组最大大小为100万。 您可以调整此大小以适合自己的需求(当然,在您自己的资源限制内),但是我们确实会在这里的JDBC示例中批量插入100万条记录。
最后,我们将需要创建由批量操作调用的存储过程( 请参见下面的清单4 )。
create or replace
procedure add_employees (emparray in tb_t_type) asbeginforall i in emparray.first .. emparray.lastinsert into EMPLOYEE( first_name, last_name,emp_no,join_date )values( emparray(i).first_name,emparray(i).last_name,emparray(i).emp_no, emparray(i).join_date );end add_employees;
清单4.创建“ add_employees”存储过程的PL / SQL
请注意,在此PL / SQL中使用了forall
习惯用法,这使得实际的大容量插入操作比仅使用普通香草“ for循环”时可能的情况快了大约一半数量级。 特别是在我自己的演示运行,我已经注意到了forall
成语产生的结果这是大约快5倍。
注意:在此示例中,我已在运行Windows 7 Home Premium的Dell笔记本电脑上使用Oracle Database Express Edition 11g第2版,该笔记本电脑具有Intel i5处理器@ 1.7GHz,8GB RAM。 对于Oracle JDBC驱动程序,我使用了ojdbc6.jar
。
JDBC
完成Oracle设置后,现在我们来看看如何利用支持JDBC批量插入操作的Oracle特定功能( 请参见下面的清单5 )。
清单5. Java示例,说明支持JDBC批量插入操作的Oracle特定功能
分析
请注意第2-4行的import语句,即,它们是ojdbc6.jar
定义的特定于Oracle的类型,这在本示例前面提到的就是利用特定于Oracle的功能进行JDBC批量插入。
如第12行的注释所示,要做的第一件事是获取我们的数据源。 请注意,对于第14-16行,您将需要用自己的值代替主机,端口和服务ID(“ sid”),尽管如果使用默认端口,则仅为1521。
在第22-23行,我们定义了一个Oracle STRUCT数组,该数组映射到我们先前在Oracle数据库中创建的用户定义类型“ tb_t_type
”( 请参见清单3 )。 同样在第22行,我们从命令行获取此变量数组的大小,即,在大容量插入操作中以100万条记录运行此示例,如下所示:
java OraBulk 1000000
在第26行,我们定义了Oracle struct描述符,该描述符映射到我们先前在Oracle数据库中创建的用户定义类型“ t_type
”( 请参见清单2 )。
接下来在第29-31行,我们准备准备批量插入的记录数组。 在此示例中,完成操作的方式有些人为设计,例如,雇员的加入日期只是该元素在循环中被迭代的时间,尽管有其技巧,但对于我们的目的来说已经足够了。
在第35-36行,我们定义了Oracle数组描述符,该描述符映射到用户定义的类型“ tb_t_type
”( 请参见清单3 ),并通过引用在第23行中定义的Oracle结构来实例化Oracle数组。
在完成所有先决条件工作之后,接下来我们在第39行创建Oracle预准备语句,以引用我们先前在Oracle数据库中定义的存储过程( 请参见清单4 )。 然后,它将Oracle数组设置为其第一个参数( 请参见第40行 )。
最后,在完成所有设置后,我们在第43行几乎没有大张旗鼓地执行了准备好的语句。
完成主要事件后,第46-48行的反高潮限制是强制提交和关闭以释放资源。 请注意,如果在批量插入期间发生异常,那么所有内容都会被回滚,因为默认情况下自动提交将处于关闭状态。
摘要
在我的基准测试运行中,在运行Windows 7 Home Premium的Dell笔记本电脑上,使用此代码在Oracle Database Express Edition 11g第2版中批量插入1百万条记录的时间为12.55秒,该笔记本电脑具有Intel i5处理器@ 1.7GHz和8GB RAM。 对于Oracle JDBC驱动程序,我使用了ojdbc6.jar
。
- 您可以下载代码和样品PL / SQL 这里的JCG
翻译自: https://www.javacodegeeks.com/2015/12/using-the-jdbc-insert-features-in-oracle.html