【问题标题】:Java Spring Boot postgresql with HikariCP - get raw string output from statement query带有 HikariCP 的 Java Spring Boot postgresql - 从语句查询中获取原始字符串输出
【发布时间】:2019-02-20 23:57:18
【问题描述】:

我正在尝试编写一个 Spring Boot 控制器,它允许用户对 Postgres 数据库进行任意 SELECT 查询并查看结果。我通过使用a form 来实现这一点,就像链接中的那样。该项目基于this starter app

代码:

@Controller
@SpringBootApplication
public class Main {

  @Value("${spring.datasource.url}")
  private String dbUrl;

  @Autowired
  private DataSource dataSource;

  public static void main(String[] args) throws Exception {
    SpringApplication.run(Main.class, args);
  }

  @GetMapping("/query")
  public String queryForm(Model model) {
    model.addAttribute("query", new Query());
    return "query";
  }

  @PostMapping("/query")
  public String querySubmit(@ModelAttribute Query query) {
    try (final Connection connection = dataSource.getConnection()) {
      final Statement stmt = connection.createStatement();
      final String rawQueryContent = query.getContent().trim();
      final String queryContent;
      if(!rawQueryContent.toLowerCase().contains("limit")) {
        queryContent = rawQueryContent + " LIMIT 500";
      } else {
        queryContent = rawQueryContent;
      }
      final ResultSet rs = stmt.executeQuery(queryContent);
      final StringBuilder sb = new StringBuilder();
      while (rs.next()) {
        sb.append("Row #" + rs.getRow() + ": " + rs.toString() + "\n");
      }
      query.setContent(sb.toString());
      rs.close();
      stmt.closeOnCompletion();
    } catch (Exception e) {
      query.setContent(e.getMessage());
    }
    return "queryresult";
  }

  @Bean
  public DataSource dataSource() throws SQLException {
    if (dbUrl == null || dbUrl.isEmpty()) {
      return new HikariDataSource();
    } else {
      HikariConfig config = new HikariConfig();
      config.setJdbcUrl(dbUrl);
      return new HikariDataSource(config);
    }
  }
}

表格如下所示:


但是我得到的输出是这样的:

Row 1: HikariProxyResultSet@188463256 wrapping org.postgresql.jdbc.PgResultSet@ff61f7d 
Row 2: HikariProxyResultSet@188463256 wrapping org.postgresql.jdbc.PgResultSet@ff61f7d 
Row 3: HikariProxyResultSet@188463256 wrapping org.postgresql.jdbc.PgResultSet@ff61f7d 
Row 4: HikariProxyResultSet@188463256 wrapping org.postgresql.jdbc.PgResultSet@ff61f7d 

这不是我想要的!我想查看数据库中的实际行,如:

Row 1:  "Dave" | 23 | "Philadelphia"
Row 2:  "Anne" | 72 | "New York"
Row 3:  "Susie" | 44 | "San Francisco"
Row 4:  "Alex" | 22 | "Miami"

哎呀,我宁愿得到我通常在手动将 SQL 输入数据库时​​得到的原始字符串输出,而不是 ResultSet 的内存中的地址。

如果事先不知道表中有多少列或列的类型,我如何获得实际的数据库输出?

【问题讨论】:

  • rs.toString() 是做什么的?
  • @prasad_ - rs.toString() 将 ResultSet 的内存中的地址作为字符串返回。那不是我想要的。我想要数据库的实际内容。
  • 仔细查看此文档。它是结果集 api。它具有从查询输出中检索信息的方法:Result Set
  • 您需要通过获取相关列来连接每个值
  • @user7294900 我不知道我正在查询的表中的列数。

标签: java spring postgresql spring-boot hikaricp


【解决方案1】:

我建议初学者通过使用JdbcTemplateResultSetExtractor 来简化代码来简化代码。您可以使用ResultSet 本身来获取结果的列数。

我也不确定您为什么要重新定义DataSource

总而言之,类似下面的代码应该可以解决问题(尚未对其进行测试并从我的头顶输入,因此可能需要一些修饰)。

@Controller
@SpringBootApplication
public class Main {

  @Autowired
  private JdbcTemplate jdbc;

  public static void main(String[] args) throws Exception {
    SpringApplication.run(Main.class, args);
  }

  @GetMapping("/query")
  public String queryForm(Model model) {
    model.addAttribute("query", new Query());
    return "query";
  }

  @PostMapping("/query")
  public String querySubmit(@ModelAttribute Query query) {
    final String rawQueryContent = query.getContent().trim();
    final String queryContent;
    if(!rawQueryContent.toLowerCase().contains("limit")) {
        queryContent = rawQueryContent + " LIMIT 500";
    } else {
        queryContent = rawQueryContent;
    }
    String content = jdbc.query(queryContent, new ResultSetExtractor<StringBuilder>() {
        public StringBuilder extractData(ResultSet rs) {
          StringBuilder sb = new StringBuilder();
          int columns = rs.getMetaData().getColumnCount();
          while (rs.next()) {
            int row = rs.getRow();
            sb.append(rs.getRow()).append('|');
            for (int i = 1 ; i <= columns ; i++) {
              sb.append(rs.getObject(i)).append('|');
            }
          }
          return sb.toString();
        }      
    });
    query.setContent(content);
    return "queryresult";
  }
}

另请参阅How to get the number of columns from a JDBC ResultSet?,了解如何获取列数。

【讨论】:

  • 我认为您的意思是 queryContent,而不是 queryContext。
  • 如前所述,在没有测试的情况下输入它作为答案。
猜你喜欢
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多