Hibernate: Storing all values retrieved from Query to ArrayList - java

My issue is that I am getting the results of only one row, that also three times. I want to retrieve all the data which has stock less than 10. How do I add the object data to the arraylist?
String lowStock = "SELECT MedcineID, MName, Quantity FROM medcineinventory WHERE Quantity < :stock";
SQLQuery query = session.createSQLQuery(lowStock);
query.setParameter("stock", 10);
List<Object[]> stocks = query.list();
ArrayList<Inventory> allResults = new ArrayList<Inventory>();
Inventory iv = new Inventory();
for(Object[] data : stocks){
iv.setMedcineID((Integer) data[0]);
iv.setMName((String) data[1]);
iv.setQuantity((Integer)data[2]);
allResults.add(iv);
}
tx.commit();
session.close();
return allResults;

You have to move your Inventory iv = new Inventory(); inside the loop:
for(Object[] data : stocks){
Inventory iv = new Inventory();
iv.setMedcineID((Integer) data[0]);
iv.setMName((String) data[1]);
iv.setQuantity((Integer)data[2]);
allResults.add(iv);
}
That's because every time you go through the list of results you alter the data of the initial iv and add a new entry to the result list. So in the end you have three entries in your final list with the same values which represent the last element of the retrieved data.
Moving the creation of iv inside the loop creates new elements every time.

for(Object[] data : stocks){
Inventory iv = new Inventory();
iv.setMedcineID((Integer) data[0]);
iv.setMName((String) data[1]);
iv.setQuantity((Integer)data[2]);
allResults.add(iv);
}
Create a new inventory object inside the for loop and add that to your arraylist. Replace your for loop with this

Related

Updating an ArrayList with items from sqlite database

I'm trying to fetch data from sqlite database and update a custom recycler view with these data. I've created a method in my Database helper class that returns an ArrayList of items fetched from the database.
This is how I expect the method to work:
query the database, store the result set in a Cursor object.
Loop through the result set in the Cursor object and add each item to the end of an ArrayList object.
Return the ArrayList object containing the items fetched from the database.
But this is how the method is working:
queries the database, stores the result set in a Cursor object. Correct.
On the first iteration of the result set, the first item in the result set is added at index 0 of the ArrayList object. Just as expected. But on the second iteration, the second item in the result set replaces the already added item in the ArrayList at index 0, and it's also added at index 1. Furthermore, on the third iteration, the third item in the result set replaces all the items in the ArrayList such that we now have only the third item at indices 0, 1 and 2 instead of having the first item at index 0, second at index 1 and third at index 2. I'd really appreciate all the help I can get on this.
Below is the snippet of the method that does the item fetching from the database
public ArrayList<RechargeCard> getCard(){
ArrayList<RechargeCard> list = new ArrayList<>();
RechargeCard card = new RechargeCard();
SQLiteDatabase database = getReadableDatabase();
String query = "SELECT * FROM " + RechargeEntry.TABLE_NAME;
Cursor cursor = database.rawQuery(query, null);
if (cursor.moveToFirst()){
do{
String name = cursor.getString(cursor.getColumnIndexOrThrow(RechargeEntry.NAME_COLUMN));
int price = cursor.getInt(cursor.getColumnIndexOrThrow(RechargeEntry.PRICE_COLUMN));
double quantity = cursor.getDouble(cursor.getColumnIndexOrThrow(RechargeEntry.QUANTITY_COLUMN));
double total = cursor.getDouble(cursor.getColumnIndexOrThrow(RechargeEntry.TOTAL));
card.setName(name);
card.setPrice(price);
card.setQuantity(quantity);
card.setTotal(total);
list.add(card);
} while (cursor.moveToNext());
}
cursor.close();
database.close();
return list;
}
What you code is doing is that it is only updating RechargeCard card = new RechargeCard(); for every iteration that the while loop is doing.
You should put RechargeCard card = new RechargeCard(); inside the do while loop
so it will create new instances every iteration
public ArrayList<RechargeCard> getCard(){
ArrayList<RechargeCard> list = new ArrayList<>();
SQLiteDatabase database = getReadableDatabase();
String query = "SELECT * FROM " + RechargeEntry.TABLE_NAME;
Cursor cursor = database.rawQuery(query, null);
if (cursor.moveToFirst()){
do{
RechargeCard card = new RechargeCard();
String name = cursor.getString(cursor.getColumnIndexOrThrow(RechargeEntry.NAME_COLUMN));
int price = cursor.getInt(cursor.getColumnIndexOrThrow(RechargeEntry.PRICE_COLUMN));
double quantity = cursor.getDouble(cursor.getColumnIndexOrThrow(RechargeEntry.QUANTITY_COLUMN));
double total = cursor.getDouble(cursor.getColumnIndexOrThrow(RechargeEntry.TOTAL));
card.setName(name);
card.setPrice(price);
card.setQuantity(quantity);
card.setTotal(total);
list.add(card);
}while (cursor.moveToNext());
}
cursor.close();
database.close();
return list;
}

Passing a list in hql query

I am not getting output when I am directly passing a list through IN clause, but getting output when passing the values separately.
Working Code below:
List<String> resultList = null;
List<String> list = new ArrayList();
list.add("123");
list.add("456"):
String query = "select * from company where id in('123','456')");
resultList=getJdbcTemplate().queryForList(query, String.class);
Not working code:
List<String> resultList = null;
List<String> list = new ArrayList();
list.add("123");
list.add("456"):
String query = "select * from company where id in(:list)");
resultList=getJdbcTemplate().queryForList(query, String.class);
I want to fetch the query based on the list passed in the query. Could someone help me here
I have created a pojo class Company.java where I have mentioned db column fields.
After the query part,
List<Company> comp = getJdbcTemplate().queryForList(query, Company.class);
Error I am getting :
Incorrect Column count: expected 1, actual 23
What changes I need to do in above line.

Retrieve selected data from DynamoDB local in java

I have created a table in my local dynamoDB. The fields are,
id (N)
name (S)
school (S)
classname (S)
Now I want to retrieve all the records for which school equals to "xschool" and print.
Tried the below code but it gives me an error in the query,
QuerySpec spec = new QuerySpec().withProjectionExpression("sid, classname, school")
.withKeyConditionExpression("school = :v_school").
withValueMap(new ValueMap().withString(":v_school", "abcschool"));
ItemCollection<QueryOutcome> items = table.query(spec);
Iterator<Item> iterator = items.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next().toJSONPretty());
}
Any suggestions for this as I'm new to dynamoDB.
AmazonDynamoDB dynamoDBClient = createClient();
DynamoDB dynamoDB = new DynamoDB(dynamoDBClient);
String tableName = "student";
Table table = dynamoDB.getTable(tableName);
Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":sc", schoolname);
ItemCollection<ScanOutcome> items = table.scan("school = :sc", // FilterExpression
"sid, school, firstname, classname", // ProjectionExpression
null, // ExpressionAttributeNames - not used in this example
expressionAttributeValues);
Iterator<Item> iterator = items.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next().toJSONPretty());
}
Try this, I think this will work for you
From the DynamoDB documentation:
The Query operation enables you to query a table or a secondary index. You must provide a partition key value and an equality condition.
The error message you got means that school is not the partition key of your table. To fix this you can
change the table definition so that school is the partition key or
use a scan instead of a query.

Java - Set generic table with SQL results

Below you can find the code that I'm using to retrieve a table from a generic SQL statement (the SQL code is inputed by the user in another part of the code).
Since I'll be storing more than one table in the future, and the retrieved table will have some format functions applied to it, I'm storing the values in a:
Map<String, Map<String,List<Object>>> tables = new HashMap<String, Map<String,List<Object>>>();
The first Map is a Table, the second is a Column and finally the list hold each line of data.
The column names/order in:
Map<String, TreeMap<Integer, String>> order = new HashMap<String, TreeMap<Integer, String>>();
The Map is tha table, the TreeMap are the column number - column name
The code to create de generic table is:
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
for(int i = 1; i <= rsmd.getColumnCount(); i++){
String name = rsmd.getColumnLabel(i); //Label vs name. Label is also what's defined by the user in: "as VENDA"
answer.put(name, null);
singleOrder.put(i, name);
}
while(rs.next()){
Iterator answerIt = answer.entrySet().iterator();
while (answerIt.hasNext()) { //Get Columns in index order to compare with body HashMap (unordered)
Map.Entry columnNameValue = (Map.Entry)answerIt.next(); //key = columnName, value = List
String columnName = (String) columnNameValue.getKey();
List<Object> tmp = answer.get(columnName);
if (tmp == null) {
tmp = new ArrayList<Object>();
answer.put(columnName, tmp);
}
Object item = rs.getObject(columnName);
if(item instanceof Integer){
item = ((Integer) item).doubleValue();
} else if (item instanceof Long){
item = ((Long) item).doubleValue();
} else if (item instanceof BigDecimal){
item = ((BigDecimal) item).doubleValue();
}
tmp.add(item);
}
}
Efficiency will be key for this part of my code. How can I improve the table creation?
(I think this is a important question for Java coders, so a clear response can serve a pattern for future programmers that have the same difficulty that I'm having now)
Update 1:
Why I'm asking: I couldn't find any example of how to handle a flexible query in Java. I've created my own solution, but I fear it's some kind of monster compared to how to handle such a case properly in Java.
As example:
Lets say I'll name the result of a first query as "table1".
The query will be: Select STORE, SALES, GOAL, EXTRA from ... ;
The order variable will be like:
Map<String, TreeMap<Integer, String>> order = new HashMap<String, TreeMap<Integer, String>>();
table1,
1, "STORE"
2, "SALES"
3, "GOAL"
4, "EXTRA"
The tables variable:
Map<String, Map<String,List<Object>>> tables = new HashMap<String, Map<String,List<Object>>>();
"table1",
"STORE",
"unit1"
"unit2"
"unit3"
"unit4"
"SALES",
1312
126
1361
6823
"GOAL"
1300
160
1200
6000
"EXTRA"
"info1"
"info2"
"info3"
"info4"

Resultset to list

I want to create a list with my database field values.
There are 2 columns, name and surname.
I want to create a list that stores all names in name column in a field and then add to my DTO.
Is this possible?
Steps you can follow: -
First you need to have a List<String> that will store all your names. Declare it like this: -
List<String> nameList = new ArrayList<String>();
Now, you have all the records fetched and stored in ResultSet. So I assume that you can iterate over ResultSet and get each values from it. You need to use ResultSet#getString to fetch the name.
Now, each time you fetch one record, get the name field and add it to your list.
while(resultSet.next()) {
nameList.add(resultSet.getString("name"));
}
Now, since you haven't given enough information about your DTO, so that part you need to find out, how to add this ArrayList to your DTO.
The above list only contains name and not surname as you wanted only name. But if you want both, you need to create a custom DTO (FullName), that
contains name and surname as fields. And instantiate it from
every ResultSet and add it to the List<FullName>
JDBC unfortunately doesn't offer any ways to conveniently do this in a one-liner. But there are other APIs, such as jOOQ (disclaimer: I work for the company behind jOOQ):
List<DTO> list =
DSL.using(connection)
.fetch("SELECT first_name, last_name FROM table")
.into(DTO.class);
Or Spring JDBC
List<DTO> list =
new JdbcTemplate(new SingleConnectionDataSource(connection, true))
.query("SELECT first_name, last_name FROM table", (rs, rowNum) ->
new DTO(rs.getString(1), rs.getString(2));
Or Apache DbUtils:
List<DTO> list =
new QueryRunner()
.query(connection,
"SELECT first_name, last_name FROM table",
new ArrayListHandler())
.stream()
.map(array -> new DTO((String) array[0], (String) array[1]))
.collect(Collectors.toList());
I've used Java 8 for the Spring JDBC / Apache DbUtils examples, but it can be done with older versions of Java as well.
It is. What have you tried ?
To access the database, you need to use JDBC and execute a query, giving you a ResultSet.
I would create an class called FullName with 2 String fields name and surname. Just populate these in a loop using
rs.getString("NAME"); // column name
rs.getString("SURNAME");
e.g.
List<FullName> fullnames = new ArrayList<FullName>();
while (rs.next()) {
fullnames.add(new FullName(rs));
}
Note that I'm populating the object via the ResultSet object directly. You may choose instead to implement a constructor taking the 2 name fields.
Note also that I'm creating a Fullname object. So the firstname/surname are kept separate and you have the freedom to add initials etc. later. You may prefer to rename this Person and that will give you the freedom to add additional attributes going forwards.
What worked for me is:
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
ArrayList<String> resultList= new ArrayList<>(columnCount);
while (rs.next()) {
int i = 1;
while(i <= columnCount) {
resultList.add(rs.getString(i++));
}
}
return resultList;
This worked for me->
private List<Object[]> convertResultsetToObject(ResultSet rs) throws SQLException {
List<Object[]> results = new ArrayList<Object[]>();
int count = 0;
if(rs != null) {
ResultSetMetaData rsm = rs.getMetaData();
count = rsm.getColumnCount();
}
while(rs != null && rs.next()) {
Object [] obj = new Object[count];
int temp = 1;
while(temp <= count) {
obj[temp - 1] = rs.getObject(temp);
temp++;
}
results.add(obj);
}
return results;
}

Categories

Resources