I have a method that should output me a JSON from a desired table. To keep the service as flexible as possible, I decided to use native queries, not to use entities and also to work without repositories. But so that I don't just get a list of objects from the database like this statement "final String sql = "SELECT * FROM " + schemaName + "." + tableName;", I extended my SQL statement with array_to_json. This is how I get a JSON from my DB.
Here is my method:
#Override
public List<Map<String, Object>> getList(String tableName, String schemaName) {
// final String sql = "SELECT * FROM " + schemaName + "." + tableName;
final String sql = "SELECT array_to_json(array_agg(" + tableName + ")) FROM " + schemaName + "." + tableName;
final Query query = em.createNativeQuery(sql);
final List<Map<String, Object>> queryResult = query.;
return queryResult;
}
When I execute my sql statement in the PG Admin then I get the following JSON:
[{"id":1,"analytic_id":1,"propertytype":"shape","min_val":null,"max_val":null,"string_val":"102941","case_else":0,"result":"kugel"},{"id":2,"analytic_id":1,"propertytype":"shape","min_val":null,"max_val":null,"string_val":"019283","case_else":0,"result":"rechteck"},{"id":3,"analytic_id":1,"propertytype":"shape","min_val":null,"max_val":null,"string_val":"0122343","case_else":0,"result":"prism"},{"id":6,"analytic_id":1,"propertytype":"color","min_val":0,"max_val":20,"string_val":null,"case_else":0,"result":"grun"},{"id":7,"analytic_id":1,"propertytype":"color","min_val":21,"max_val":50,"string_val":null,"case_else":0,"result":"gelb"},{"id":8,"analytic_id":1,"propertytype":"color","min_val":51,"max_val":80,"string_val":null,"case_else":0,"result":"hellblau"},{"id":9,"analytic_id":1,"propertytype":"color","min_val":81,"max_val":999,"string_val":null,"case_else":0,"result":"rot"},{"id":10,"analytic_id":1,"propertytype":"color","min_val":null,"max_val":null,"string_val":null,"case_else":1,"result":"lila"}]
Now for my question:
So I get a JSON from my query. But how do I rebuild my method so that I can display the result of my query in the GetRequest. It is important to me that I get a JSON with all data back and that the return type is compatible with OPENAPI 3.0.
Thanks in advance
I have an SQL statement to select a BRAND_NAME based on an input parameter. The code goes something like this:
public ResponseEntity<List<Map<String, Object>>> getBrand(String brandName){
sql = "SELECT BRAND_NAME AS \"brandName\" FROM BRAND_E WHERE LOWER(BRAND_NAME) LIKE '%" + brandName + "%'";
return new ResponseEntity<List<Map<String, Object>>>(jdbc.queryForList(sql), HttpStatus.OK);
}
I've found out that this can probably cause SQL injection attacks, so I was wondering how to code this better.
Yes.If you directly use the request param on your sql it can lead to SQL injection attacks. We can always go with the prepared statement by adding a placeholder to where the values must be added.
Use queryForList(String sql, Object... args) or queryForList(String sql, Object[] args, Class<T> elementType)
Eg:-
String employeeId= "1";
String sql = "select id,name,address from employee where id = ?";
getJdbcTemplate(). queryForList(sql, new Object[]{employeeId}, Employee.class);
I am executing multiple queries concurrently and retrieving the results. But, the queries belong to multiple tables so, when resultset is retrieved, it is difficult to identify that a resultset belong to which table.
Can anyone help here as to how to identify the table names for each query resultset?
I tried below code but table name is blank!!!!
public static void getColumnNames(ResultSet rs) throws SQLException {
if (rs == null) {
return;
}
// get result set meta data
ResultSetMetaData rsMetaData = rs.getMetaData();
int numberOfColumns = rsMetaData.getColumnCount();
// get the column names; column indexes start from 1
for (int i = 1; i < numberOfColumns + 1; i++) {
String columnName = rsMetaData.getColumnName(i);
// Get the name of the column's table name
String tableName = rsMetaData.getTableName(i);
System.out.println("column name=" + columnName + " table=" + tableName + "");
}
}
I am calling this method like this:
jdbcTemplate.query(sql, new ResultSetExtractor<ResultSet>() {
#Override
public ResultSet extractData(ResultSet resultSet) throws SQLException,
DataAccessException {
getColumnNames(resultSet);
return resultSet;
}
});
Please advise, what is done wrong here? :(
You're not doing anything wrong here. The problem is caused by the method itself in connection with your DBMS or your JDBC driver, respectively.
See this doc please. 'table name or "" if not applicable' suggests that in your case the DBMS/driver does not provide the required information, causing the method to return an empty string.
I'm afraid, you'll have to find another way to detect which query the result originated from.
Here is my code which uses jdbcTemplate
String SQL = "select branch from branchTable where branch_name = '" + branch + "'";
ArrayList<String> branchList = (ArrayList<String>) jdbcTemplateObject.query(SQL, new RowMapper() {
public Object mapRow(ResultSet resultSet, int i) throws SQLException {
return resultSet.getString("city_desc");
}
});
return branchList;
Now i want to be able to use preparedstatement with a query like "select branch from branchTable where branch_name = ?"
How can i do that with jdbcTemplate ?
Examples i searched show demonstration on how to use it with update or insert query, but not with select query..
Please help.
JdbcTemplate has another query() method which takes arguments of the prepared statement as parameter:
jdbcTemplateObject.query(SQL, new Object[] {branchName}, new RowMapper() {...});
Note that:
SQL should be named sql
You should use List and not ArrayList. Nothing in the javadoc guarantees that an ArrayList is returned. And you shouldn't care about the concrete type of list returned.
You should use a RowMapper<String> and not a raw RowMapper.
This is my method. As you can see I'm using native sql to execute INSERT queries.
public void addNews(String title, String content) {
Session session = null;
session = this.sessionFactory.getCurrentSession();
Query query = session
.createSQLQuery(
"INSERT INTO news VALUES(NULL,:title,:content,NULL)")
.setString("title", title).setString("content", content);
int updated = query.executeUpdate();
}
Is it safe? Or how can I improve my method?
Yes, setting values as parameters (setString() method) preventing from SQL-injections. Non secure sql-statement looks like this:
String query = "INSERT INTO news VALUES(NULL," + title + "," + content + ",NULL)";
Read more about SQL injections (and other types of vulnerabilities) you can here: https://www.owasp.org/index.php/SQL_Injection