How to fetch entire row as array of objects with JDBC - java

I have to make a 'query' method for my class which accesses MySQL thru' JDBC.
The input parameter to the method is a full SQL command (with values included), so I don't know the names of columns to fetch out.
Some of the columns are strings, some others are integers, etc.
The method needs to return the value of type ArrayList<HashMap<String,Object>>
where each HashMap is 1 row, and the ArrayList contains all rows of result.
I'm thinking of using ResultSet.getMetaData().getColumnCount() to get the number of columns then fetch cell by cell out of the current row, but is this the only solution? any better ones?

I have the example code here, just in case anybody need it. ('Con' in the code is the standard JDBC connection).
//query a full sql command
public static ArrayList<HashMap<String,Object>>
rawQuery(String fullCommand) {
try {
//create statement
Statement stm = null;
stm = con.createStatement();
//query
ResultSet result = null;
boolean returningRows = stm.execute(fullCommand);
if (returningRows)
result = stm.getResultSet();
else
return new ArrayList<HashMap<String,Object>>();
//get metadata
ResultSetMetaData meta = null;
meta = result.getMetaData();
//get column names
int colCount = meta.getColumnCount();
ArrayList<String> cols = new ArrayList<String>();
for (int index=1; index<=Col_Count; index++)
cols.add(meta.getColumnName(index));
//fetch out rows
ArrayList<HashMap<String,Object>> rows =
new ArrayList<HashMap<String,Object>>();
while (result.next()) {
HashMap<String,Object> row = new HashMap<String,Object>();
for (String colName:cols) {
Object val = Result.getObject(colName);
row.put(colName,val);
}
rows.add(row);
}
//close statement
stm.close();
//pass back rows
return tows;
}
catch (Exception ex) {
System.out.print(ex.getMessage());
return new ArrayList<HashMap<String,Object>>();
}
}//raw_query

Related

Row_Number() in MySql result value Double, but in IBM Data Studio result Int

I want result value in java is Int like in IBM Data Studio, but in my case is java generate value in double, i don't know why?, Please help to fix it!
This my java code to generate Number in table
private void polDatToTab(ResultSet rs, JTable table) throws SQLException{
String[] colHead = new String[] {"No","NIK","Nama"};
DefaultTableModel tm = new DefaultTableModel();
ResultSetMetaData rsd = rs.getMetaData();
Vector<String> nameCol = new Vector<String>();
int kolCount = rsd.getColumnCount();
for(int i=0;i<colHead.length;i++){
nameCol.add(colHead[i]);
}
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while(rs.next()){
Vector<Object> vec = new Vector<Object>();
for(int j=1;j<=kolCount;j++){
vec.add(rs.getObject(j));
}
data.add(vec);
}
tm.setDataVector(data, nameCol);
table.setModel(tm);
}
This my java code to display Table in Gui
private void srcEmp(){
String srcE = "SELECT (#ROW_NUMBER:=#ROW_NUMBER + 1) AS No_Urut,NIK,NAMA FROM PAYROLL.KARYAWAN,"
+ "(SELECT #ROW_NUMBER:=0) AS T WHERE NAMA LIKE '%"+srcRes+"%'";
DbConnect co = new DbConnect();
co.connectDB();
try {
st = co.connection.createStatement();
ResultSet ul = st.executeQuery(srcE);
polDatToTab(ul, tabResSrc);
} catch (SQLException ex) {
Logger.getLogger(ResSrc.class.getName()).log(Level.SEVERE, null, ex);
}
}
This my sql code in IBM Data Studio generate true value in int
SELECT (#ROW_NUMBER:=#ROW_NUMBER + 1) AS No_Urut,NIK,NAMA
FROM PAYROLL.KARYAWAN,(SELECT #ROW_NUMBER:=0) AS T
WHERE NAMA LIKE '%"+srcRes+"%'
This my Result in Java Gui:
and This my Result in IBM Data Studio
Your polDatToTab method isn't generic, it looks like it's designed to work only with this particular resultset. I am jumping to that conclusion because of this line
String[] colHead = new String[] {"No","NIK","Nama"};
As such, you are aware that the first column is expected to be an int. Therefore,
vec.add(rs.getInt(1));
for(int j=2; j<=kolCount; j++){
vec.add(rs.getObject(j));
}
Does the trick

Add vector to existing jTable to show records in database

I have developed below code,
try{
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/online_store","username","password");
if(con != null){
String query = "SELECT * FROM expense";
rs = stmt.executeQuery(query);
ResultSetMetaData rsmt = rs.getMetaData();
int c = rsmt.getColumnCount();
Vector column = new Vector(c);
for(int i = 1; i <= c; i++) { column.add(rsmt.getColumnName(i)); }
Vector data = new Vector(); Vector row = new Vector();
while(rs.next())
{
row = new Vector(c);
for(int i = 1; i <= c; i++)
{
row.add(rs.getString(i));
}
data.add(row);
}
expense_table.add(data);
// expense_table.getColumnName(null);
JOptionPane.showMessageDialog(null, "get details from database");
}
}catch(SQLException ex){
System.out.println(ex);
}
My existing table's name is expense_table. I need to display all the records from database in this table without change its structure/without creating new table.Everything is ok except showing data(rows) vector in table which is " expense_table.add(data);" line. Please tell me is there any method to to this.
I need to display all the records from database in this table without change its structure/without creating new table.
So then you don't need to access the column names from the ResultSet. You just need to add new rows of data to the JTable. So get rid of the logic that creates the "column" Vector.
//expense_table.add(data);
You can't add a Vector to a JTable. There is no method that allows you to do this so get rid of that statement.
Instead you need to add the data to the DefaultTableModel one row at a time:
//data.add(row);
DefaultTableModel model = (DefaultTableModel)expense_table.getModel();
model.addRow( row );

ResultSet Data of every row store in other array index

I am new in JAVA, so kindly understand my question and please give your valuable and precise answer.
How to store resultset data in anohter array ? Should I use ArrayList etc. My code is just for example.
Statement stmt = null;
ResultSet query_rs;
String query = "SELECT * FROM my_table";
query_rs = stmt.executeQuery(query);
int counter_rs = 0;
ArrayList my_arr = new ArrayList();
while(query_rs.next())
{
//here I want to add one row data in array index
counter_rs++;
my_arr[counter_rs] = query_rs; //Store row data in particular array index
}
System.out.println(my_arr.toString()); //Show all data
P.S. My major line is my_arr[counter_rs] = query_rs;. Thanks in advance
my_arr is arraylist if you want to add any element my_arr.add(anyElement) or if you want to set any element in particular location use this set(int index, E element)
my_arr.set(0,anyElement);
Statement stmt = null;
ResultSet query_rs;
String query = "SELECT * FROM my_table";
query_rs = stmt.executeQuery(query);
int counter_rs = 0;
ArrayList my_arr = new ArrayList();
while(query_rs.next())
{
//here I want to add one row data in array index
my_arr.set(counter_rs,query_rs); //use this
// or
// my_arr.add(query_rs);
counter_rs++;
}
//System.out.println(my_arr.toString()); //Show all data
// use for loop to get all data
my_arr is ArrayList not array
ArrayList my_arr = new ArrayList();
use my_arr.add() not as my_arr[counter_rs] = query_rs;
If i understand your question, then i think you need to do the following:
First declare an arrayList with a RowType like >
ArrayList<DataRow> my_arr = new ArrayList<DataRow>(); // DataRow should hold the columns data.
Second : add each fetched row to the list.
while(query_rs.next())
{
DataRow row = // fill the row from the ResultSet
my_arr.add(row);
}
third : loop over the list and print the data;

Java ResultSet Missing Final Record if Where Clause included in SQL command

I have a very simple java application intended to reach into a db and pull out a resultset based on an input on a java form. However, any parameters added to the SQL Statement end with a loss of the final record in the recordset (though it does seem to pull the proper result.)
The below code results in my entire dataset, with example at the top (as expected.)
Name|Location|Details
A|Here|7854
A|There|7854
B|Here|8761
C|Gone|5312
public void actionPerformed(ActionEvent e) {
try {
String url = "jdbc:sqlserver://localhost:1433;DatabaseName=$DBname;user=$user;password=$password";
String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
Class.forName(driver).newInstance();
Connection dbconn = DriverManager.getConnection(url);
Statement stmt = dbconn.createStatement();
ResultSet rs;
rs = stmt.executeQuery("SELECT * from schema.table");
tblServers.setModel(buildTableModel(rs));
dbconn.close();
} catch (Exception f) {
System.err.println("Downloading Servers from the Database Failed! ");
System.err.println(f.getMessage());
}
}
private DefaultTableModel buildTableModel(ResultSet rs) throws SQLException {
ResultSetMetaData rsmetaData = rs.getMetaData();
//Get Column Names
int numCols = rsmetaData.getColumnCount();
Vector<String> columnNames = new Vector<String>();
for (int column = 1; column <= numCols; column++) {
columnNames.add(rsmetaData.getColumnName(column));
}
//Iterate through rows
Vector<Object> data = new Vector<Object>();
while (rs.next()) {
Vector<Object> rows = new Vector<Object>();
for (int colIndex = 1; colIndex <= numCols ; colIndex++) {
rows.add(rs.getObject(colIndex));
}
data.add(rows);
}
return new DefaultTableModel(data, columnNames);
}
}
);
Now if I change nothing but the SQL line to any variant with a "where" clause, like:
rs = stmt.executeQuery("SELECT * from schema.table where name = 'A'");
I get:
Name|Location|Details
A|Here|7854
Or if searched for B, I get no results:
Name|Location|Details
|||
Any ideas are appreciated; I'm sure this is something extremely simple.
#Sasha: Yes, I am sure I am getting 1 result. I have tried with many permutations and it always results in either a blank resultset (but with accurate headers) or headers, and resultset, minus the final row.
#PM77-1: As soon as the code spits back the return (data, ColumnNames) my JTable has the resultset visible to the user.
#Glenn: On your suggestion, I added System.out.println(data) and 'System.out.println(rs)' to just before the 'return new DefaultTableModel'. The output is [] and SQLServerResultSet:1, respectively
#JohnnyAW The results for that with a where clause are the same as my comment above - no "tests" appear in the syslog. When I remove the where clause, I get a bunch of syslog entries with "test" prefacing my records.
Correction: I get "testtesttest" to the sum of 8 tests, my entire testing recordset. One test gets missed when I have a Where clause.

Store rows of resultset in array of strings

I want to count the numbers of entries in resultset and then store these values in an array and pass this array to create a graph.
ResultSet rs = stmt.executeQuery( "SELECT distinct "+jTextField.getText()+" as
call from tablename"); // this statement will select the unique entries in a
particular column provided by jtextfield
int count=0;
while(rs.next())
{ ++count; } // This will count the number of entries in the result set.
Now I want to store the values of result set in an array of string. I used the following code
String[] row = new String[count];
while(rs.next())
{
for (int i=0; i <columnCount ; i++)
{
row[i] = rs.getString(i + 1);
}
}
Error : Invalid Descriptor Index.
Please suggest how to copy the result of resultset in array.
For example if I enter priority in jTextField , the result set will contain
priority1
priority2
priority3
In your first while loop you read all the entries in the ResultSet, so when executing the second while loop there's nothing else to read. Also, the index of ResultSet#getXxx starts at 1, not at 0. Also, since you don't know the amount of rows that you will read, it will be better using a List backed by ArrayList instead.
Considering these, your code should look like:
ResultSet rs = stmt.executeQuery( "SELECT distinct "+jTextField.getText()+
" as call from tablename");
List<String> results = new ArrayList<String>();
while(rs.next()) {
results.add(rs.getString(1));
}
Based in your comment, I extended the sample:
public List<String> yourRandomQuery(String columnName) {
Connection con = null;
ResultSet rs = null;
List<String> results = new ArrayList<String>();
try {
String baseQuery = "SELECT DISTINCT %s AS call FROM tablename";
con = ...; //retrieve your connection
ResultSet rs = stmt.executeQuery(String.format(baseQuery, columnName));
while(rs.next()) {
results.add(rs.getString(1));
}
} catch (SQLException e) {
//handle your exception
e.printStacktrace(System.out);
} finally {
closeResource(rs);
closeResource(con);
}
return results;
}
//both Connection and ResultSet interfaces extends from AutoCloseable interface
public void closeResource(AutoCloseable ac) {
try {
if (ac != null) {
ac.close();
}
} catch (Exception e) {
//handle this exception as well...
}
}
public void someMethod() {
//retrieve the results from database
List<String> results = yourRandomQuery(jTextField.getText());
//consume the results as you wish
//basic example: printing them in the console
for(String result : results) {
System.out.println(result);
}
}
Try this
ResultSet rs = stmt.executeQuery( "SELECT distinct "+jTextField.getText()+" as
call from tablename");
List<String> list=new ArrayList<>();
while(rs.next())
{
list.add(rs.getString(1));
}
Why not just create a HashSet<String> and write into that. Note that HashSet is unordered, just like your query. By using a collection that is of arbitrary size you don't need to determine the require dsize in advance.

Categories