Resultset To List - java

I want to convert my Resultset to List in my JSP page. and want to display all the values. This is my query:
SELECT userId, userName
FROM user;
I have executed that using preparedstatement and got the Resultset. But how to convert it as a List and want to display the result like this:
userID userName
------------------
1001 user-X
1006 user-Y
1007 user-Z

You need to iterate over the ResultSet object in a loop, row by row, to pull out each column value:
List ll = new LinkedList();
ResultSet rs = stmt.executeQuery("SELECT userid, username FROM USER");
// Fetch each row from the result set
while (rs.next()) {
int i = rs.getInt("userid");
String str = rs.getString("username");
//Assuming you have a user object
User user = new User(i, str);
ll.add(user);
}

You could always use Commons DbUtils and the MapListHandler. From the doc:
ResultSetHandler implementation that
converts a ResultSet into a List of
Maps
so it'll take a lot of boilerplate code out of your hands.

A ResultSet should never get as far as a JSP. It should be mapping into a data structure or object and closed inside the method scope in which it was created. It's a database cursor, a scarce resource. Your app will run out of them soon if you persist with such a design.

var rs = stmt.executeQuery();
List<Map<String, Object>> result = new ArrayList<>();
while (rs.next()) {
Map<String, Object> resMap = new HashMap<>();
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
resMap.put(rs.getMetaData().getColumnName(i), rs.getObject(i));
}
result.add(resMap);
}

You can make a list of lists.
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
List row = null;
List table = new List();
while(rs.next())
{
for(int i = 0; i < n; i++)
row.add(rs.next(i);
tabla.add(row)
}

Related

How to do Looping with ResultSet?

So, I want to loop this ResultSet in order to update the table one by one, but the method while(rsl.next()) can't help me do the looping. It's just work once, and then the others are skipped. Can someone help me fix this problem? Thanks in advance
try {
String url = "jdbc:mysql://localhost/minimarket";
String user = "root";
String pass = "";
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, user, pass);
Statement stmt = conn.createStatement();
ResultSet rsl = stmt.executeQuery("SELECT * FROM keranjang WHERE pemesan='"+login.userid+"'");
while (rsl.next()) {
String nb = rsl.getString("nama_barang");
String dtl = rsl.getString("detail");
String beratt = rsl.getString("berat");
String hrga = rsl.getString("harga");
String jmlh = rsl.getString("jumlah");
stmt.executeUpdate("UPDATE barang SET stok=stok+'"+jmlh+"' WHERE nama_barang='"+nb+"' AND detail='"+dtl+"' AND berat='"+beratt+"'");
stmt.executeUpdate("DELETE FROM keranjang WHERE pemesan ='"+login.userid+"' AND nama_barang='"+nb+"'");
}
conn.close();
} catch (Exception error) {
}
System.exit(0);
Problem:
if (rsl.next())
fix:
while (rsl.next())
Debug the app and check if the your connection to the database is valid.
When you execute an executeUpdate on your statement an int is returned and most importantly your result set object rs1 from your query gets closed and can't be accessed anymore since the Statement class only handles one query/result set. I haven't tested this myself but I am pretty sure this is the reason.
The solution is to have a separate Statement object for the update/delete so that the original ResultSet is not affected. Something like below
Statement stmt = conn.createStatement();
Statement updStmt = conn.createStatement();
ResultSet rsl = stmt.executeQuery("SELECT * FROM keranjang WHERE pemesan='"+login.userid+"'");
while (rsl.next()) {
String nb = rsl.getString("nama_barang");
String dtl = rsl.getString("detail");
String beratt = rsl.getString("berat");
String hrga = rsl.getString("harga");
String jmlh = rsl.getString("jumlah");
updStmt.executeUpdate("UPDATE barang SET stok=stok+'"+jmlh+"' WHERE nama_barang='"+nb+"' AND detail='"+dtl+"' AND berat='"+beratt+"'");
updStmt.executeUpdate("DELETE FROM keranjang WHERE pemesan ='"+login.userid+"' AND nama_barang='"+nb+"'");
}
If I've understood your problem correctly, there are two possible problems here:
the resultset is null - I assume that this cant be the case as if it was you'd get an exception in your while loop and nothing would be output
the second problem is that resultset.getString(i++) will get columns 1,2,3 and so on from each subsequent row
I think that the second point is probably your problem here.
Let us say you only had 1 row returned, as follows
Col 1, Col 2, Col3
A , B, C
Your code as it stands would only get A - it wouldn't get the rest of the columns.
I suggest you change your code as follows:
ResultSet resultset = ...;
ArrayList<String> arrayList = new ArrayList<String>();
while (resultset.next()) {
int i = 1;
while(i <= numberOfColumns) {
arrayList.add(resultset.getString(i++));
}
System.out.println(resultset.getString("Col 1"));
System.out.println(resultset.getString("Col 2"));
System.out.println(resultset.getString("Col 3"));
System.out.println(resultset.getString("Col n"));
}
To get the number of columns:
ResultSetMetaData metadata = resultset.getMetaData();
int numberOfColumns = metadata.getColumnCount();

Iterate 2D array of ResultSet to JTable

I have a resultset class that all of the query operations are stored. My problem is thatI am trying to fill a jtable with resultset data but I am only able to display the data in one column where I have three. This is the snippet of the resultset class:
public static List<List<String>> getAllFabrics() throws SQLException{
sql = "SELECT * FROM fabric";
List<List<String>> values = new ArrayList<>();
List<String> id = new ArrayList<>();
List<String> item = new ArrayList<>();
List<String> supplier = new ArrayList<>();
stmt = con.createStatement();
rs = stmt.executeQuery(sql);
//metaData = rs.getMetaData();
//int columnNum = metaData.getColumnCount();
while(rs.next()){
id.add(String.valueOf(rs.getInt("id")));
item.add(rs.getString("ItemDesc"));
supplier.add(rs.getString("Supplier"));
}
values.add(id);
values.add(item);
values.add(supplier);
return values;
}
and this is the jtable method that I am trying for hours to solve:
public static DefaultTableModel loadTable(){
ModelDB model = null;
DefaultTableModel tableModel = new DefaultTableModel();
tableModel.addColumn("ID");
tableModel.addColumn("Fabric");
tableModel.addColumn("Supplier");
try{
List<String> id = model.getAllFabrics().get(0);
List<String> item = model.getAllFabrics().get(1);
List<String> supplier = model.getAllFabrics().get(2);
//System.out.println(model.getAllFabrics().size()); tableModel.addRow(new Object[]{subRow});
for(List<String> row:model.getAllFabrics()){
tableModel.addRow(new Object[]{id,item,supplier});
}
}catch(SQLException ex){
ex.printStackTrace();
}
return tableModel;
}
I can't find a way to iterate the values to display in their respective column.
Original answer
You are almost there! You only need to change the loop:
for(int i = 0; i < id.size(); i++) {
tableModel.addRow(new Object[] {id.get(i),item.get(i),supplier.get(i)});
}
But as said in the comments, you should consider changing to an array of rows, not columns.
Edit
This is one approach. It is basically same as your code except the rows/columns are interchanged so the method returns a List of rows, not columns:
public static List<List<String>> getAllFabrics() throws SQLException{
sql = "SELECT * FROM fabric";
List<List<String>> values = new ArrayList<>();
stmt = con.createStatement();
rs = stmt.executeQuery(sql);
while(rs.next()){
List<String> row = new ArrayList<>();
row.add(String.valueOf(rs.getInt("id")));
row.add(rs.getString("ItemDesc"));
row.add(rs.getString("Supplier"));
// Now row contains {id, item, supplier}
values.add(row);
}
return values;
}
Then in your loadTable() method change to:
...
try{
for(List<String> row: model.getAllFabrics()){
tableModel.addRow(row.toArray(new String[row.size()]);
}
...
In your original code you call model.getAllFabrics() multiple times to get the return value. This is not good because every time you do that the method gets called and it needs to make the SQL-request again etc. Store the return value in a variable instead. In this case though as the return value is only accessed once you can equally just do as I described above.
Hope this helps :)

ResultSet to Array

I have a Result set returned using a query:
String query = "select Bookname, SubjectName from books join Subjects on Subjects.SubjectID = Books.subjectID where classID = '1a'";
ResultSet temp = null;
try
{
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(query);
temp = rs;
}
I was just wondering is it possible to turn the Resultset into two seperate arrays: eg BookName[] and BookSubject[] so I can show them in a list view later on? Relatively new to resultset and this concept in android
You should be able to easily iterate through the results on the result set, populating each array with the results as you interate.
Something like this:
...
ResultSet rs = st.executeQuery(query);
ArrayList<String> names = new ArrayList<String>();
ArrayList<String> subjects = new ArrayList<String>();
while (rs.next()) {
names.add(rs.getString(1));
subjects.add(rs.getString(2));
}
// finally turn the array lists into arrays - if really needed
String[] nameArr = new String[names.size()];
nameArr = names.toArray(nameArr);
String[] subjectArr = new String[subjects.size()];
subjectArr = subjects.toArray(subjectArr);
Hope that helps!

Using a HashMap to store database table & column names

I have some code that retrieves table & column names from a database:
PreparedStatement p = conn.prepareStatement(
"SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'SQLUser'");
rs = p.executeQuery();
I was thinking that I could use a HashMap to store this data, where the key is the table name (which is always unique) and an ArrayList to store the list of columns contained within that table.
How can I iterate through the ResultSet so that for each table a new ArrayList is created, populated with related column names and then added to the HashMap using that table name as the key?
You can use something like this:
Map<String, List<String>> map = new HashMap<String, List<String>>();
ResultSet rs = st.executeQuery(sql);
while (rs.next()) {
String table = rs.getString("table_name"));
ArrayList<String> columns = map.get(table);
if (columns == null) {
columns = new ArrayList<String>();
map.put(table, columns)
}
columns.add(rs.getString("column_name"));
}
Your code should look like this -
Map<String, List<String>> tableMap = new HashMap<String, List<String>>();
ArrayList<String> columnList = new ArrayList<String>();
PreparedStatement p = conn.prepareStatement(
"SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'SQLUser'");
ResultSet rs = p.executeQuery();
while (rs.next()) {
String columnName = rs.getString("COLUMN_NAME"));
columnList.add(columnName);
}
tableMap.put("SQLUser", columnList);
Also you can use the ResultSetMetaData to get the column names from a table.
ResultSet resultSet = st.executeQuery("Select * from SQLUser")
ResultSetMetaData metaData = resultSet.getMetaData();
int count = metaData.getColumnCount();
List<String> columnList = new ArrayList<String>();
for (int i = 1; i <= count; i++) {
columnList.add(metaData.getColumnLabel(i)));
}

JAVA sql NOT IN list statement

Am trying to select record from database where record id NOT IN list.
take a look # my problem below.
String Sqlids = "2,6,3,9"; // this is dynamic so the number of element is unknown
String str= "SELECT TOP 1 * FROM student WHERE ID NOT IN (2,6,3,9) ORDER BY NEWID()";
PreparedStatement stat = con.prepareStatement(str);
ResultSet rs = stat.executeQuery();
The above statement work FINE, but if i change it to
String Sqlids = "2,6,3,9";
String str= "SELECT TOP 1 * FROM student WHERE ID NOT IN (Sqlids) ORDER BY NEWID()";
PreparedStatement stat = con.prepareStatement(str);
ResultSet rs = stat.executeQuery();
//i also try this
String Sqlids = "2,6,3,9";
String str= "SELECT TOP 1 * FROM student WHERE ID NOT IN (?) ORDER BY NEWID()";
PreparedStatement stat = con.prepareStatement(str);
stat.setString(1,Sqlids );
ResultSet rs = stat.executeQuery();
THE ABOVE STATEMENT DOESN'T FILTER
Since Sqlids is one string is seeing it as one parameter so it return repeated rows, is there an integer format for storing values like 2,6,3,9 ?
since the Sqlids is from an arraylist called SqlidList
i try somtin like this
Iterator iTr = SqlidList.iterator();
while(iTr.hasNext()){
stat.setString(1,iTr.next().toString()+",");
}
but the setString(1,--) is not available since is in a while loop
Use Connection#createArrayOf after converting your ids to a String[]
String[] ids = {"2", "6", "3", "9"};
String str= "SELECT TOP 1 * FROM student WHERE ID NOT IN ? ORDER BY NEWID()";
PreparedStatement stat = con.prepareStatement(str);
stat.setArray(1, con.createArrayOf("text",ids));
ResultSet rs = stat.executeQuery();
If createArrayOf is not supported by your JDBC driver (as in this case) I'd probably just construct the query string in place e.g:
String Sqlids = "2,6,3,9";
String str= "SELECT TOP 1 * FROM student WHERE ID NOT IN ("+Sqlids+") ORDER BY NEWID()";
or if you have a collection of ids use a utility method to create the array content:
public static String toSqlArray(List<String> strings) {
StringBuilder sb = new StringBuilder();
boolean doneOne = false;
for(String str: strings){
if(doneOne){
sb.append(", ");
}
sb.append("'").append(str).append("'");
doneOne = true;
}
return sb.toString();
}
The way I've solved the problem is :
SQL = "...WHERE ID NOT IN ({0}) ..."
have a method which builds a string containing a number of ? equal to the size of SqlidList
public static String buildQuestionMarks(final int count) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++) {
sb.append("?" + ",");
}
return sb.substring(0, sb.length() - 1);
}
use java.text.MessageFormat.format() to insert the list of ? into the sql
String finalSql = MessageFormat.format(SQL, questionMarksString);
have a method to set the params on teh prepared statement. Something similar to what you wrote although you need to increment the first parameter of stat.setString()
This should work for variable number of parameters.
Did you tried using
int[] array = {2,6,3,9};
String str= "SELECT TOP 1 * FROM student WHERE ID NOT IN (?,?,?,?) ORDER BY NEWID()";
PreparedStatement stat = con.prepareStatement(str);
for(int i = 1; i <= array.length; i++)
stat.setString(i,array[i - 1]);
ResultSet rs = stat.executeQuery();

Categories

Resources