Inserting a resultset into jtable directly - java

If is there any way to insert a resultset into jtable directly?

Bad idea.
You shouldn't be passing anything from the java.sql package out of your persistence tier.
You can certainly iterate over a ResultSet and load the contents into your DefaultTableModel. But I wouldn't recommend it.
Something like this:
public DefaultTableModel map(ResultSet resultSet) throws SQLException
{
DefaultTableModel defaultTableModel = new DefaultTableModel();
ResultSetMetaData meta = resultSet.getMetaData();
int numberOfColumns = meta.getColumnCount();
while (resultSet.next())
{
Object [] rowData = new Object[numberOfColumns];
for (int i = 0; i < rowData.length; ++i)
{
rowData[i] = resultSet.getObject(i+1);
}
defaultTableModel.addRow(rowData);
}
return defaultTableModel;
}

Related

Error when calling getColumnCount() from ResultSet metadata

I seem to be have a problem when trying to get the coulmn count from a resultset's metadata. THe error is Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: SQLite JDBC: inconsistent internal state.
THe idea is to use this table model to populate a JTable with the result from the database query. However when I do I get the above error.
The relevant code is:
public DefaultTableModel buildFlightModel()
throws SQLException {
query="SELECT Airline.AirlineName, Flight.FlightID, Flight.Location, Flight.Destination, Flight.ArriveTime, Flight.LeaveTime FROM Flight INNER JOIN Airline ON Airline.AirlineID=Flight.AirlineID;";
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:coursework.db");
stmt = c.createStatement();
rs=stmt.executeQuery(query);
while(rs.next()){
//System.out.println(s);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ResultSetMetaData metaData = rs.getMetaData();
// names of columns
Vector<String> columnNames = new Vector<String>();
int columnCount = metaData.getColumnCount();
for (int column = 1; column <= columnCount; column++) {
columnNames.add(metaData.getColumnName(column));
}
// data of the table
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while (rs.next()) {
Vector<Object> vector = new Vector<Object>();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
vector.add(rs.getObject(columnIndex));
}
data.add(vector);
}
return new DefaultTableModel(data, columnNames);
}
Any thoughts/ideas/help would be deeply appreciated. Thank you.
This exception is thrown when ResultSet.isclose() == true. Try to create a Clone of the MetaData before starting the Read-Loop.

JTable displaying the same row from Mysql table

I'm showing the method were the JTable is constructed, the error is when adding the rows inside the for (int i = 1; i <= numero_columnas; i++) loop, or the way the DefaultTableModel model = new DefaultTableModel(); is declared, I can't find the error.
public void verTablaTable (Connection db, String nombre) throws Exception{
Statement stmt=db.createStatement();
ResultSet sst_ResultSet = stmt.executeQuery("SELECT * FROM "+nombre);
ResultSetMetaData md = sst_ResultSet.getMetaData();
int numero_columnas = md.getColumnCount();
DefaultTableModel model = new DefaultTableModel();
for (int i=1;i<=numero_columnas; i++){
model.addColumn(md.getColumnName(i));
}
JTable tabla =new JTable(model);
DefaultTableModel model1 = (DefaultTableModel) tabla.getModel();
Vector row = new Vector();
row.setSize(numero_columnas);
while (sst_ResultSet.next()){
for (int i = 1; i <= numero_columnas; i++){
row.set(i-1,sst_ResultSet.getString(i));
}
model1.addRow(row);
}
tabla.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JScrollPane sp_vertabla = new JScrollPane(tabla);
sp_vertabla.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
sp_vertabla.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
sp_vertabla.setBounds(50,30,700,500);
JPanel cont_vertabla = new JPanel(null);
cont_vertabla.setPreferredSize(new Dimension(750,600));
cont_vertabla.add(sp_vertabla);
f_vertabla.setContentPane(cont_vertabla);
f_vertabla.pack();
f_vertabla.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//f_vertabla.setResizable(false);
f_vertabla.setVisible(true);
f_vertabla.addWindowListener(this);
}
this is the way the JTable looks
The row listed in the above pic, is the last one in the mysql table
Try adding the line
Vector row = new Vector();
inside the while loop.

JTable missing first row

i already searched the whole web but I can't find a solution, so i decided to ask here.
Following problem: I am using those 2 methods to populate a JTable with a DefaultTableModel, the ResultSet shows the right amount of data entries (i already searched it with System.out.println) but the JTable always misses the first row
I am using a method to get a ResultSet like this:
public static JTable DBCFillBTableAuftraege() {
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
JTable table = null;
try {
con = DriverManager.getConnection(host, uName, uPass);
stmt = con.createStatement( );
rs = stmt.executeQuery("SELECT a.auftrags_nr, k.firma, a.auftragsdatum, a.lieferdatum, a.rechnungsbetrag, k.name, k.strasse, k.plz, k.ort from auftrag a join kunde k on k.kunden_nr = a.kunden_nr ");
while (rs.next()) {
table = new JTable(tableModel(rs));
return table;
}
} catch (SQLException e) {
System.out.println(e);
} finally {
try {
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return table;
}
Which then calls this method:
public static DefaultTableModel TableModel(ResultSet rs)
throws SQLException {
ResultSetMetaData metaData = rs.getMetaData();
System.out.println(rs);
// names of columns
Vector<String> columnNames = new Vector<String>();
int columnCount = metaData.getColumnCount();
for (int column = 1; column <= columnCount; column++) {
columnNames.add(metaData.getColumnName(column));
}
// data of the table
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while (rs.next()) {
Vector<Object> vector = new Vector<Object>();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
vector.add(rs.getObject(columnIndex));
}
data.add(vector);
}
return new DefaultTableModel(data, columnNames);
}
In my main:
TableAuftrag = DBCFillBTableAuftraege();
scpaneBestell.setViewportView(TableAuftrag);
It works fine, it is showing me my column headers and the data, except one problem:
It is always missing the first row and starts with the second one
Your problem starts here...
// Move to first row...
while (rs.next()) {
table = new JTable(tableModel(rs));
return table;
}
and manifests
// Move to second row and beyond...
while (rs.next()) {
Vector<Object> vector = new Vector<Object>();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
vector.add(rs.getObject(columnIndex));
}
data.add(vector);
}
Basically, in the first while (rs.next()), you move to the first row, but in the second while (rs.next()) you move to the second row, without handling the first...
It might be better to simply pass the ResultSet directly to the TableModel.
Convention would also suggest that you probably should not need to create a new JTable, but instead, just create a new TableModel and apply to a pre-existing table
while (rs.next()) {
table = new JTable(tableModel(rs));
return table;
}
You're consuming the first row of the result set here, and then call tableModel(), which consumes the other rows. The while loop is useless. Just do
table = new JTable(tableModel(rs));
return table;

Retrieving Mysql data to the JTable in Netbeans

I used this coding to retrieve the Mysql data to the JTable.but it returns only the first data row of the relevant table of the database but then again it count the number of rows correctly and all it returns is same copy of the first row equal to the row count.
I'm new to Java and netbeans environment so if someone can help me to solve this problem i'll be really grateful and thank you in advance :)
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/data", "root", "1122");
Statement stat = (Statement) con.createStatement();
stat.executeQuery("select * from reserve;");
ResultSet rs=stat.getResultSet();
ResultSetMetaData md = rs.getMetaData();
int columnCount = md.getColumnCount();
Vector data=new Vector();
Vector columnNames= new Vector();
Vector row = new Vector(columnCount);
for(int i=1;i<=columnCount;i++){
columnNames.addElement(md.getColumnName(i));
}
while(rs.next()){
for(int i=1; i<=columnCount; i++){
row.addElement(rs.getObject(i));
}
data.addElement(row);
}
DefaultTableModel model = new DefaultTableModel(data, columnNames);
jTable1.setModel( model );
You keep adding to the same Vector row. Try creating a new instance for each iteration of rs.next().
You have an error with your Vector. Consider using something like :
Vector data = new Vector(columnCount);
Vector row = new Vector(columnCount);
Vector columnNames = new Vector(columnCount);
for (int i = 1; i <= columnCount; i++) {
columnNames.addElement(md.getColumnName(i));
}
while (rs.next()) {
for (int i = 1; i <= columnCount; i++) {
row.addElement(rs.getObject(i));
}
data.addElement(row);
row = new Vector(columnCount); // Create a new row Vector
}
DefaultTableModel model = new DefaultTableModel(data, columnNames);
jTable1.setModel( model );

Efficient way to Handle ResultSet in Java

I'm using a ResultSet in Java, and am not sure how to properly close it. I'm considering using the ResultSet to construct a HashMap and then closing the ResultSet after that. Is this HashMap technique efficient, or are there more efficient ways of handling this situation? I need both keys and values, so using a HashMap seemed like a logical choice.
If using a HashMap is the most efficient method, how do I construct and use the HashMap in my code?
Here's what I've tried:
public HashMap resultSetToHashMap(ResultSet rs) throws SQLException {
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
HashMap row = new HashMap();
while (rs.next()) {
for (int i = 1; i <= columns; i++) {
row.put(md.getColumnName(i), rs.getObject(i));
}
}
return row;
}
Iterate over the ResultSet
Create a new Object for each row, to store the fields you need
Add this new object to ArrayList or Hashmap or whatever you fancy
Close the ResultSet, Statement and the DB connection
Done
EDIT: now that you have posted code, I have made a few changes to it.
public List resultSetToArrayList(ResultSet rs) throws SQLException{
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
ArrayList list = new ArrayList(50);
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);
}
return list;
}
I just cleaned up RHT's answer to eliminate some warnings and thought I would share. Eclipse did most of the work:
public List<HashMap<String,Object>> convertResultSetToList(ResultSet rs) throws SQLException {
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
List<HashMap<String,Object>> list = new ArrayList<HashMap<String,Object>>();
while (rs.next()) {
HashMap<String,Object> row = new HashMap<String, Object>(columns);
for(int i=1; i<=columns; ++i) {
row.put(md.getColumnName(i),rs.getObject(i));
}
list.add(row);
}
return list;
}
RHT pretty much has it. Or you could use a RowSetDynaClass and let someone else do all the work :)
this is my alternative solution, instead of a List of Map, i'm using a Map of List.
Tested on tables of 5000 elements, on a remote db, times are around 350ms for eiter method.
private Map<String, List<Object>> resultSetToArrayList(ResultSet rs) throws SQLException {
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
Map<String, List<Object>> map = new HashMap<>(columns);
for (int i = 1; i <= columns; ++i) {
map.put(md.getColumnName(i), new ArrayList<>());
}
while (rs.next()) {
for (int i = 1; i <= columns; ++i) {
map.get(md.getColumnName(i)).add(rs.getObject(i));
}
}
return map;
}
A couple of things to enhance the other answers. First, you should never return a HashMap, which is a specific implementation. Return instead a plain old java.util.Map. But that's actually not right for this example, anyway. Your code only returns the last row of the ResultSet as a (Hash)Map. You instead want to return a List<Map<String,Object>>. Think about how you should modify your code to do that. (Or you could take Dave Newton's suggestion).
i improved the solutions of RHTs/Brad Ms and of Lestos answer.
i extended both solutions in leaving the state there, where it was found.
So i save the current ResultSet position and restore it after i created the maps.
The rs is the ResultSet, its a field variable and so in my solutions-snippets not visible.
I replaced the specific Map in Brad Ms solution to the gerneric Map.
public List<Map<String, Object>> resultAsListMap() throws SQLException
{
var md = rs.getMetaData();
var columns = md.getColumnCount();
var list = new ArrayList<Map<String, Object>>();
var currRowIndex = rs.getRow();
rs.beforeFirst();
while (rs.next())
{
HashMap<String, Object> row = new HashMap<String, Object>(columns);
for (int i = 1; i <= columns; ++i)
{
row.put(md.getColumnName(i), rs.getObject(i));
}
list.add(row);
}
rs.absolute(currRowIndex);
return list;
}
In Lestos solution, i optimized the code. In his code he have to lookup the Maps each iteration of that for-loop. I reduced that to only one array-acces each for-loop iteration. So the program must not seach each iteration step for that string-key.
public Map<String, List<Object>> resultAsMapList() throws SQLException
{
var md = rs.getMetaData();
var columns = md.getColumnCount();
var tmp = new ArrayList[columns];
var map = new HashMap<String, List<Object>>(columns);
var currRowIndex = rs.getRow();
rs.beforeFirst();
for (int i = 1; i <= columns; ++i)
{
tmp[i - 1] = new ArrayList<>();
map.put(md.getColumnName(i), tmp[i - 1]);
}
while (rs.next())
{
for (int i = 1; i <= columns; ++i)
{
tmp[i - 1].add(rs.getObject(i));
}
}
rs.absolute(currRowIndex);
return map;
}
Here is the code little modified that i got it from google -
List data_table = new ArrayList<>();
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection(conn_url, user_id, password);
Statement stmt = con.createStatement();
System.out.println("query_string: "+query_string);
ResultSet rs = stmt.executeQuery(query_string);
ResultSetMetaData rsmd = rs.getMetaData();
int row_count = 0;
while (rs.next()) {
HashMap<String, String> data_map = new HashMap<>();
if (row_count == 240001) {
break;
}
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
data_map.put(rsmd.getColumnName(i), rs.getString(i));
}
data_table.add(data_map);
row_count = row_count + 1;
}
rs.close();
stmt.close();
con.close();
public static List<HashMap<Object, Object>> GetListOfDataFromResultSet(ResultSet rs) throws SQLException {
ResultSetMetaData metaData = rs.getMetaData();
int count = metaData.getColumnCount();
String[] columnName = new String[count];
List<HashMap<Object,Object>> lst=new ArrayList<>();
while(rs.next()) {
HashMap<Object,Object> map=new HashMap<>();
for (int i = 1; i <= count; i++){
columnName[i-1] = metaData.getColumnLabel(i);
map.put(columnName[i-1], rs.getObject(i));
}
lst.add(map);
}
return lst;
}

Categories