`
fengpeng
  • 浏览: 103098 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用Spring jdbc template调用Sybase带有返回结果集的储存过程-要点

阅读更多
关键字: Spring   spring    

google半天,没找到有人写者方面的,我就开个头吧。有不对的地方还请大侠们拍砖。
要点其实很简单,就是把在declareParameter时要先声明返回结果集参数,再声明input参数。

先看看程序吧:
Sybase 存储过程

代码
  1. IF OBJECT_ID('dbo.sp_xx') IS NOT NULL   
  2. BEGIN   
  3.     DROP PROCEDURE dbo.sp_xx   
  4.     IF OBJECT_ID('dbo.sp_xx') IS NOT NULL   
  5.         PRINT '<<< FAILED DROPPING PROCEDURE dbo.sp_xx >>>'   
  6.     ELSE   
  7.         PRINT '<<< DROPPED PROCEDURE dbo.sp_xx >>>'   
  8. END   
  9. go   
  10. create proc sp_xx ( @userid int)    
  11. as   
  12. begin   
  13.     select personid, personname from person where personid = @userid  
  14.        
  15.     select teamid, teamname from team   
  16. end   
  17.   
  18. EXEC sp_procxmode 'dbo.sp_xx','unchained'   
  19. go   
<script>render_code();</script>
正确的java调用程序如下
代码
  1. private class ProcWithResultSet extends StoredProcedure   
  2. {   
  3.     public ProcWithResultSet(DataSource dataSource)   
  4.     {   
  5.         setDataSource(dataSource);   
  6.         setSql("sp_xx");   
  7.                
  8.         //declareParameter(new SqlParameter("userid", java.sql.Types.INTEGER));              //(1)   
  9.         //declare the first out param in the sp, the name rsPerson is the key of result map   
  10.         declareParameter(new SqlReturnResultSet("rsPerson"new PersonRowMapper()));   
  11.         //declare the second out param in the sp, the name rsTeam is the key of result map   
  12.         declareParameter(new SqlReturnResultSet("rsTeam"new TeamRowMapper()));   
  13.     //declare input params, the name userid is the IN params of the param   
  14.         declareParameter(new SqlParameter("userid", java.sql.Types.INTEGER));                //(2)   
  15.            
  16.         compile();   
  17.     }   
  18.        
  19.     public Map getRsFromSP(int userID)   
  20.     {   
  21.            
  22.         Map map = new HashMap();   
  23.         map.put("userid"new Integer(userID));   
  24.         return execute(map);   
  25.     }   
  26. }   
  27.   
  28. private class PersonRowMapper implements RowMapper    
  29. {   
  30. public Object mapRow(ResultSet rs, int rowNum) throws SQLException   
  31. {   
  32.     UserInfo u = new UserInfo();   
  33.     u.setPersonID(rs.getInt(1));   
  34.     u.setUserName(rs.getString(2));   
  35.     return u;   
  36. }   
  37. }   
  38. private class TeamRowMapper implements RowMapper    
  39. {   
  40. public Object mapRow(ResultSet rs, int rowNum) throws SQLException   
  41. {   
  42.     return new PropertyValue(rs.getInt(1)+"", rs.getString(2));   
  43. }      
  44. }   
<script>render_code();</script>
Spring中对于jdbc 调用带有返回结果集的存储过程是用的这个方法。
代码
  1.  /**  
  2.  * Extract returned ResultSets from the completed stored procedure.  
  3.  * @param cs JDBC wrapper for the stored procedure  
  4.  * @param parameters Parameter list for the stored procedure  
  5.  * @return Map that contains returned results  
  6.  */  
  7. protected Map extractReturnedResultSets(CallableStatement cs, List parameters, int updateCount)   
  8.         throws SQLException {   
  9.   
  10.     Map returnedResults = new HashMap();   
  11.     int rsIndex = 0;             
  12.     boolean moreResults;   
  13.     do {   
  14.         if (updateCount == -1) {                 //(3)   
  15.             Object param = null;   
  16.             if (parameters != null && parameters.size() > rsIndex) {   
  17.                 param = parameters.get(rsIndex);     //(4)   
  18.             }   
  19.             if (param instanceof SqlReturnResultSet) {   
  20.                 SqlReturnResultSet rsParam = (SqlReturnResultSet) param;   
  21.                 returnedResults.putAll(processResultSet(cs.getResultSet(), rsParam)); //(5)   
  22.             }   
  23.             else {   
  24.                 logger.warn("Results returned from stored procedure but a corresponding " +   
  25.                         "SqlOutParameter/SqlReturnResultSet parameter was not declared");   
  26.             }   
  27.             rsIndex++;   
  28.         }   
  29.         moreResults = cs.getMoreResults();           //(6)   
  30.         updateCount = cs.getUpdateCount();   
  31.         if (logger.isDebugEnabled()) {   
  32.             logger.debug("CallableStatement.getUpdateCount() returned " + updateCount);   
  33.         }   
  34.     }   
  35.     while (moreResults || updateCount != -1);   
  36.     return returnedResults;   
  37. }   
<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调用时注意一下了。

分享到:
评论

相关推荐

    Spring JdbcTemplate调用Oracle存储过程实现CRUD

    存储过程使用 `SYS_REFCURSOR` 输出参数将结果集返回给调用方。 `P_EMP_ADD` 存储过程用于添加新员工信息,并返回添加结果。该过程接收两个输入参数:`V_ID` 和 `V_NAME`,分别用于添加员工 ID 和姓名。存储过程...

    Spring boot+Spring JDBC Template+mysql+ sharding-j-subdb.zip

    Spring JDBC Template提供了诸如事务管理、异常转换和结果集处理等高级功能,使开发者能更专注于业务逻辑,而不是底层数据库操作。 接下来是MySQL,这是一个广泛使用的开源关系型数据库管理系统(RDBMS)。它以其性能...

    使用spring jdbc template简化jdbc数据库操作实例代码

    Spring JDBC Template是Spring... &lt;artifactId&gt;spring-jdbc &lt;version&gt;5.3.23 ``` 接下来,配置Spring JDBC Template。在Spring的配置文件(如:applicationContext.xml)中,定义一个JdbcTemplate bean: ```xml ...

    spring-jdbc-5.3.15-API文档-中文版.zip

    赠送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.RELEASE开发工具 spring-jdbc-4.3.6....

    spring-jdbc jar包.rar

    在项目中使用"spring-jdbc jar包",开发者需要配置DataSource,并根据需求选择使用JdbcTemplate或其他辅助类。在编写SQL时,可以使用预编译的PreparedStatement来防止SQL注入攻击。此外,还可以利用Spring的AOP...

    Spring Data JDBC与JDBC的区别

    7. **CallableStatement**: 用于调用数据库存储过程。 8. **ResultSet**: 存储查询结果,包含多条记录,可以迭代遍历。 而Spring Data JDBC是Spring框架的一部分,它简化了数据库操作,提供了更高层次的抽象。相比...

    spring对jdbc的支持jar包

    1. **JdbcTemplate**:这是Spring JDBC的基础组件,它通过模板方法模式封装了常见的JDBC操作,如执行SQL查询、更新、存储过程等。使用JdbcTemplate,开发者无需手动管理数据库连接、预编译语句、结果集转换等细节,...

    Spring JDBC与事务管理

    (1)使用Spring JDBC实现书店的购书过程,即有如下一个BookShopDao接口,编写BookShopDaoImp类实现该接口中的所有方法,并通过JUnit测试这些方法。 (2)(2) 在BookShopDao中添加一个purchase购书方法,其操作流程是...

    spring_JDBC整合包

    这个"spring_JDBC基本包"可能包含的文件有Spring框架的基础库,如spring-jdbc.jar,数据库驱动如mysql-connector-java.jar,以及其他可能需要的依赖,如commons-dbcp或HikariCP这样的连接池库。确保所有必要的库都...

    使用 Spring JDBC Template 对数据库查询(登录)和删除(maven)

    使用 Spring JDBC Template 对数据库查询(登录)和删除(maven),图文教程地址:https://blog.csdn.net/qq_40147863/article/details/86015509

    使用 Spring MVC + JDBC Template 实现筛选、检索功能(maven)

    使用 Spring MVC + JDBC Template 实现筛选、检索功能(maven),图文教程地址:https://blog.csdn.net/qq_40147863/article/details/86187642

    使用Spring的JdbcTemplate调用Oracle的存储过程

    使用Spring的JdbcTemplate调用Oracle的存储过程

    spring jdbc.zip

    它提供了大量的方法,用于执行SQL查询、更新、存储过程等,这些方法能够自动处理资源的关闭、异常处理以及结果集的映射。例如,我们可以通过以下方式使用JdbcTemplate执行SQL查询: ```java @Autowired private ...

    使用Spring JDBC 案例

    在本文中,我们将深入探讨如何使用Spring JDBC进行数据库操作,并结合使用不同的连接池技术,包括Spring自带的、C3P0、DBCP和Druid。此外,我们还将介绍一个自定义的行映射器工具类,它在处理数据库查询结果时能提供...

    spring jdbc Templatetest 访问mysql数据库,批量插入数据

    首先,我们需要在项目中引入Spring框架的相关依赖,通常包括`spring-context`和`spring-jdbc`。这些可以在Maven或Gradle的配置文件中添加对应的依赖项。 在MySQL数据库方面,确保已经创建了一个合适的数据库和表。...

    SpringJDBC.rar_SpringJDBC_spring jdbc

    Spring JDBC是Spring框架的一个重要模块,它为Java开发者提供了与关系数据库交互的抽象层,简化了JDBC(Java Database Connectivity)的使用。本教程通过一个实际案例,将深入讲解Spring JDBC的基本概念、核心组件...

    SpringJDBC.rar_jdbc spring_spring jd_spring jdbc_spring使用JDBC进行数

    2. **JdbcTemplate**:这是Spring JDBC最常用的工具类,提供了大量的模板方法,用于执行SQL查询、更新、调用存储过程等操作,大大减少了手动处理结果集和异常的情况。 3. **SimpleJdbcTemplate**:这是JdbcTemplate...

    Spring JDBC相关jar包:spring_jdbc_4.0.0.zip

    在这个“spring_jdbc_4.0.0.zip”压缩包中,包含的是Spring JDBC 4.0.0版本的jar文件,即“spring-jdbc-4.0.0.jar”。 在Spring JDBC中,最重要的概念是`JdbcTemplate`。这是一个非常实用的工具类,它通过模板方法...

Global site tag (gtag.js) - Google Analytics