I am using JAVA with sql I want to create query object name dynamically based on loop
example
Query query1;
Query query2;
Query query3....
the number 1,2,3 comes from variable i incremented in for loop.
You will probably want to use a Map<String, Query> where you can then do:
Map<String, Query> queries = new HashMap<String, Query>();
for (int i = 0; i < limit; i++) {
queries.put("query" + i, new Query());
}
I'd just like to point out that this is a code smell, and you should probably wonder why you need to create so many queries.
Related
Hello fellow programmers, I want to add in loop multiple lists into HashMap. I dont't know why when its getting to second iteration records are multiplied e.g. there is 10 records for February( monthId = 2) and after whole loop there is 40 of them injected. Below is code:
public HashMap<String,List<Transaction>> convertTransactionsPerMonth(int
userId){
for(int monthId = 1; monthId < 13; monthId++){
ArrayList<Transaction> transactionsFromDatabase = new ArrayList<>
(entityManager
.createQuery("SELECT t FROM Transaction t WHERE
MONTH(t.transactionDate) LIKE :monthId AND t.user.id = :userId",
Transaction.class)
.setParameter("monthId", monthId)
.setParameter("userId", userId)
.getResultList());
transactionsPerMonth.put(Months.getById(monthId),
transactionsFromDatabase);
}
return transactionsPerMonth;
}
When comparing two numbers in sql you use = and not LIKE
"SELECT t FROM Transaction t WHERE
MONTH(t.transactionDate) = :monthId AND t.user.id = :userId"
also it looks like transactionsPerMonthis declared outside of the method and then returned, are you sure it is empty when the method is called? Probably better to declare it as a local variable.
Bit of a beginner's questions but...
I have a ResultSet object that I return from a database - 3 columns of 30 rows.
I retrieve the following dataset:
using the following:
try {
preparedStatement = conn.prepareStatement(
sqlStatement,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
rs = preparedStatement.executeQuery();
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
while(rs.next()) {
HashMap row = new HashMap(columns);
for(int i=1; i<=columns; ++i){
row.put(md.getColumnName(i),rs.getObject(i));
}
list.add(row);
}
...and I return it as an ArrayList
...which, when debugging, displays as follows:
I want to be able to iterate over the HashMap values, in pseudo code:
get key 0
get value 0, 1 & 2
use these as test data
if no luck then try key 2
This shouldn't be hard I know, I'm just struggling to find the best way of iterating over an ArrayList of HashMaps
You are using raw types, and your IDE or compiler are throwing you tons of warnings about this. You should heed them. Becaus you didn't, you were capable of writing code that assigns a list containing maps (each map representing one returned db result, mapping column names to the values in the row)... to a variable of type List<String>.
This model of translating a DB row to a map is a bad idea. There are plenty of nice libraries out there to interact with DBs. For example, JDBI is simple to understand has a more thought-through API for accessing results. It can even map results onto java data types.
If you must use the model you've pasted so far, for starters, add generics everywhere so that the compiler would have marked that down as a compile-time error. At the very least make that List<Map<String, Object>>.
Let me reiterate that switching things over to JDBI is a far superior road forward, but in the interests of answering the directly posed question, once you've added the generics and fixed your variable types, you can do this:
List<Map<String, Object>> data = getResultSet(syndicatorName);
for (int rowIdx = 0; rowIdx < data.size(); i++) {
Map<String, Object> row = data.get(rowIdx);
for (Map.Entry<String, Object> cell : row.entrySet()) {
System.out.printf("Row %d cell %s: %s\n", rowIdx, cell.getKey(), cell.getValue());
}
}
Note that your cell values are 'Object' here. You'd have to cast them to what you know the data type to be. This is not idiomatic java but there's no way to fix that without completely redesigning the getResultSet method. Again.. JDBI or similar libraries is what you really want here.
You need a nested Loop (at least i would do it that way...there are not only a few other ways):
for (HashMap<T,T> i : ArrayList<HashMap<T,T>>) {
for (T j : i.keySet()){
i.get(j);
//further code
}
}
I am using the using Spring Batch + Spring JDBC. In my project, we're passing list of say Account to IN query of native SQL. In IN paramater we can max pass the 999 records and remaining list we again need to process.
I developed the following code but that doesn't works well if I have more than 2000 records. How can I make the dynamic, so if any list values comes in code should generate result ?
if(accNumList.size() < 999) {
Map<String, Set<Integer>> singletonMap = Collections.singletonMap("valSet1", accNumList);
Map<String, Object> paramMap = new HashMap<>();
paramMap.putAll(singletonMap);
paramMap.put("isFlag", "Y");
List<Map<String, Object>> queryForMap = namedParameterJdbcTemplate.queryForList(sql, paramMap);
}else {
int sizeOfRecords = accNumList.size();
// convert set to List
List<Integer> data = new ArrayList<>(accNumList);
List<Integer> subItems = data.subList(0, 999);
Map<String, List<Integer>> singletonMap = Collections.singletonMap("valSet1", subItems);
Map<String, Object> paramMap = new HashMap<>();
paramMap.putAll(singletonMap);
List<Map<String, Object>> queryForMap = namedParameterJdbcTemplate.queryForList(sql, paramMap);
// remaining
int remaining = sizeOfRecords - 999;
List<Integer> newsubItems = data.subList(1000, remaining);
Map<String, List<Integer>> newsingletonMap = Collections.singletonMap("valSet1", newsubItems);
Map<String, Object> newparamMap = new HashMap<>();
newparamMap.putAll(newsingletonMap);
List<Map<String, Object>> newqueryForMap = namedParameterJdbcTemplate.queryForList(sql, newparamMap);
//final
List<Map<String, Object>> queryForMapFinal = new ArrayList<>();
queryForMapFinal.add(paramMap);
queryForMapFinal.add(newparamMap);
}
Working around the IN limit is inefficient, building a JDBC query in Java is not always the right tool for the job. Consider the following:
Thousands of bound values will result in potentially megabytes of SQL. It will take a long time to send this SQL to the database. The Database might take longer to read the SQL text than execute it as per Tom's answer to "Limit and conversion very long IN list: WHERE x IN ( ,,, ...)" question.
It will be inefficient due to SQL parsing. Not only does it take a long time to parse this long SQL but each invocation has a different number of bound parameters which will be parsed and planned separately (see this article which explains it).
There is a hard limit of bound parameters in a SQL statement. You can repeat the OR a few times to work around the IN limit but you are going to hit the SQL statement limit at some point.
For those types of queries, it's usually better to create temporary tables. Create one before your query, insert all the identifiers into it and join it with the entity table in your query to simulate the IN condition.
Ideally, you can replace the Java code with a stored procedure, especially if you are pulling out tens of thousands of identifiers from the database just to pass them back to the database in the next query.
I have a list of objects (result from a select query), I want to convert it into an array and I want to put each column of the query in a column in the array. I have tried many solutions in the forum but I haven't found a solution.
In my bean I have the following list:
private List<PhBonCmd> listEntree; // The PhBonCmd is an object model imported has attributes like codeprod , quant ,...
.....
String sql ="select c.codeprod as codeprod , c.quant as quant ,c.date_cmd as date_cmd, c.date_expir as date_expir,c.numbco as numbco, c.auteur as auteur,"
+"c.idcmd as idcmd ,f.nomfourn as nomfourn ,coalesce(c.quant_livre, 0) as quant_livre ,m.libelle as libelle "
+"from commandes c,listeproduit m,fournisseur f "
+"where c.codeprod=m.codeproduit and c.fourn=f.idfourn and c.statut='IN' and c.numbco ='"+getNumbco()+"' ";
listEntree = (List<PhBonCmd>) this.bcService.execRequete(sql);//Here the results of the sql query
Now what I want is to put each column of the List (listEntree) in a multidimensional arraylist, so as if I want to access to a specific single value in of the arraylist, I do so.
I want to put the results of the query in an array and from there , i want to access to elements of the array . Have things like this array1[row][col]
Why are you casting to List<PhBonCmd>? . The ResultSet is by default multidimensional. If you want to convert to a multidimensional List, you can do it by processing the ResultSet.
If you are using Spring , you can use RowMapper or ResultSetExtractor to get the desired behaviour.
I don't know the reason of doing that, when you have OOP power, but here it is.
You have to use reflection to get know fields (lets say columns if you wish) of PhBonCmd on fly:
Class clazz = PhBonCmd.class;
Field[] fields = clazz.getFields();
String[][] myDemensionalArray = new String[fields.length()][listEntree.size()];
for(int i=0; i < fields.length(); i++){
for(int j=0; j < listEntree.size(); j++){
myDemensionalArray[i][j] = fields[i].get(listEntree.get(j));
}
}
I think I've become code-blind.
I'm currently doing a small project with a friend and we're using JDBC to select from a mySQL database.
What I want is that after running the select statement, I get some sort of '2D' list of all the data back.
I think I want something returned like this -
array[columnName][all of the data inside the selected column]
Pseudo Code
// Count all rows from a column
// Count the columns selected
// Adds the column names to 'array'
for(int i = 1; i <= columnCount; i++)
columns.add(resultSetMeta.getColumnName(i));
// Adds the results of the first column to the 'array'
// How can I add the results from n columns?
for(int i = 1; i <= rowCount; i++ ) {
while (resultSet.next())
rows.add(resultSet.getString(i));
}
columnsAndRows.put(columns, rows);
What is the most appropriate data type to use to 'replicate' a table - ArrayLists, Arrays, or HashMaps?
What's the best way of making a ResultSet into a 2D datatype?
When iterating through a ResultSet, how can I move to the next column?
you can use hashmap for key value pairs, where as key you put your resultset metadata and values as resultset values.
HashMap<String, Object> p = new HashMap<String, Object>();
p.put("ResultSetkey1","ResultSetvalue1");
p.put("ResultSetkey2","ResultSetvalue2");
Also I would like to say use ResultsetUtils ResultsetUtils