【问题标题】:SimpleJdbcCall executeObject() usage in Spring FrameworkSpring Framework 中 SimpleJdbcCall executeObject() 的使用
【发布时间】:2015-07-08 14:52:28
【问题描述】:

我通常在我的存储库包中这样做:

public void setDataSource(DataSource dataSource) {
    procGetDeviceDetails = new SimpleJdbcCall(dataSource)
        .withProcedureName("web_Device_Details")
        .returningResultSet("results", BeanPropertyRowMapper.newInstance(Device.class));
}

public Device deviceDetails(Map input) {
    Map m = procGetDeviceDetails.execute(input);
    List<Device> list = (List<Device>) m.get("results");
    if (list.size() > 0) {
        return list.get(0);
    }
    return null;
}

我希望在第二种方法中删除样板,因此我已切换到 executeObject()。我试过这个。都失败了。

public Device deviceDetails(Map input) {
    Device device = procGetDeviceDetails.executeObject(Device.class, input);
    return device;
}

public Device deviceDetails(Map input) {
    List<Device> device = procGetDeviceDetails.executeObject(List.class, input);
    return device.get(0);
}

问题是我的设备是空的。我还尝试仅声明 Object 而不是 Device 或 List ,它仍然为空。我做错了什么?

我知道结果已正确映射到 Device 类,因为我看到 procGetDeviceDetails (SimpleJdbcCall) 已声明 RowParameters 等于 {#result-set-1=org.springframework.jdbc.core.BeanPropertyRowMapper@79095fd7} 并且 BeanPropertyRowMapper 已映射类集到设备。

似乎泛型或其他东西困扰着我。我在这里找到了例子。 https://jira.spring.io/browse/SPR-7270

谢谢!

【问题讨论】:

    标签: spring spring-mvc spring-data spring-jdbc


    【解决方案1】:

    问题在于存储过程设计。 SimpleJdbcCall 中的这些方法使用 OUTPUT 参数,而我的存储过程通常将数据作为结果集返回。

    @Override
    @SuppressWarnings("unchecked")
    public <T> T executeObject(Class<T> returnType, Map<String, ?> args) {
        return (T) doExecute(args).get(getScalarOutParameterName());
    }
    

    因此,我创建了 SimpleJdbcCall 的子类,其中包含两个额外的方法 executeObjectSingle 和 executeObjectList,这使我能够简单地使用。

    public <T> T executeObjectSingle(Class<T> returnType, Map<String, ?> args) {
        List<T> o = executeObjectList(returnType, args);
        return o.get(0);
    }
    
    public <T> List<T> executeObjectList(Class<T> returnType, Map<String, ?> args) {
        Map<String, Object> m = doExecute(args);
        List<T> o = (List<T>) m.get(parameterNameResultSet);
        return o;
    }
    

    当然,这应该通过大小和空检查来扩展,但它显示了这个想法。

    SQL Server 中的存储过程示例:

    ALTER PROCEDURE [dbo].[Device_something]
        @device varchar(50),
        @username varchar(50),
        @password varchar(50)
    AS
    BEGIN
        SET NOCOUNT ON;
    
        select 'foo' as token
        union
        select 'bar' as token
    END
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-05
      • 1970-01-01
      • 1970-01-01
      • 2012-10-21
      • 2020-08-20
      • 2014-01-08
      • 2011-09-16
      相关资源
      最近更新 更多