【问题标题】:MyBatis Springs Oracle Stored ProcedureMyBatis Springs Oracle 存储过程
【发布时间】:2016-10-15 10:17:06
【问题描述】:

我一直在使用 MyBatis 开发 Spring 应用程序:

假设我有一个 Oracle 存储过程:

CREATE OR REPLACE PROCEDURE getDBUSERByUserId(
     p_userid IN DBUSER.USER_ID INTEGER,
     o_username OUT DBUSER.USERNAME VARCHAR,
     o_createdby OUT  DBUSER.CREATED_BY VARCHAR, 
     o_date OUT DBUSER.CREATED_DATE DATE)
IS 
BEGIN
   SELECT USERNAME , CREATED_BY, CREATED_DATE
   INTO o_username, o_createdby,  o_date
   from  DBUSER WHERE USER_ID = p_userid;
END

对于上面的SP我写了如下mapper.xml:

<mapper namespace="UserDetails">
  <resultMap id="getDbUserDetails" type="map">
    <result property="p_userid" column="INTEGER" />
    <result property="o_username" column="VARCHAR" />
    <result property="o_createdby" column="VARCHAR" />
    <result property="o_date" column="VARCHAR" />
  </resultMap>

  <select id="getDbUserByUserId" resultMap="getDbUserDetails" parameterType="map" statementType="CALLABLE">
        { call getDBUSERByUserId(
           #{p_userid,jdbcType=INTEGER,mode=IN},
           #{o_username,jdbcType=VARCHAR,mode=OUT},
           #{o_createdby,jdbcType=VARCHAR,mode=OUT},
           #{o_date,jdbcType=VARCHAR,mode=OUT})
         }
  </select>
</mapper>

调用该SP对应的Java代码:

public Map<String, Object> getUserDetails() {

  Map<String, Object> parametersMap = new HashMap<String, Object>();
  parametersMap.put(p_userid,"XYZ-123");
  parametersMap.put(o_username,"Tom74");
  parametersMap.put(o_createdby,"Maverick");
  parametersMap.put(o_date,new Date());

  getSqlSession().selectList("UserDetails.getDbUserByUserId", parametersMap);

  System.out.println(parametersMap);

  return parametersMap;
}

在执行时抛出异常:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.IncompleteElementException: Could not find result map java.lang.String
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:364)
    at com.sun.proxy.$Proxy7.selectList(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:194)
    at com.bt.cmps.kci_services.dao.NotificationDaoImplV10.getKcis(NotificationDaoImplV10.java:252)
    at com.bt.kci_services.services.NotificationServiceImplV10.getKcis(NotificationServiceImplV10.java:208)
    at com.bt.kci_services.services.NotificationProcessorImplV10.getKcis(NotificationProcessorImplV10.java:106)
    at com.bt.kci_services.services.test.NotificationProcessorImplV10Test.testGetKcisForOnlyCustId(NotificationProcessorImplV10Test.java:103)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at junit.framework.TestCase.runTest(TestCase.java:154)
    at org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests.runManaged(AbstractJUnit38SpringContextTests.java:334)
    at org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests.access$0(AbstractJUnit38SpringContextTests.java:326)
    at org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests$1.run(AbstractJUnit38SpringContextTests.java:216)
    at org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests.runTest(AbstractJUnit38SpringContextTests.java:296)
    at org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests.runTestTimed(AbstractJUnit38SpringContextTests.java:253)
    at org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests.runBare(AbstractJUnit38SpringContextTests.java:213)
    at junit.framework.TestResult$1.protect(TestResult.java:106)
    at junit.framework.TestResult.runProtected(TestResult.java:124)
    at junit.framework.TestResult.run(TestResult.java:109)
    at junit.framework.TestCase.run(TestCase.java:118)
    at junit.framework.TestSuite.runTest(TestSuite.java:208)
    at junit.framework.TestSuite.run(TestSuite.java:203)
    at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:131)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.apache.ibatis.builder.IncompleteElementException: Could not find result map java.lang.String
    at org.apache.ibatis.builder.MapperBuilderAssistant.setStatementResultMap(MapperBuilderAssistant.java:373)
    at org.apache.ibatis.builder.MapperBuilderAssistant.addMappedStatement(MapperBuilderAssistant.java:311)
    at org.apache.ibatis.builder.xml.XMLStatementBuilder.parseStatementNode(XMLStatementBuilder.java:109)
    at org.apache.ibatis.session.Configuration.buildAllStatements(Configuration.java:698)
    at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:629)
    at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:624)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:103)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:98)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:354)
Caused by: java.lang.IllegalArgumentException: Result Maps collection does not contain value for java.lang.String
    at org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:791)
    at org.apache.ibatis.session.Configuration.getResultMap(Configuration.java:550)
    at org.apache.ibatis.builder.MapperBuilderAssistant.setStatementResultMap(MapperBuilderAssistant.java:371)

我在谷歌上搜索了很多关于这个问题的信息,但似乎没有任何帮助。 我是 MyBatis 的新手,因此我们将不胜感激。 我正在使用 mybatis-3.2.3。

提前谢谢..!!!

【问题讨论】:

    标签: java oracle stored-procedures mybatis spring-mybatis


    【解决方案1】:

    你不应该在你的 hashMap 中指定参数。你应该写类似

    .selectOne("test.testOutput", 参数);

    public Map<String, Object> getUserDetails() {
    
      Map<String, Object> parametersMap = new HashMap<String, Object>();
      parametersMap.put(p_userid,"XYZ-123");
    
      getSqlSession().selectOne("UserDetails.getDbUserByUserId", parametersMap);
    
      System.out.println(parametersMap);
    
      return parametersMap;
    }
    

    【讨论】:

      【解决方案2】:

      我不同意 @Michael Piankov 关于问题的根源:我刚刚检查了 parameterMap 是否包含 OUT 的键/值没有区别参数。

      我在尝试执行您的代码时遇到了一些问题。 无法重现相同的异常,无论如何还是有一些提示:

      • 您根本不需要结果映射,因为所有映射都在过程调用中完成。

      • 参数p_userid 的预期值必须可转换整数,“XYZ-123”不是。

      • OUT 参数 o_date 被声明为 DATE 但映射为 jdbcType=VARCHAR,它可能会与其他类型产生问题。

      • 最后我有以下工作:

      -存储过程:

      CREATE OR REPLACE PROCEDURE getDBUSERByUserId(
          p_userid IN INTEGER,
          o_username OUT VARCHAR2,
          o_createdby OUT VARCHAR2,
          o_date OUT DATE)
      IS
      BEGIN
        SELECT 'USERNAME' , 'CREATED_BY', CURRENT_DATE
        INTO o_username, o_createdby, o_date
        FROM dual ;
      END;
      

      -映射器:

      <select id="getDbUserByUserId" resultMap="getDbUserDetails" parameterType="map" statementType="CALLABLE">
              { call getDBUSERByUserId(
                 #{p_userid,jdbcType=INTEGER,mode=IN},
                 #{o_username,jdbcType=VARCHAR,mode=OUT},
                 #{o_createdby,jdbcType=VARCHAR,mode=OUT},
                 #{o_date,jdbcType=VARCHAR,mode=OUT})
               }
      </select>
      

      -Java:

      SqlSession session = sessionFactory.openSession();
      
      Map<String, Object> parametersMap = new HashMap<String, Object>();
      parametersMap.put("p_userid",123);
      parametersMap.put("o_username",null);
      parametersMap.put("o_createdby",null);
      parametersMap.put("o_date",null);
      
      session.selectOne("getDbUserByUserId", parametersMap);
      System.out.println(parametersMap);
      

      【讨论】:

        猜你喜欢
        • 2014-05-26
        • 2013-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-27
        • 2011-01-03
        • 2011-12-29
        相关资源
        最近更新 更多