带有 JdbcTemplate 的 Spring Boot 读取 100 列最终变成“结果集已关闭”

问题描述 投票:0回答:1

这是我的代码片段

package com.org.repository;

import com.org.config.datasourceconfig.DataSourceConfig;
import com.org.domain.transformer.SimpleMapper;
import com.org.infra.projection.SimpleProjection;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.util.*;

@Slf4j
@Repository
public class MyJDBCRepository extends AbstractJdbcRepository {

    public MyJDBCRepository(DataSourceConfig dataSourceConfig) {
        super(dataSourceConfig);
    }

    public SimpleProjection findBy(
            Integer search1,
            Integer search2){
        String query = SQL_QUERY;

        boolean hasCondition = query.toLowerCase(Locale.ROOT).contains("where");
        StringBuilder queryBuilder = new StringBuilder(query);

        hasCondition = appendEqualToClause(queryBuilder, hasCondition,  "a.column1", search1);
        hasCondition = appendEqualToClause(queryBuilder, hasCondition,  "a.column2 ", search2);
        
        queryBuilder.append(" limit 1");//TODO: This is temp change since we dont have `TimeStamp` type of column in reporting tables.

        log.info("createPreparedStatement [SQL Query]: {} ", queryBuilder);

        List<Object> params = new ArrayList<>();
        if (search1!= null) {
            params.add(search1);
        }
        if (search1 != null) {
            params.add(search2);
        }
        
        try {
            return getReadJdbcTemplate().queryForObject(queryBuilder.toString(), params.toArray(), new SimpleMapper());
        } catch (Exception e) {
            log.error("Exception in searchApplications Query: {}", e.getMessage(), e);
        }
        return null;
    }
}

public static boolean appendEqualToClause(StringBuilder queryBuilder, boolean hasCondition, String columnName, Object value) {
    if (value != null) {
        queryBuilder.append(hasCondition ? " AND " : " WHERE ")
                .append(columnName)
                .append(" = ?");
        return true; // Return true to update hasCondition
    }
    return hasCondition; // If no condition is added, return the same value
}

这是映射器

package com.org.domain.transformer;

import com.org.infra.projection.SimpleProjection;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.RowMapper;

import java.sql.ResultSet;
import java.sql.SQLException;

@Slf4j
public class SimpleMapper implements RowMapper<SimpleProjection> {

    @Override
    public SimpleProjection mapRow(ResultSet rs, int rowNum) throws SQLException {
        return new SimpleProjection() {
            @Override
            public Long getColumn1() {
                try {
                    return rs.getLong("column1");
                } catch (SQLException e) {
                    log.error("1. Reading column name failed : {}", e.getMessage());
                    return null;
                }
            }

            @Override
            public String getColumn2() {
                try {
                    return rs.getString("column2");
                } catch (SQLException e) {
                    log.error("2. Reading column name failed : {}", e.getMessage());
                    return null;
                }
            }

            :: ::
            :: ::

            @Override
            public Integer getColumn99() {
                try {
                    return rs.getInt("column99");
                } catch (SQLException e) {
                    log.error("99. Reading column name failed : {}", e.getMessage());
                    return null;
                }
            }

            @Override
            public Integer getColumn100() {
                try {
                    return rs.getInt("column100");
                } catch (SQLException e) {
                    log.error("100. Reading column name failed : {}", e.getMessage());
                    return null;
                }
            }
        };
    }
}

注意:我没有发布整个课程,因为它有很多行,所以我发布了一个简化版本。

投影接口

package com.org.infra.projection;

public interface SimpleProjection {

    Integer getColumn1();
    Integer getColumn2();
    
    :: ::
    :: ::
    
    Integer getColumn99();
    Integer getColumn100();
}

这是我的数据源配置

public DataSource readDataSource() {
    HikariConfig config = new HikariConfig();
    config.setDriverClassName(dataBaseDriver);
    config.setJdbcUrl(readDataBaseUrl);
    config.setUsername(readDataBaseUser);
    config.setPassword(readDataBasePassword);
    config.setMaximumPoolSize(readMaximumPoolSize);
    config.setIdleTimeout(readIdleTimeout);
    config.setMinimumIdle(readMinimumIdle);
    config.setIdleTimeout(readIdleTimeout);
    config.setConnectionTimeout(readConnectionTimeout);
    config.setMaxLifetime(readMaxLifeTime);
    return new HikariDataSource(config);
}

及其属性

spring.datasource.read.hikari.maximum-pool-size=10
spring.datasource.read.hikari.minimum-idle=5
spring.datasource.read.hikari.idle-timeout=10000
spring.datasource.read.hikari.connection-timeout=30000
spring.datasource.read.hikari.max-lifetime=60000

执行时,我得到:

74. Reading column name failed : This ResultSet is closed.
46. Reading column name failed : This ResultSet is closed.

我所做的是注释掉或在第 50 列之后没有阅读,对于那些它给我数据的人,从第 41 列开始它给我一个错误“结果集已关闭”,这是我的发现。

有什么帮助或让我知道我在这里做错了什么吗?

java spring-boot resultset jdbctemplate
1个回答
0
投票

错误

This ResultSet is closed
意味着您正在尝试从没有数据的结果集中获取数据。很可能是你的程序逻辑有问题。至少有一个地方看起来不对:

        if (search1!= null) {
            params.add(search1);
        }
        if (search1 != null) {
            params.add(search2);
        }

你是说吗?

        if (search1 != null) {
            params.add(search1);
        }
        if (search2 != null) {
            params.add(search2);
        }
© www.soinside.com 2019 - 2024. All rights reserved.