注入spring jdbc,参见:http://godandghost.iteye.com/admin/blogs/1724763
1. 存储过程中各个出入参都是基本类型时:
PROCEDURE p_get_province
(
iv_code VARCHAR2, --字符串类型
in_staff_role NUMBER, --数字类型
in_provincial_id NUMBER,
iv_m_id VARCHAR2,
ocur_exec_status OUT pkg_ref_cursor.gcur_record_set, --游标类型
ocur_province OUT pkg_ref_cursor.gcur_record_set --游标类型
);
public static List getProvice(final Map<String, String> paramMap) throws Exception
{
try {
List list = template.execute(new ConnectionCallback<List>()
{
@Override
public List doInConnection(Connection conn)
throws SQLException, DataAccessException
{
CallableStatement call = conn.prepareCall("call p_get_province(?,?,?,?,?,?)");
call.setString("iv_code", paramMap.get("Report_Id"));
if (StringUtils.isNotBlank(paramMap.get("Role"))) {
call.setInt("in_staff_role", Integer.parseInt(paramMap.get("Role")));
} else {
call.setString("in_staff_role", null);
}
if (StringUtils.isNotBlank(paramMap.get("ProvinceId"))) {
call.setInt("in_provincial_id", Integer.parseInt(paramMap.get("ProvinceId")));
} else {
call.setString("in_provincial_id", null);
}
call.setString("iv_m_id", paramMap.get("mId"));
call.registerOutParameter("ocur_exec_status", OracleTypes.CURSOR);
call.registerOutParameter("ocur_province", OracleTypes.CURSOR);
DataSourceUtils.applyTimeout(call, template.getDataSource(), 30);// 30秒超时
call.execute();
ResultSet rs = (ResultSet) call.getObject("ocur_exec_status");
int status = 0;
String info = "";
while (rs.next()) {
status = rs.getInt("Exec_Status");
info = rs.getString("Exec_info");
}
rs.close();
if (status == 0) {
List<MyObject> provinceList = new ArrayList<MyObject>();
ResultSet rs1 = (ResultSet) call.getObject("ocur_province");
while (rs1.next()) {
MyObject mo = new MyObject();
mo.setValue(rs1.getString("province_value"));
mo.setText(rs1.getString("province"));
provinceList.add(mo);
}
rs1.close();
return provinceList;
} else {
return null;
}
}
});
return list;
}
catch (DataAccessException e) {
throw e;
}
catch (Exception e) {
throw e;
}
}
2.存储过程中有自定义struct时
Struct类型声明:
CREATE OR REPLACE TYPE header_struct as object
(
w_id varchar2(8),
a_time date,
b_time date,
token varchar2(20)
)
create or replace type Report_List as varray(2000) of REPORT_STRUCT
create or replace type REPORT_STRUCT as object(
REQUEST_ID NUMBER(10),
STATUS NUMBER(3),
FILENAME VARCHAR2(200),
DESCRIPTION VARCHAR2(201),
REQUESTDATETIME DATE
)
CREATE OR REPLACE TYPE ERROR_MESSAGE_STRUCT as object
(
error_type number(3),
error_code number(10),
message varchar2(255)
)
存储过程声明:
CREATE OR REPLACE PROCEDURE get_report_list
(
iv_header IN header_struct,
iv_function_name IN VARCHAR2,
iv_report_date IN DATE,
ov_report_list OUT report_list,
ov_error_message OUT error_message_struct
)
Java代码写法:
public static Object[] getReportResultList(final Header header,
final String functionName, final Date dateTime)
{
try {
return template.execute(new ConnectionCallback<Object[]>()
{
@Override
public Object[] doInConnection(Connection conn) throws SQLException, DataAccessException
{
Connection con = conn.getMetaData().getConnection();// 此处需要将connection类型转换一下
OracleCallableStatement call = (OracleCallableStatement) con
.prepareCall("call get_report_list(?,?,?,?,?)");
// 存储过程第一个参数
oracle.sql.STRUCT headerStruct = getHeaderStruct(header, con);
// 声明存储过程的入参
call.setSTRUCT(1, headerStruct);// 参数类型是Struct
call.setString(2, functionName);// 参数类型是String
call.setDate(3, dateTime);
// 声明存储过程的出参
call.registerOutParameter(4, OracleTypes.ARRAY, "REPORT_LIST");// REPORT_LIST必须大写
call.registerOutParameter(5, OracleTypes.STRUCT, "ERROR_MESSAGE_STRUCT");// ERROR_MESSAGE_STRUCT必须大写
DataSourceUtils.applyTimeout(call, sbcTemplate.getDataSource(), 30);
call.execute();
// 出参第一个结构体是一个Struct的Array
oracle.sql.ARRAY array = call.getARRAY(4);
List<ReportResult> resultList = new ArrayList<ReportResult>();
if (array != null) {
Datum[] data = array.getOracleArray();
for (Datum datum : data) {
STRUCT struct = (STRUCT) datum;
Datum[] datas = struct.getOracleAttributes();
int requestId = 0;
int status = 0;
String fileName = "";
String description = "";
NUMBER requestIdNum = (NUMBER) datas[0];
if (requestIdNum != null) {
requestId = requestIdNum.bigIntegerValue().intValue();
}
NUMBER statusNum = (NUMBER) datas[1];
if (statusNum != null) {
status = statusNum.bigIntegerValue().intValue();
}
try {
if (datas[2] != null) {
fileName = new String(datas[2].getBytes(), "GBK");
}
if (datas[3] != null) {
description = new String(datas[3].getBytes(), "GBK");
}
}
catch (UnsupportedEncodingException e) {
logger.warn("不支持的字符编码", e);
}
oracle.sql.DATE requestDate = (oracle.sql.DATE) datas[4];
java.sql.Timestamp date = null;
if (requestDate != null) {
date = requestDate.timestampValue();
}
ReportResult rr = new ReportResult(requestId,
status, fileName, description, date);
resultList.add(rr);
}
} else {
System.out.println("空");
}
// 第二个结构体errormessage
STRUCT errorMsgStruct = call.getSTRUCT(5);
ErrorMessage em = new ErrorMessage();
if (errorMsgStruct != null) {
em = initErrorMessage(errorMsgStruct);
}
con.close();
return new Object[] { resultList, em };
}
});
}
catch (Exception e) {
throw e;
}
}
private static STRUCT getHeaderStruct(Header header, Connection con)
throws SQLException
{
java.sql.Timestamp aTime = null;
java.sql.Timestamp bTime = null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
java.util.Date aTimeUtil = sdf.parse(header.getaTime());
aTime = new java.sql.Timestamp(aTimeUtil.getTime());
}
catch (ParseException e) {
logger.note("aTime时间转换发生错误", e);
}
try {
java.util.Date bTimeUtil = sdf.parse(header.getbTime());
bTime = new java.sql.Timestamp(bTimeUtil.getTime());
}
catch (ParseException e) {
logger.note("bTime时间转换发生错误", e);
}
Object[] head = { header.getWitnessID(), bTime, aTime,
header.getToken() };
oracle.sql.StructDescriptor headerDesc = oracle.sql.StructDescriptor.createDescriptor("HEADER_STRUCT", con);// HEADER_STRUCT必须大写
oracle.sql.STRUCT headerStruct = new oracle.sql.STRUCT(headerDesc, con, head);
return headerStruct;
}
private static ErrorMessage initErrorMessage(STRUCT errorMsgStruct)
{
try {
Datum[] datas = errorMsgStruct.getOracleAttributes();
int errorType = 0;
int errorCode = 0;
String errorMsg = "";
NUMBER errorTypeNum = (NUMBER) datas[0];
if (errorTypeNum != null) {
errorType = errorTypeNum.bigIntegerValue().intValue();
}
NUMBER errorCodeNum = (NUMBER) datas[1];
if (errorCodeNum != null) {
errorCode = errorCodeNum.bigIntegerValue().intValue();
}
try {
if (datas[2] != null) {
errorMsg = new String(datas[2].getBytes(), "GBK");
}
}
catch (UnsupportedEncodingException e) {
logger.warn("不支持的字符编码", e);
}
ErrorMessage em = new ErrorMessage(errorCode, errorType, errorMsg);
return em;
}
catch (SQLException e) {
return null;
}
}
需要注意的是,oracle的驱动包与字符集包必须对应,否则一旦Struct结构体中有字符串(无论是不是中文)都是乱码,导致Struct结构体初始化失败。我用的oracle驱动包是ojdbc6.jar,就必须用与其对应的orai18n.jar。关于乱码问题可以参见:http://blog.csdn.net/hzw2312/article/details/8444462
另注:
当使用Connection con = conn.getMetaData().getConnection();转换数据库连接时,此连接相当于新建了一个连接,不受Spring JDBC控制,不会自动回收。所以在程序最后需要手动关闭:con.close();
分享到:
相关推荐
Spring JDBC是Spring框架的一个核心模块,它为Java数据库连接(JDBC)提供了一种抽象层,使得开发者可以更轻松地处理数据库操作。Spring JDBC模块的主要目标是减少对JDBC API的直接依赖,通过提供一种更加高级、易于...
"Spring JDBC入门 - SangS - 博客园.url" 和 "SpringJdbc的几种不同的用法 - 低调开发 - ITeye技术网站.url" 可能包含了一些关于如何使用SpringJDBC的基本教程和高级技巧,包括批处理操作、动态SQL和自定义SQL查询等...
6. **JDBC 模板扩展**:除了 JdbcTemplate,Spring 还提供了一个更高级的接口——SimpleJdbcInsert 和 SimpleJdbcCall,它们分别简化了插入操作和存储过程的调用。 7. **异常处理**:Spring JDBC 把 SQL 异常翻译成...
【标题】"Spring mvc + Spring + Spring jdbc 整合 demo.rar" 提供了一个整合了Spring MVC、Spring和Spring JDBC的示例项目。这个压缩包包含了一整套使用Java EE技术栈开发的Web应用程序,主要关注于后端数据处理和...
示例代码展示了如何在Hibernate中使用JDBC调用存储过程: ```java Session session = HibernateSessionFactory.currentSession(); Connection conn = session.connection(); Transaction tx = session.begin...
Spring JDBC提供了几种不同的查询实现: - **GenericSqlQuery**:通用查询,适用于一般的SQL查询。 - **UpdatableSqlQuery**:除了返回查询结果外,还可以更新与查询结果关联的数据。 - **...
Spring JDBC是Spring框架的一部分,它提供了一种抽象层,使得我们能够更方便地使用Java的JDBC(Java Database Connectivity)来处理数据库操作。这个模块的主要目标是简化数据库访问,同时保持JDBC的强大功能,避免...
高级主题可能包括批处理、预编译的PreparedStatement、存储过程调用、事务管理、异常处理、连接池的使用以及JDBC的性能优化。 5. **JDBC 2.0核心功能和扩展**: JDBC 2.0引入了一些新特性,如CallableStatement...
本文将围绕“poi+springmvc+springjdbc导入导出excel实例”的主题,详细讲述如何使用这些技术实现数据的导入导出功能。 首先,我们需要了解这些技术的基础概念: 1. POI:Apache POI是一个开源的Java库,用于处理...
Spring bean是存储在Spring IoC容器中的Java对象,可以通过容器来配置和管理。 18、spring提供了哪些配置方式? Spring提供了以下配置方式: - 基于XML的配置 - 基于注解的配置 - 基于Java类的配置 19、spring支持...
Spring JdbcTemplate提供了一个面向对象的接口,用于执行SQL查询、更新和存储过程,避免了直接与JDBC API打交道的繁琐工作。它通过异常处理、事务管理以及结果集的自动处理,简化了数据库访问。基于注解的Spring ...
CallableStatement用于调用数据库的存储过程或函数,支持IN、OUT和IN/OUT参数。 #### 十、元数据信息 JDBC提供了获取数据库和参数元数据的机制,有助于理解数据库结构和优化查询。 #### 十一、批处理的使用 ...
### Java JDBC连接数据库代码大全详解 #### 一、JDBC基础概述 ...随着技术的发展,现代框架如Spring Data JPA等已经极大地简化了这一过程,但在理解更高层次的抽象之前,掌握JDBC的基础是非常重要的。
Spring框架以其依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented Programming,AOP)为核心特性,为开发者提供了大量的模块来处理各种任务,如数据访问、Web开发、事务管理、远程调用等。...
在Spring 1.2.6源码中,我们可以看到以下几个关键知识点: 1. **依赖注入(Dependency Injection,DI)**:这是Spring的核心功能之一,它通过反转控制来管理对象之间的依赖关系。源码中,你可以看到`BeanFactory`...
以下是几种常见的整合方式: - **窍门1. 使用Spring的ActionSupport**:Spring 提供了一种机制,可以将Struts的Action对象交给Spring进行管理。这种方式的好处是可以利用Spring的强大功能,如依赖注入、事务管理和...
Spring JDBC提供了一种抽象层,简化了数据库操作,而ORM框架则允许开发者使用面向对象的方式处理数据库交互。 6. **Spring Boot**:Spring Boot是为了简化Spring应用的初始搭建以及开发过程而诞生的。它默认配置了...
4. **几种常用数据库的驱动程序及JDBC URL**: 不同数据库的JDBC驱动和URL格式各异,如MySQL的`jdbc:mysql://`,Oracle的`jdbc:oracle:thin:`,SQL Server的`jdbc:sqlserver://`等。 **利用JDBC执行数据库操作** 1....
JDBC包括以下几个核心概念: 1. **Driver Manager**:管理所有已注册的数据库驱动,负责建立数据库连接。 2. **Connection**:代表数据库连接,通过Driver Manager获取。 3. **Statement/PreparedStatement/...
此框架旨在简化在 Hadoop 生态系统中的开发工作,提供了一种更加面向 Spring 的方式来处理 MapReduce 任务、HDFS 文件系统操作以及与 HBase 和 Hive 等数据存储系统的集成。 #### 二、Spring 和 Hadoop ##### 2.1 ...