Build map with column name and column values from java.sql.ResultSet - java

I have the following snippet:
Connection connection = getConnection(schemaName);
Statement stmt = connection.createStatement();
String sql = "SELECT * FROM " + tableName;
ResultSet rs = stmt.executeQuery(sql);
now what I want to achieve is building a
Map<String , List<String>>
where key is the columnName and value is list of columnValues. Here is my code:
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
List<String> columnNames = new LinkedList<>();
for (int i = 1; i <= columnCount; i++) {
columnNames.add(rsmd.getColumnName(i));
}
Map<String, List<String>> columnNameToValuesMap = new HashMap<String, List<String>>();
for (String columnName : columnNames) {
List<String> values = new ArrayList<>();
try {
while (rs.next()) {
values.add(rs.getString(columnName));
}
} catch (SQLException e) {
e.printStackTrace();
}
columnNameToValuesMap.put(columnName, values);
}
The issue is that after the first columnName iteration, rs.next() is empty. So basically The result map contains the values for only the first column. How can I reuse the same resultSet for each iteration ? Why its empty after the first one ?

You can follow the below steps:
(1) Initialise the columnNameToValuesMap with empty list objects with column name as key
(2) Iterate the resultset using rs.next()
(3) Get each column data using a for loop and add to list values object
(4) Add the list of columns data to columnNameToValuesMap object
You can refer the below code with comments:
List<String> columnNames = new LinkedList<>();
Map<String,List<String>> columnNameToValuesMap=new HashMap<String, List<String>>();
for (int i = 1; i <= columnCount; i++) {
String columnName = rsmd.getColumnName(i);
columnNames.add(columnName);
//Load the Map initially with keys(columnnames) and empty list
columnNameToValuesMap.put(columnName, new ArrayList());
}
try {
while (rs.next()) { //Iterate the resultset for each row
for (String columnName : columnNames) {
//Get the list mapped to column name
List<String> columnDataList = columnNameToValuesMap.get(columnName);
//Add the current row's column data to list
columnDataList.add(rs.getString(columnName));
//add the updated list of column data to the map now
columnNameToValuesMap.put(columnName, columnDataList);
}
}
} catch (SQLException e) {
e.printStackTrace();
}

Related

How to display arraylist in jtable dynamically

I am new to Java so please bare with me :).
I created a function that fetch the records from the table.
public ArrayList<Object> getAll() {
try {
ArrayList<Object> resultList = new ArrayList<>();
query = this.conn.prepareStatement("select * from " +
this.currentTable + this.tableClass.getWhere());
ResultSet result = query.executeQuery();
ResultSetMetaData meta = result.getMetaData();
int totalColumn = meta.getColumnCount();
while(result.next()) {
ArrayList<Object> obj = new ArrayList<>();
for (int x = 1; x < totalColumn; x++) {
obj.add(result.getObject(x));
}
resultList.add(obj);
}
result.close();
query.close();
return resultList;
} catch (Exception e) {
System.out.println("Error : " + e.getMessage());
}
return null;
}
Now, I want to display the ArrayList above in my JTable.
DefaultTableModel model = new DefaultTableModel();
ArrayList<Object> obj = this.getAll(); //call the method above
// How to insert the records above.
tableResult.setModel(model);
The problem is, there is an error while inserting an ArrayList in a JTable. I tried to cast ArrayList to Object[] but it has also an error.
Does anybody know?

search between dates how to show in jtable

Here is code, i am using 2 jdatechooser and i put the codes in a button. I am also not sure if the query is correct.
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
try
{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String url="jdbc:sqlserver://USER-PC:1433;databaseName=tblgg";
String userr="sa";
String passs="1234";
Connection con=DriverManager.getConnection(url,userr,passs);
java.util.Date first = dt1.getDate();
java.util.Date second = dt2.getDate();
String sql="SELECT * FROM tbl_sale WHERE date between '"+ first+"'and
'"+second+"'";
PreparedStatement pst= con.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
tblsale.setModel(DbUtils.resultSetToTableModel(rs));
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null, e);
}
}
Okay i edit my code. xD now something is happening but nothing is showing up.
To correct your lack of prepared statement usage. Try this
Resuse your connection
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String url="jdbc:sqlserver://USER-PC:1433;databaseName=tblgg";
String userr="sa";
String passs="1234";
Connection con=DriverManager.getConnection(url,userr,passs);
ResultSet result = null;
String sql2 = "select\n" +
"*\n" +
"from student\n" +
"where date(first) > ? and date(second) < ?";
PreparedStatement ps1 = con.prepareStatement( sql2, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY) ;
ps1.setObject (1 , startDatePicker.getModel().getValue());
ps1.setObject (2 , endDatePicker.getModel().getValue());
result = ps1.executeQuery();
// get number of rows
result.last();
numRows = result.getRow();
result.first();
//Get metadata object for result
ResultSetMetaData meta = result.getMetaData();
// create an arry of string for the colum names
colNames = new String[meta.getColumnCount()];
// store column names in the new col names array
for( int i = 0; i< meta.getColumnCount(); i++)
{
//get column name
colNames[i] = meta.getColumnLabel(i+1);
}
// create 2 d string array for table data
tableData = new String [numRows][meta.getColumnCount()];
// store columns in the data
for ( int row = 0 ; row < numRows; row++)
{
for (int col = 0; col < meta.getColumnCount(); col++)
{
tableData[row][col]= result.getString(col + 1);
}
result.next();
}
// close statement
ps1.close();
connection.close();
System.out.println("Data Table Loaded.");
}
To show the created result data set you use these lines
JTable table = new JTable(tableData,colNames);
JScrollPane scrollPane = new JScrollPane(table);
Don't forget to add the scroll pane to your JPanel
panel.add(scrollPane);

JTable missing last column name

i have created jtable but it doesn't show the last column name i don't know what i did wrong in code database have 4 columns id , name, fathername and phone number but jtable only show 3 columns.
public void load() {
try {
DBO db = new DBO();
con = db.connect();
String sql = "Select * from personinfo";
PreparedStatement pst = con.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();
DefaultTableModel tb = new DefaultTableModel();
Vector col = new Vector();
for (int i = 1; i < count; i++) {
col.addElement(rsmd.getColumnName(i));
}
tb.setColumnIdentifiers(col);
while (rs.next()) {
Vector rows = new Vector();
for (int j = 1; j < rsmd.getColumnCount(); j++) {
rows.addElement(rs.getString(j));
}
tb.addRow(rows);
PersonTable.setModel(tb);
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex);
}
}
I think you should use
pst.setString(1, "%"+name.getText()+"%");
when creating a prepared statement ? is used to replace bind variables. Values which you are not using as bind variables cannot be used the way you want, in this case using like. You can most probably go through this PreparedStatement IN clause alternatives?
Your question is quiet easily a duplicate Using “like” wildcard in prepared statement

Fill a Swing table with some data from MySQL DB

I need to fill a Swing table with some data from MySQL DB. The problem is that the table does not display all the columns (i.e. a.aircraftType and b.aircraftCategory). In Debug mode I checked that the query returns correct data. So, why finally some columns are not displayed?
private JTable tbArrivals;
private QueryTableModelFS mdArrivals;
mdArrivals = new QueryTableModelFS();
tbArrivals = new JTable(mdArrivals);
private void fillArrivals() {
mdArrivals.setHost(url); mdArrivals.setDB(db); mdArrivals.setLogin(login); mdArrivals.setPassw(passw);
String query;
query = "SELECT a.id,a.flightNum_arr,a.from_ICAO,a.ETA,a.pkId,a.aircraftType,b.aircraftCategory " +
"FROM flightschedule a, aircrafts b " +
"WHERE a.aircraftType = b.aircraftType;";
mdArrivals.setQuery(query);
}
public void setQuery(String query) {
cache = new Vector();
try {
// Execute the query and store the result set and its metadata
Connection con = getConnection();
Statement statement = con.createStatement();
ResultSet rs = statement.executeQuery(query);
ResultSetMetaData meta = rs.getMetaData();
colCount = meta.getColumnCount();
// Rebuild the headers array with the new column names
headers = new String[colCount];
for (int h = 1; h <= colCount; h++) {
headers[h - 1] = meta.getColumnName(h);
}
while (rs.next()) {
String[] record = new String[colCount];
for (int i = 0; i < colCount; i++) {
record[i] = rs.getString(i + 1);
}
cache.addElement(record);
}
fireTableChanged(null);
rs.close();
if (con.getAutoCommit() != false) {
con.close();
}
} catch (Exception e) {
cache = new Vector();
e.printStackTrace();
}
}
I can't tell what how your TableModel works (it looks like you might be using the DefaultTableModel), but I would suggest using Vectors instead of Arrays to get the data from your ResultSet. Right now your code is very confusing. In one loop you are using (i - 1) to access the data. In the next loop you are using (i + 1). I know the reason is because Arrays are 0 based and the ResultSet is 1 based.
When you use a Vector your loops can just start with 1 and then you just use the addElement() method to add the data to the Vector so your code is not concerned with matching indexes.
See Table From Database Example in Table From Database.

ResultSet in JTable

How to display ResultSet in JTable. i am using this code
String [] record= new
String[ColCount];
for (i=0; i<ColCount; i++)
{
record[i]=rset1.getString(i+1);
}
cell[i] = rset1.getString("loginname");
cell[i] = rset1.getString( "role");
System.out.println(cell[i][0]);
//ItemGroup = rset1.getString( "Status");
}
System.out.println(ItemCode);
JTable jt = new JTable(
cell[i], headers);
but I get only one row which is lastly inserted to database.
You need to put a while loop around your code to iterate over the result set. eg,
while(rset1.next())
{
//do something
}
The code that you have listed is incomplete/incomprehensible, but the code below shows how to take a ResultSet with an arbitrary number of columns and display its contents in a JTable.
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
private void viewTable(){
//Perform database query here, which will open a Connection to the database
//Assume we use the above query to populate a ResultSet results
//Get information about the ResultSet
ResultSetMetaData metaData = results.getMetaData();
//Gets the number of columns in results
int columnCount = metaData.getColumnCount();
//Gets the name of each column in results
String[] columnNames = new String[columnCount];
for(int i = 0; i < columnNames.length; i++){
columnNames[i] = metaData.getColumnLabel(i+1);
}
//You can use a String[] to keep track of the rows if you know the #
//# of rows in the ResultSet, this implementation assumes that we don't
//This ArrayList will keep track of each row in results (each row is
//represented by a String[]
ArrayList<String[]> rows = new ArrayList<>();
while(results.next()){
//Fetch each row from the ResultSet, and add to ArrayList of rows
String[] currentRow = new String[columnCount];
for(int i = 0; i < columnCount; i++){
//Again, note that ResultSet column indecies start at 1
currentRow[i] = results.getString(i+1);
}
rows.add(currentRow);
}
//Close Connection to the database here
String[][] rowsArray = new String[rows.size()][columnCount];
rowsArray = rows.toArray(rowsArray);
table = new JTable(rowsArray, columnNames);
}

Categories

Resources