Iterate 2D array of ResultSet to JTable - java

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 :)

Related

Populate jTable from ArrayList<String>, without creating a new class.

I have a Web Service which returns ArrayList<String> from Database. I need to populate a jTable on client Java application with that ArrayList. How can I organise the ArrayList, so it shows in correct rows on the table? Currently it returns every element, separated with comma.
Here is the WebMethod bit:
#WebMethod(operationName = "ListCustomers")
public ArrayList ListCustomers() {
try{
Class.forName("org.apache.derby.jdbc.ClientDriver");
Connection con = DriverManager.getConnection("jdbc:derby://localhost:1527/BankDB", "bankadmin", "bankadmin");
Statement st = con.createStatement();
PreparedStatement prst = con.prepareStatement("select Name, AccountNumber from CUSTOMERS");
ArrayList<String> list = new ArrayList<>();
ResultSet rs = prst.executeQuery();
while(rs.next()){
String nm = rs.getString("Name");
String an = rs.getString("AccountNumber").toString();
list.add(new String (nm));
list.add(new String (an));
}
return (ArrayList) list;
}
catch(SQLException ex){
System.err.println(ex.getMessage());
return null;
}
catch (ClassNotFoundException ex) {
Logger.getLogger(BankServerService.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("second");
return null;
}
finally{
if(st != null){
try {
st.close();
}
catch(SQLException ex){
System.out.println("Could not close statement");
}
}
}
}
This returns:
[TestName1, 46484654897, Name2, 646543543, emp3, 534354354]
The client node looks like this, which I run in another method:
listCustomers();
DefaultTableModel model = (DefaultTableModel) jTable1.getModel();
Object rowData[] = new Object[listCustomers().size()];
for (int i=0; i<listCustomers().size(); i++){
rowData[i] = listCustomers().get(i);
model.addRow(rowData);
}
This populates only TestName1, 46484654897, into like 10 rows.
I need to show TestName1, Name2, emp3, on separate rows on 1st column of the table, and 46484654897, 646543543, 534354354 on separate rows on 2nd column.
If your goal is to put each name/account number combination on it's own row, but you've got them all in a single list you would need to do something a bit different.
listCustomers();
DefaultTableModel model = (DefaultTableModel) jTable1.getModel();
for(int i = 0; i < listCustomers.size(); i+=2){
Object[] rowdata = new Object[] {listCustomers.get(i), listCustomers.get(i+1)};
model.addRow(rowdata);
}
You increment i by 2 each time, since you only care about name + account number combo, and it goes in pairs.
Secondly you only want to pass model.addRow the object array with the data you want for that row. You were adding every string in listcustomer to it, then adding the whole array to the model as a row.
Above I just added a new rowdata object array inside the for loop, and populated it with the value at i (the name) and the value at i+1 (the account number). Keep in mind this will get out of sync if for some reason a name or account number is missing.

Storing values inside while loop using JDBC

ResultSet rs = dbmd.getSchemas();
while(rs.next()) {
String DbNames = rs.getString("TABLE_SCHEM");
}
I'm trying to store the value of DbNames and use it later. I tried using ArrayList
ResultSet rs = dbmd.getSchemas();
ArrayList<String> dbs = new ArrayList<>();
while(rs.next()) {
dbs.add(rs.getString("TABLE_SCHEM"));
}
for(String[] s : dbs)
{
System.out.println(Arrays.toString(s));
}
I'm new to programming and used StackOverflow resources to fix my problem, but I'm still having problems. Please help me figure this out.
Currently, your ArrayList is a raw type because you have not specified a data type for the ArrayList. Change your ArrayList declaration to a generic type by using
ArrayList<String> dbs = new ArrayList<>();
That way, when you try to access the values later, they will be String instead of Object.
Your new code will be
ResultSet rs = dbmd.getSchemas();
ArrayList<String> dbs = new ArrayList<>();
while(rs.next()) {
dbs.add(rs.getString("TABLE_SCHEM"));
}
for(String s : dbs) {
System.out.println(s);
}
Create ArrayList to save your data retrieved from the result set as below:
ResultSet resultset = ;
ArrayList<String> arrayList = new ArrayList<String>();
while (resultset.next()) {
arrayList.add(resultset.getString('TABLE_SCHEM'));
}

How to return multiple rows from result set in java?

I have a query, which returns multiple rows to result set. now i need to return total rows in to the application which calling this function.
I tried with this code:
final PreparedStatement ps = con.prepareStatement(query);
rs = ps.executeQuery();
while (rs.next()) {
result = rs.getInt(1);
}
by this code i am able to return only one value.
Now i want to return multiple rows
Create ArrayList of Integer and add result, return that array list.
ArrayList<Integer> resultList = new ArrayList<Integer>();
while (rs.next()) {
result = rs.getInt(1);
resultList.add(result);
}
return resultList;
You can use below code :
public static List<String> getSqlQueryResult(String sqlQuery) {
List<String> lst = new ArrayList<String>();
try {
Statement stmt = conSql.createStatement();
ResultSet res = stmt.executeQuery(sqlQuery);
ResultSetMetaData rsmd = res.getMetaData();
while (res.next()) {
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
lst.add(res.getString(i));
}
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return lst;
}
Try This code Hope this helps you
final PreparedStatement ps = con.prepareStatement(query);
ResultSet rs=ps.getResutlSet();
ResultSetMetaData rsmd=rs.getMetaData();
for(int i=1;i<=rsmd.getRowCount();i++){
String resut=rsmd.getString(i);
}
In this line result = rs.getInt(1); result is getting replaced each time with a new value.
A good alternate would be to store the values in a list then return the list provided the method return type should be List
Result set will contain the number of rows returned by the query.
Using result set object.next we can easily go through this rows of data.
In the above code you have only getting one value.
if result set contain more than one value.
then get this values using the index.
while(rs. next)
{
result1=rs.getInt(1);//this will get the two value in each row.
result2=rs.getInt(2);
}
if there are are more than one value then use that much index rs.getint(1)....rs.getInt(10)
also for Strings rs.getString(2)

extra column automatically appended in jtable (how to remove it )

I am working on a java project
I am using jdk 1.6
I am want to add data from database in jtable
I have achieved this by using DefaulTableModel
and I got the column names by using ResultSetMetadata
but the problem is
**I am getting a extra column name A at the 0th index of jtable
I want to remove this column
it looks like this
A | deptno
I only need deptno
**
the code used for creating this model is
private void updateTable() throws Exception {
String sqlrow = "Select count(*) from emp";
rs= db.sta.executeQuery(sqlrow);
rs.next();
int rows=rs.getInt(1);
System.out.println(""+rows);
String sqldata = "SELECT deptno FROM emp";
rs =db.sta.executeQuery(sqldata);
rsMD = rs.getMetaData();
numberOfColumns = rsMD.getColumnCount();
ColumnNames = new String[numberOfColumns+1];
System.out.println(""+numberOfColumns);
for(int i=1;i<=numberOfColumns;i++)
{
String colName=rsMD.getColumnName(i);
ColumnNames[i] = colName;
System.out.println(""+ColumnNames[i]);
}
//Cj is a method which takes sqlQuery , rows, column
Object[][] rowData=CJ(sqldata,rows,numberOfColumns);
//jt is table name
jt.setModel(new DefaultTableModel(rowData,ColumnNames));
}
// code for cj()
public Object[][] CJ(String sql,int rows,int cols)
{
Object[][] obj=new Object[rows][cols+1];
ResultSet rs=null;
try{
rs= db.sta.executeQuery(sql);
int c=0;
while(rs.next())
{
for(int i=1;i<=cols;i++)
{
obj[c][i]=rs.getString(i);
}
c++;
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
return obj;
}
I am using this code on
button click
updateTable();
jsp = new JScrollPane(jt); // jt is Jtable
jp.add(jsp); //jp is jpanel
please help me out
Not following the naming convention makes it hard to read, but I would suggest to take a closer look at the following piece of code
numberOfColumns = rsMD.getColumnCount();
ColumnNames = new String[numberOfColumns+1];
System.out.println(""+numberOfColumns);
for(int i=1;i<=numberOfColumns;i++)
{
String colName=rsMD.getColumnName(i);
ColumnNames[i] = colName;
System.out.println(""+ColumnNames[i]);
}
Here you explicitly use more column names then numberOfColumns. Idem for your CJ method, where you start at index 1.
Just start all those for loops at index 0, make the arrays one shorter and everything should work

Resultset To List

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)
}

Categories

Resources