google半天,没找到有人写者方面的,我就开个头吧。有不对的地方还请大侠们拍砖。
要点其实很简单,就是把在declareParameter时要先声明返回结果集参数,再声明input参数。
先看看程序吧:
Sybase 存储过程
代码
- IF OBJECT_ID('dbo.sp_xx') IS NOT NULL
- BEGIN
- DROP PROCEDURE dbo.sp_xx
- IF OBJECT_ID('dbo.sp_xx') IS NOT NULL
- PRINT '<<< FAILED DROPPING PROCEDURE dbo.sp_xx >>>'
- ELSE
- PRINT '<<< DROPPED PROCEDURE dbo.sp_xx >>>'
- END
- go
- create proc sp_xx ( @userid int)
- as
- begin
- select personid, personname from person where personid = @userid
-
- select teamid, teamname from team
- end
-
- EXEC sp_procxmode 'dbo.sp_xx','unchained'
- go
<script>render_code();</script>
正确的java调用程序如下
代码
- private class ProcWithResultSet extends StoredProcedure
- {
- public ProcWithResultSet(DataSource dataSource)
- {
- setDataSource(dataSource);
- setSql("sp_xx");
-
-
-
- declareParameter(new SqlReturnResultSet("rsPerson", new PersonRowMapper()));
-
- declareParameter(new SqlReturnResultSet("rsTeam", new TeamRowMapper()));
-
- declareParameter(new SqlParameter("userid", java.sql.Types.INTEGER));
-
- compile();
- }
-
- public Map getRsFromSP(int userID)
- {
-
- Map map = new HashMap();
- map.put("userid", new Integer(userID));
- return execute(map);
- }
- }
-
- private class PersonRowMapper implements RowMapper
- {
- public Object mapRow(ResultSet rs, int rowNum) throws SQLException
- {
- UserInfo u = new UserInfo();
- u.setPersonID(rs.getInt(1));
- u.setUserName(rs.getString(2));
- return u;
- }
- }
- private class TeamRowMapper implements RowMapper
- {
- public Object mapRow(ResultSet rs, int rowNum) throws SQLException
- {
- return new PropertyValue(rs.getInt(1)+"", rs.getString(2));
- }
- }
<script>render_code();</script>
Spring中对于jdbc 调用带有返回结果集的存储过程是用的这个方法。
代码
-
-
-
-
-
-
- protected Map extractReturnedResultSets(CallableStatement cs, List parameters, int updateCount)
- throws SQLException {
-
- Map returnedResults = new HashMap();
- int rsIndex = 0;
- boolean moreResults;
- do {
- if (updateCount == -1) {
- Object param = null;
- if (parameters != null && parameters.size() > rsIndex) {
- param = parameters.get(rsIndex);
- }
- if (param instanceof SqlReturnResultSet) {
- SqlReturnResultSet rsParam = (SqlReturnResultSet) param;
- returnedResults.putAll(processResultSet(cs.getResultSet(), rsParam));
- }
- else {
- logger.warn("Results returned from stored procedure but a corresponding " +
- "SqlOutParameter/SqlReturnResultSet parameter was not declared");
- }
- rsIndex++;
- }
- moreResults = cs.getMoreResults();
- updateCount = cs.getUpdateCount();
- if (logger.isDebugEnabled()) {
- logger.debug("CallableStatement.getUpdateCount() returned " + updateCount);
- }
- }
- while (moreResults || updateCount != -1);
- return returnedResults;
- }
<script>render_code();</script>
原因分析:
1:Sybase不支持Out 参数返回结果集。只能再Sp当中最后select column from some table
2:Sybase的JDBC Driver对于jdbc的实现比较令人费解,如果一个Sp返回多个结果集,如果不调用第一个结果集即statement.getResultSet()
那么接下来statementcs.getMoreResults()会返回False,即使有有第二个返回结果集,它一样返回false,那么Spring就会把返回结果认为是一个update的
结果,就不会对其它结果集进行处理。
3:Spring中如果jdbc返回结果集,那么程序会执行到(3)处,这里rsIndex = 0,如果输入参数声明在先,那么这里得到的将会是输入参数,
(5)处的cs.getResultSet()将不会被执行,第一个ResultSet不会被处理,同时,因为(5)处没有被执行,那么(6)处会返回false,也就是解下来
的结果集不会被正确的认出来,Spring也不会去处理后续的结果集,这样就一个结果集也得不到了。
4:这里主要还是Sybase jdbcDriver在实现jdbc时有bug,但是我们只能顺着人家来,在用Spring Jdbctemplate调用时注意一下了。
|
相关推荐
存储过程使用 `SYS_REFCURSOR` 输出参数将结果集返回给调用方。 `P_EMP_ADD` 存储过程用于添加新员工信息,并返回添加结果。该过程接收两个输入参数:`V_ID` 和 `V_NAME`,分别用于添加员工 ID 和姓名。存储过程...
Spring JDBC Template提供了诸如事务管理、异常转换和结果集处理等高级功能,使开发者能更专注于业务逻辑,而不是底层数据库操作。 接下来是MySQL,这是一个广泛使用的开源关系型数据库管理系统(RDBMS)。它以其性能...
Spring JDBC Template是Spring... <artifactId>spring-jdbc <version>5.3.23 ``` 接下来,配置Spring JDBC Template。在Spring的配置文件(如:applicationContext.xml)中,定义一个JdbcTemplate bean: ```xml ...
赠送jar包:spring-jdbc-5.3.15.jar; 赠送原API文档:spring-jdbc-5.3.15-javadoc.jar; 赠送源代码:spring-jdbc-5.3.15-sources.jar; 赠送Maven依赖信息文件:spring-jdbc-5.3.15.pom; 包含翻译后的API文档:...
开发工具 spring-jdbc-4.3.6.RELEASE开发工具 spring-jdbc-4.3.6.RELEASE开发工具 spring-jdbc-4.3.6.RELEASE开发工具 spring-jdbc-4.3.6.RELEASE开发工具 spring-jdbc-4.3.6.RELEASE开发工具 spring-jdbc-4.3.6....
在项目中使用"spring-jdbc jar包",开发者需要配置DataSource,并根据需求选择使用JdbcTemplate或其他辅助类。在编写SQL时,可以使用预编译的PreparedStatement来防止SQL注入攻击。此外,还可以利用Spring的AOP...
7. **CallableStatement**: 用于调用数据库存储过程。 8. **ResultSet**: 存储查询结果,包含多条记录,可以迭代遍历。 而Spring Data JDBC是Spring框架的一部分,它简化了数据库操作,提供了更高层次的抽象。相比...
1. **JdbcTemplate**:这是Spring JDBC的基础组件,它通过模板方法模式封装了常见的JDBC操作,如执行SQL查询、更新、存储过程等。使用JdbcTemplate,开发者无需手动管理数据库连接、预编译语句、结果集转换等细节,...
(1)使用Spring JDBC实现书店的购书过程,即有如下一个BookShopDao接口,编写BookShopDaoImp类实现该接口中的所有方法,并通过JUnit测试这些方法。 (2)(2) 在BookShopDao中添加一个purchase购书方法,其操作流程是...
这个"spring_JDBC基本包"可能包含的文件有Spring框架的基础库,如spring-jdbc.jar,数据库驱动如mysql-connector-java.jar,以及其他可能需要的依赖,如commons-dbcp或HikariCP这样的连接池库。确保所有必要的库都...
使用 Spring JDBC Template 对数据库查询(登录)和删除(maven),图文教程地址:https://blog.csdn.net/qq_40147863/article/details/86015509
使用 Spring MVC + JDBC Template 实现筛选、检索功能(maven),图文教程地址:https://blog.csdn.net/qq_40147863/article/details/86187642
使用Spring的JdbcTemplate调用Oracle的存储过程
它提供了大量的方法,用于执行SQL查询、更新、存储过程等,这些方法能够自动处理资源的关闭、异常处理以及结果集的映射。例如,我们可以通过以下方式使用JdbcTemplate执行SQL查询: ```java @Autowired private ...
在本文中,我们将深入探讨如何使用Spring JDBC进行数据库操作,并结合使用不同的连接池技术,包括Spring自带的、C3P0、DBCP和Druid。此外,我们还将介绍一个自定义的行映射器工具类,它在处理数据库查询结果时能提供...
首先,我们需要在项目中引入Spring框架的相关依赖,通常包括`spring-context`和`spring-jdbc`。这些可以在Maven或Gradle的配置文件中添加对应的依赖项。 在MySQL数据库方面,确保已经创建了一个合适的数据库和表。...
Spring JDBC是Spring框架的一个重要模块,它为Java开发者提供了与关系数据库交互的抽象层,简化了JDBC(Java Database Connectivity)的使用。本教程通过一个实际案例,将深入讲解Spring JDBC的基本概念、核心组件...
2. **JdbcTemplate**:这是Spring JDBC最常用的工具类,提供了大量的模板方法,用于执行SQL查询、更新、调用存储过程等操作,大大减少了手动处理结果集和异常的情况。 3. **SimpleJdbcTemplate**:这是JdbcTemplate...
在这个“spring_jdbc_4.0.0.zip”压缩包中,包含的是Spring JDBC 4.0.0版本的jar文件,即“spring-jdbc-4.0.0.jar”。 在Spring JDBC中,最重要的概念是`JdbcTemplate`。这是一个非常实用的工具类,它通过模板方法...