Java Spring Boot postgresql с HikariCP - получить необработанный вывод строки из запроса оператора - PullRequest
0 голосов
/ 17 сентября 2018

Я пытаюсь написать Spring Boot Controller, который позволяет пользователю выполнять произвольные запросы SELECT к базе данных Postgres и видеть результат. Я реализовал это, используя форму , как в ссылке. Проект основан на этом стартовом приложении .

Код:

@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);
    }
  }
}

Форма выглядит так:

Query form


Но вывод, который я получаю, выглядит так:

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.

Как получить фактический вывод базы данных, не зная заранее точно, сколько столбцов будет в таблице или типы столбцов?

1 Ответ

0 голосов
/ 17 сентября 2018

Я бы предложил для начала упростить ваш код, используя JdbcTemplate в сочетании с ResultSetExtractor для упрощения кода. Вы можете использовать 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";
  }
}

См. Также Как получить количество столбцов из JDBC ResultSet? Как узнать количество столбцов.

...