I am trying to write a Spring Boot Controller that allows the user to make arbitrary SELECT queries to a Postgres database and see the result. I implemented this by using a form like the one in the link. The project is based on this starter app.
Code:
@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);
}
}
}
The form looks like this:
But the output I am getting looks like this:
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
This is not what I want! I want to see the actual rows in the database, as in:
Row 1: "Dave" | 23 | "Philadelphia"
Row 2: "Anne" | 72 | "New York"
Row 3: "Susie" | 44 | "San Francisco"
Row 4: "Alex" | 22 | "Miami"
Heck, I would rather get the raw string output that I normally get when I hand-type SQL into the database than the address in memory of the ResultSet.
How do I get the actual database output without knowing in advance exactly how many columns there will be in the table or the types of the columns?