如何在Java中使用SimpleJdbcCall读取空号,Spring?

时间:2016-07-26 18:12:21

标签: java spring

我有SimpleJdbcCall的问题。数字列中有一个空值,当我试图通过存储过程查询它时,我得到了NumberFormatException。

我有一个具有这种结构的表:

 COLUMN_NAME     DATA_TYPE
 -----------------------------
 USER_ID        NUMBER
 LOGIN          VARCHAR2(30 CHAR)
 PASSWORD       VARCHAR2(60 BYTE)
 NAME           VARCHAR2(30 CHAR)
 RATING         NUMBER(1,1)

我正在尝试查询一条记录:

USER_ID    LOGIN        PASSWORD        NAME            RATING
----------------------------------------------------------------
1          TestLogin    TestPassword    TestName        null

这是我的程序:

create or replace procedure get_user_by_login

                               (p_login in number,
                                p_password out varchar2,
                                p_name out varchar2,
                                p_rating out number)
  as

  begin

    select password, name, rating
      into p_password, p_name, p_rating
      from users_test
      where login = p_login;

  end;
/

这是我的代码:

public class Main
{

    public static void main(String[] args) {
        User user = getUserByLogin("TestLogin");

        System.out.println(user);
    }



    static User getUserByLogin(String login)
    {
        SimpleJdbcCall          call = new SimpleJdbcCall(getDataSource());
                                call.withProcedureName("get_user_by_login");

        MapSqlParameterSource   in = new MapSqlParameterSource();
                                in.addValue("p_login", login);

        call.declareParameters( new SqlOutParameter("p_password", Types.VARCHAR),
                                new SqlOutParameter("p_name", Types.VARCHAR),
                                new SqlOutParameter("p_rating", Types.NUMERIC));

        Map<String, Object> out = call.execute(in);

        User user = new User();
        user.setLogin(login);
        user.setPassword((String) out.get("p_password"));
        user.setName((String) out.get("p_name"));
        user.setRating((BigDecimal) out.get("p_rating"));

        return user;
    }

    static DataSource getDataSource() {
        PoolProperties poolProps = new PoolProperties();
        poolProps.setUrl("jdbc:oracle:thin:@localhost:1521:testDB");
        poolProps.setDriverClassName("oracle.jdbc.OracleDriver");
        poolProps.setUsername("TestUser");
        poolProps.setPassword("test");
        poolProps.setInitialSize(5);
        poolProps.setMaxActive(10);

        DataSource dataSource = new DataSource();
        dataSource.setPoolProperties(poolProps);

        return dataSource;
    }

}

这是我得到的例外:

Exception in thread "main" java.lang.NumberFormatException
    at java.math.BigDecimal.<init>(BigDecimal.java:494)
    at java.math.BigDecimal.<init>(BigDecimal.java:383)
    at java.math.BigDecimal.<init>(BigDecimal.java:806)
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:9153)
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8954)
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:9557)
    at oracle.jdbc.driver.OracleCallableStatement.setObject(OracleCallableStatement.java:6090)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:249)
    at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:364)
    at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:235)
    at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:150)
    at org.springframework.jdbc.core.CallableStatementCreatorFactory$CallableStatementCreatorImpl.createCallableStatement(CallableStatementCreatorFactory.java:213)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:1077)
    at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1135)
    at org.springframework.jdbc.core.simple.AbstractJdbcCall.executeCallInternal(AbstractJdbcCall.java:405)
    at org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute(AbstractJdbcCall.java:365)
    at org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SimpleJdbcCall.java:198)
    at com.eisima.spring.Main.getUserByLogin(Main.java:39)
    at com.eisima.spring.Main.main(Main.java:20)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

2 个答案:

答案 0 :(得分:0)

嗯,您可以通过多种方式处理这种情况,例如,尽管这不是最佳方式:

try {
   user.setRating((BigDecimal) out.get("p_rating"));
} catch (NumberFormatException e) {
   e.printStackTrace();
}

或者也许:

if (out.get("p_rating") == null) {
  user.setRating(new BigDecimal(0));
}

但是如果你试图设置一个空值,你应该期待NumberFormatException。上面两个中的一个将解决您的问题,但您应该分析您的用例,看看哪些对您来说最合适。

答案 1 :(得分:0)

原因是程序声明不正确:

    create or replace procedure get_user_by_login

 -- i'm passing string there --->  (p_login in number, 
                                    p_password out varchar2,
                                    p_name out varchar2,
                                    p_rating out number)
      as

      begin

        select password, name, rating
          into p_password, p_name, p_rating
          from users
          where login = p_login;

      end;
    /

我在考虑将null转换为BigDecimal时出错,但根本没有任何null值的错误。正如预期的那样,过程调用在列中的值为null时返回空值。

感谢大家的帮助。