如何使用 EclipseLink 处理以 Oracle 类型作为输入或输出的 Oracle 存储过程调用
我进行了概念验证,以了解使用 EclipseLink 调用存储过程的效率如何。我能够使用带有标量/原始数据类型(链接整数、varchar 等)的 EclispeLink 来调用 Oracle 存储过程。我想了解如何使用集合(Oracle 类型/用户定义类型)作为输入或输出参数来处理来自 EclipseLink 的 Oracle Store 过程。如果有人通过一个例子帮助我理解这一点,我将非常感激。
谢谢 MAK
这是我使用游标作为输出实现的示例,我想用用户定义的 oracle 类型替换游标,这也在下面提到。使用 Eclipselink 从 Java 调用过程 get_holiday_list_type。
任何帮助我真的很感激。
主类
package services;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.platform.database.oracle.Oracle11Platform;
import org.eclipse.persistence.queries.DataReadQuery;
import org.eclipse.persistence.queries.StoredProcedureCall;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.DatabaseRecord;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.Session;
public class TestEclipseLinkJPA {
Session s;
TestEclipseLinkJPA() {
String DATABASE_USERNAME = "SD64_FIRMCONFIG";
String DATABASE_PASSWORD = "sdbaseline";
String DATABASE_URL = "jdbc:oracle:thin:@GWMPCMTD.ea:1527:GWMPCMTD";
String DATABASE_DRIVER = "oracle.jdbc.driver.OracleDriver";
DatabaseLogin login = new DatabaseLogin();
login.setUserName(DATABASE_USERNAME);
login.setPassword(DATABASE_PASSWORD);
login.setConnectionString(DATABASE_URL);
login.setDriverClassName(DATABASE_DRIVER);
login.setDatasourcePlatform(new Oracle11Platform());
((DatabaseLogin) login).bindAllParameters();
Project project = new Project(login);
s = project.createDatabaseSession();
s.setLogLevel(SessionLog.FINE);
((DatabaseSession) s).login();
}
public static void main(String args[]) {
TestEclipseLinkJPA test = new TestEclipseLinkJPA();
test.run();
}
protected void run() {
testProcCursor();
}
/*
* Run Proc with scalar input and cursor output
*/
@SuppressWarnings("unchecked")
private void testProcCursor() {
List outList = new ArrayList();
StoredProcedureCall call = new StoredProcedureCall();
call.setProcedureName("test_holiday_pkg.get_holiday_list_cur");
call.addNamedArgument("i_user_id");
call.addNamedArgument("i_hol_year");
call.useNamedCursorOutputAsResultSet("o_approvalreasonlist");
DataReadQuery query = new DataReadQuery();
query.setCall(call);
query.addArgument("i_user_id");
query.addArgument("i_hol_year");
List<Integer> queryArgs = new ArrayList<Integer>();
queryArgs.add(Integer.valueOf(50077));
queryArgs.add(Integer.valueOf(2010));
outList = (List) s.executeQuery(query, queryArgs);
ListIterator<DatabaseRecord> litr = ((List<DatabaseRecord>) outList)
.listIterator();
while (litr.hasNext()) {
DatabaseRecord record = (DatabaseRecord) litr.next();
System.out.println("Value -->" + record.get("BSNS_OBJCT_ID"));
}
}
}
对象
package dataobjects;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class KeyValuePairTo implements Serializable {
/**
*
*/
private static final long serialVersionUID = -5022039632874557887L;
@Id
@Column(name = "BSNS_OBJCT_ID")
private String key;
@Column(name = "DSCRPTN")
private String value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
过程细节
drop type obj_key_value_array2;
CREATE OR REPLACE TYPE obj_key_value2 AS OBJECT (
bsns_objct_id VARCHAR2 (15 CHAR),
dscrptn VARCHAR2 (65 CHAR)
)
/
CREATE OR REPLACE TYPE obj_key_value_array2 AS TABLE OF obj_key_value2
/
CREATE OR REPLACE PACKAGE test_holiday_pkg1
AS
PROCEDURE get_holiday_list_cur (
i_user_id IN NUMBER,
i_hol_year IN NUMBER,
o_approvalreasonlist OUT sys_refcursor
);
PROCEDURE get_holiday_list_type (
i_user_id IN NUMBER,
i_hol_year IN NUMBER,
o_approvalreasonlist OUT obj_key_value_array2
);
END test_holiday_pkg1;
/
CREATE OR REPLACE PACKAGE BODY TEST_HOLIDAY_PKG1
AS
PROCEDURE get_holiday_list_cur (
i_user_id IN NUMBER,
i_hol_year IN NUMBER,
o_approvalreasonlist OUT sys_refcursor
)
AS
BEGIN
OPEN o_approvalreasonlist FOR
SELECT to_char(BSNS_OBJCT_ID) bsns_objct_id, DSCRPTN
FROM holiday
WHERE hol_year = i_hol_year;
END get_holiday_list_cur;
PROCEDURE get_holiday_list_type (
i_user_id IN NUMBER,
i_hol_year IN NUMBER,
o_approvalreasonlist OUT obj_key_value_array2
)
AS
BEGIN
SELECT obj_key_value2 (to_char(bsns_objct_id), dscrptn)
BULK COLLECT INTO o_approvalreasonlist
FROM holiday
WHERE hol_year = i_hol_year;
END get_holiday_list_type;
END test_holiday_pkg1;
/
show errors;
I doing a Proof Of Concept to figure out how efficient to call a store procedure using EclipseLink. I was able to call oracle store procedure using EclispeLink with Scalar/primitive data types (link Integer, varchar etc). I wanted to understand how can I handle Oracle Store procedure from EclipseLink with collection(Oracle Types/User defined types) as input or output parameters. I would really appreciate if some one help me understand this with an example.
Thanks
MAK
Here is the example which I implemented using cursor as output, and I want to replace cursor with user defined oracle type which is also mention below. Call procedure get_holiday_list_type from Java using Eclipselink.
Any help I really appreciate it.
Main Class
package services;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.platform.database.oracle.Oracle11Platform;
import org.eclipse.persistence.queries.DataReadQuery;
import org.eclipse.persistence.queries.StoredProcedureCall;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.DatabaseRecord;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.Session;
public class TestEclipseLinkJPA {
Session s;
TestEclipseLinkJPA() {
String DATABASE_USERNAME = "SD64_FIRMCONFIG";
String DATABASE_PASSWORD = "sdbaseline";
String DATABASE_URL = "jdbc:oracle:thin:@GWMPCMTD.ea:1527:GWMPCMTD";
String DATABASE_DRIVER = "oracle.jdbc.driver.OracleDriver";
DatabaseLogin login = new DatabaseLogin();
login.setUserName(DATABASE_USERNAME);
login.setPassword(DATABASE_PASSWORD);
login.setConnectionString(DATABASE_URL);
login.setDriverClassName(DATABASE_DRIVER);
login.setDatasourcePlatform(new Oracle11Platform());
((DatabaseLogin) login).bindAllParameters();
Project project = new Project(login);
s = project.createDatabaseSession();
s.setLogLevel(SessionLog.FINE);
((DatabaseSession) s).login();
}
public static void main(String args[]) {
TestEclipseLinkJPA test = new TestEclipseLinkJPA();
test.run();
}
protected void run() {
testProcCursor();
}
/*
* Run Proc with scalar input and cursor output
*/
@SuppressWarnings("unchecked")
private void testProcCursor() {
List outList = new ArrayList();
StoredProcedureCall call = new StoredProcedureCall();
call.setProcedureName("test_holiday_pkg.get_holiday_list_cur");
call.addNamedArgument("i_user_id");
call.addNamedArgument("i_hol_year");
call.useNamedCursorOutputAsResultSet("o_approvalreasonlist");
DataReadQuery query = new DataReadQuery();
query.setCall(call);
query.addArgument("i_user_id");
query.addArgument("i_hol_year");
List<Integer> queryArgs = new ArrayList<Integer>();
queryArgs.add(Integer.valueOf(50077));
queryArgs.add(Integer.valueOf(2010));
outList = (List) s.executeQuery(query, queryArgs);
ListIterator<DatabaseRecord> litr = ((List<DatabaseRecord>) outList)
.listIterator();
while (litr.hasNext()) {
DatabaseRecord record = (DatabaseRecord) litr.next();
System.out.println("Value -->" + record.get("BSNS_OBJCT_ID"));
}
}
}
Object
package dataobjects;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class KeyValuePairTo implements Serializable {
/**
*
*/
private static final long serialVersionUID = -5022039632874557887L;
@Id
@Column(name = "BSNS_OBJCT_ID")
private String key;
@Column(name = "DSCRPTN")
private String value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Procedure details
drop type obj_key_value_array2;
CREATE OR REPLACE TYPE obj_key_value2 AS OBJECT (
bsns_objct_id VARCHAR2 (15 CHAR),
dscrptn VARCHAR2 (65 CHAR)
)
/
CREATE OR REPLACE TYPE obj_key_value_array2 AS TABLE OF obj_key_value2
/
CREATE OR REPLACE PACKAGE test_holiday_pkg1
AS
PROCEDURE get_holiday_list_cur (
i_user_id IN NUMBER,
i_hol_year IN NUMBER,
o_approvalreasonlist OUT sys_refcursor
);
PROCEDURE get_holiday_list_type (
i_user_id IN NUMBER,
i_hol_year IN NUMBER,
o_approvalreasonlist OUT obj_key_value_array2
);
END test_holiday_pkg1;
/
CREATE OR REPLACE PACKAGE BODY TEST_HOLIDAY_PKG1
AS
PROCEDURE get_holiday_list_cur (
i_user_id IN NUMBER,
i_hol_year IN NUMBER,
o_approvalreasonlist OUT sys_refcursor
)
AS
BEGIN
OPEN o_approvalreasonlist FOR
SELECT to_char(BSNS_OBJCT_ID) bsns_objct_id, DSCRPTN
FROM holiday
WHERE hol_year = i_hol_year;
END get_holiday_list_cur;
PROCEDURE get_holiday_list_type (
i_user_id IN NUMBER,
i_hol_year IN NUMBER,
o_approvalreasonlist OUT obj_key_value_array2
)
AS
BEGIN
SELECT obj_key_value2 (to_char(bsns_objct_id), dscrptn)
BULK COLLECT INTO o_approvalreasonlist
FROM holiday
WHERE hol_year = i_hol_year;
END get_holiday_list_type;
END test_holiday_pkg1;
/
show errors;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
也许看看用于存储过程查询的EclipseLink扩展。请注意,JPA 扩展显然不可移植,就像 Oracle 特定类型一样(因此这两次击败了 JPA)。
Maybe have a look at the EclipseLink extensions for Stored Procedure Query. Note that JPA extensions are obviously not portable, like oracle specific types (so this defeats JPA twice).