Monday, November 08, 2010

LẬP TRÌNH ORACLE VỚI JAVA: Sử dụng mảng đối tượng tự định nghĩa

Trong bài viết này mình trình bày với các bạn một cách đơn giản để cập nhật một mảng đối tượng tự định nghĩa xuống cơ sở dữ liệu Oracle sử dụng ngôn ngữ lập trình Java. Đồng thời chúng ta cũng sẽ so sánh thời gian thực thi của việc sử dụng mảng (Array) so với cách mà chúng ta vẫn thường dùng là sử dụng từng đối tượng (Ojbect) với từng lần gọi thực thi procedure.

Cách cập nhật một mảng dữ liệu của cùng một đối tượng thường được sử dụng khi chúng ta có nhu cầu cập nhật một số lượng lớn dữ liệu xuống cơ sở dữ liệu. Còn đối với số lượng dữ liệu ít thì chúng ta sử dụng cách thông thường.

Đầu tiên thì các bạn chạy các script sau để tạo bảng và các procedure cần thiết cho việc test.

CREATE TABLE test_table

(

number_col NUMBER(10),

string_col VARCHAR2(100 BYTE),

date_col DATE

)

TABLESPACE users

PCTUSED 0

PCTFREE 10

INITRANS 1

MAXTRANS 255

STORAGE (

INITIAL 64 k

MINEXTENTS 1

MAXEXTENTS UNLIMITED

PCTINCREASE 0

BUFFER_POOL DEFAULT

)

NOLOGGING

NOCOMPRESS

NOCACHE

NOPARALLEL

NOMONITORING;

CREATE OR REPLACE TYPE test_table_o AS OBJECT (

number_col NUMBER (10),

string_col VARCHAR2 (100 BYTE),

date_col DATE

)

/

CREATE OR REPLACE TYPE test_table_a AS TABLE OF test_table_o;

/

CREATE OR REPLACE PACKAGE idata.pkg_test

AS

PROCEDURE insert_array (p_array IN test_table_a);

PROCEDURE insert_object (

p_number IN NUMBER,

p_string IN VARCHAR2,

p_date IN DATE

);

END pkg_test;

/

CREATE OR REPLACE PACKAGE BODY idata.pkg_test

AS

PROCEDURE insert_array (p_array IN test_table_a)

IS

BEGIN

FORALL i IN p_array.FIRST .. p_array.LAST

INSERT INTO test_table

(number_col,

string_col,

date_col

)

VALUES (TREAT (p_array (i) AS test_table_o).number_col,

TREAT (p_array (i) AS test_table_o).string_col,

TREAT (p_array (i) AS test_table_o).date_col

);

END;

PROCEDURE insert_object (

p_number IN NUMBER,

p_string IN VARCHAR2,

p_date IN DATE

)

IS

BEGIN

INSERT INTO test_table

VALUES (p_number, p_string, p_date);

END;

END pkg_test;

/


Thực thi đoạn mã Java sau để thực hiện test.

Bạn tăng dần biến count_object từ 10 lên 100, rồi tới 1000 … để kiểm tra sự thay đổi về tốc độ thực thi của đoạn mã cập nhật sử dụng mãng và cập nhật lần lượt từng đối tượng.


package testoraclearray;


import java.sql.CallableStatement;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import oracle.jdbc.OracleDriver;


/**

* @company WWW.BEGIN.VN

* @author Le Duc Tam

*/

public class Main {

public static void main(String[] args) {


int count_object = 100;

Connection conn = null;

try {

if (conn == null) {

DriverManager.registerDriver(new OracleDriver());

conn = DriverManager.getConnection(

"jdbc:oracle:thin:@localhost:1521:ORADB",

"idata", "idata");

}


//ARRAY

long l1 = new java.util.Date().getTime();

Object[][] binDetails = new Object[count_object][3];


for (int i = 0; i <>

java.sql.Timestamp tstamp = new java.sql.Timestamp(new java.util.Date().getTime());

binDetails[i][0] = i;

binDetails[i][1] = "www.begin.vn";

binDetails[i][2] = tstamp;

}


oracle.sql.ARRAY demo_array = new oracle.sql.ARRAY(new oracle.sql.ArrayDescriptor("TEST_TABLE_A", conn), conn, binDetails);


CallableStatement cs = conn.prepareCall("{call pkg_test.insert_array(?)}");

cs.setArray(1, demo_array);

cs.execute();

long l2 = new java.util.Date().getTime();

//conn.close();

System.out.println("Execution Time Array:" + (l2 - l1));


//if (conn == null || conn.isClosed()) {

//DriverManager.registerDriver(new OracleDriver());

//conn = DriverManager.getConnection(

//"jdbc:oracle:thin:@localhost:1521:ORADB",

//"idata", "idata");

//}

//OBJECTS

long l3 = new java.util.Date().getTime();

CallableStatement cso = conn.prepareCall("{call pkg_test.insert_object(?,?,?)}");

for (int m = 0; m <>

cso.setInt(1, m);

cso.setString(2, "www.begin.vn");

//cso.setTimestamp(3, (Timestamp)binDetails[m][2]);

cso.setTimestamp(3, new java.sql.Timestamp(new java.util.Date().getTime()));

cso.execute();

}

long l4 = new java.util.Date().getTime();

System.out.println("Execution Time Object:" + (l4 - l3));


conn.close();

} catch (SQLException e) {

System.out.println(e.toString());

}

}

}


Xem ra thời gian thực thi của Array càng lúc càng nhanh hơn khi count_object càng lúc càng tăng lên.

Ví dụ khi mình để cơ sở dữ liệu trên localhost với ứng dụng và đặt count_object = 100.000 thì có kết quả như sau:

Execution Time Array:3250

Execution Time Object:110375


Nhanh hơn gấp 33 lần!


Mã nguồn chương trình chi tiết ở link dưới đây:

http://cid-60a6680ce5dc0825.office.live.com/self.aspx/Programing/TestOracleARRAY.rar

Thành phố Hồ Chí Minh, ngày 19 tháng 9 năm 2010

Lê Đức Tâm

No comments: