public void search() throws Exception{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String url = "jdbc:odbc:******";
String user = "*****";
String pass = "*****";
Connection con = DriverManager.getConnection(url, user, pass);
Statement state = con.createStatement();
ResultSet rs = state.executeQuery("");
ResultSetMetaData rsmetadata = rs.getMetaData();
int columns = rsmetadata.getColumnCount();
DefaultTableModel dtm = new DefaultTableModel();
Vector column_name = new Vector();
Vector data_rows = new Vector();
for (int i=1; i<columns;i++){
column_name.addElement(rsmetadata.getColumnName(i));
}
dtm.setColumnIdentifiers(column_name);
while(rs.next()){
data_rows = new Vector();
for (int j=1; j<columns; j++){
data_rows.addElement(rs.getString(j));
}
dtm.addRow(data_rows);
}
tblPatient.setModel(dtm);
}
On my ResultSet rs = state.executeQuery() I used this SQL
"SELECT "
+ "pIDNo AS 'Patient ID',"
+ "pLName AS 'Last Name',"
+ "pFName AS 'First Name',"
+ "pMI AS 'M.I.',"
+ "pSex AS 'Sex',"
+ "pStatus AS 'Status',"
+ "pTelNo AS 'Contact No.',"
+ "pDocID AS 'Doctor ID',"
+ "pAddr AS 'St. No.',"
+ "pStreet AS 'St. Name',"
+ "pBarangay AS 'Barangay',"
+ "pCity AS 'City',"
+ " pProvince AS 'Province',"
+ " pLNameKIN AS 'Last Name',"
+ "pFNameKIN AS 'First Name',"
+ "pMIKIN AS 'M.I.',"
+ "pRelationKIN AS 'Relation',"
+ "pTotalDue AS 'Total Due'"
+ " FROM dbo.Patients");
First I run this line (pTotalDue didn't come up to jTable.)
And on my second attempt to display it I do this:
"SELECT pTotalDue AS 'Total Due' FROM dbo.Patients"
Now I tried this one, and I think something's really wrong about my codes. BTW this column has MONEY DATA TYPE
why does it didn't show to my JTable? could anyone tell me what is the problem with my codes?
(Problem in the answer that has given to me)
public class QueryOnWorkerThread extends SwingWorker{
private final JTable tableToUpdate;
public QueryOnWorkerThread( JTable aTableToUpdate ) {
tableToUpdate = aTableToUpdate;
}
#Override
protected TableModel doInBackground() throws Exception {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String url = "jdbc:odbc:OJT_dsn";
String user = "sa";
String pass = "";
Connection con = DriverManager.getConnection( url, user, pass );
Statement state = con.createStatement();
ResultSet rs = state.executeQuery("");
ResultSetMetaData rsmetadata = rs.getMetaData();
int columns = rsmetadata.getColumnCount();
DefaultTableModel dtm = new DefaultTableModel();
Vector column_name = new Vector();
Vector data_rows;
//note the <= check iso the < check (as the count starts at index 1)
for (int i=1; i<=columns;i++){
column_name.addElement(rsmetadata.getColumnName(i));
}
dtm.setColumnIdentifiers(column_name);
while(rs.next()){
data_rows = new Vector();
//note the <= check iso the < check (as the count starts at index 1)
for (int j=1; j<=columns; j++){
data_rows.addElement(rs.getString(j));
}
dtm.addRow(data_rows);
}
return dtm;
}
`#Override <<<<<<<<<<<<<<<<<<<<< I have a problem here it says : done() in javaapplication25.SearchPatient.QueryWorkerThread cannot override done() in javax.swing.SwingWorker overriden method does not throw java.lang.Exception , what does it mean sir?`
protected void done() throws Exception{
//this method runs on the EDT, so it is safe to update our table here
try {
tableToUpdate.setModel( get() );
} catch ( InterruptedException e ) {
throw new RuntimeException( e );
} catch ( ExecutionException e ) {
throw new RuntimeException( e );
}
}
try this
DefaultTableModel dtm=(DefaultTableModel)table.getModel();
for (int i = dtm.getRowCount() - 1; i > -1; i--) {
dtm.removeRow(i);
}
Connection con = DriverManager.getConnection(url, user, pass);
Statement state = con.createStatement();
ResultSet rs = state.executeQuery("Your SQL Query");
while(rs.next())
{
String str1=rs.getString(1);
String str2=rs.getString(2);
String str3=rs.getString(3);
String str4=rs.getString(4);
String str5=rs.getString(5);
:
:
:
dtm.addRow(new Object[]{str1,str2,str3,str4,str5});
}
In you loops, your exit condition is
j<columns
this means thant the last column will never be recovered. try this insted:
for (int j=1; j<=columns; j++)
The fact that your last column does not appear is probably related to your loop statements, as already indicated by #Joan.
There are however more issues with this code. You should only update Swing components on the Event Dispatch Thread, and on that Thread you should not perform long running operations. In short, mixing SQL queries and updates of the JTable should not happen on the same thread. Consult the Concurrency in Swing guide for more info.
Using a SwingWorker could solve this issue:
public class QueryOnWorkerThread extends SwingWorker<TableModel, Void>{
private final JTable tableToUpdate;
public QueryOnWorkerThread( JTable aTableToUpdate ) {
tableToUpdate = aTableToUpdate;
}
#Override
protected TableModel doInBackground() throws Exception {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String url = "jdbc:odbc:******";
String user = "*****";
String pass = "*****";
Connection con = DriverManager.getConnection( url, user, pass );
Statement state = con.createStatement();
ResultSet rs = state.executeQuery("");
ResultSetMetaData rsmetadata = rs.getMetaData();
int columns = rsmetadata.getColumnCount();
DefaultTableModel dtm = new DefaultTableModel();
Vector column_name = new Vector();
Vector data_rows;
//note the <= check iso the < check (as the count starts at index 1)
for (int i=1; i<=columns;i++){
column_name.addElement(rsmetadata.getColumnName(i));
}
dtm.setColumnIdentifiers(column_name);
while(rs.next()){
data_rows = new Vector();
//note the <= check iso the < check (as the count starts at index 1)
for (int j=1; j<=columns; j++){
data_rows.addElement(rs.getString(j));
}
dtm.addRow(data_rows);
}
return dtm;
}
#Override
protected void done() {
//this method runs on the EDT, so it is safe to update our table here
try {
tableToUpdate.setModel( get() );
} catch ( InterruptedException e ) {
throw new RuntimeException( e );
} catch ( ExecutionException e ) {
throw new RuntimeException( e );
}
}
}
The SwingWorker can be started by calling
QueryOnWorkerThread worker = new QueryOnWorkerThread( tblPatient );
worker.execute();
Note how I changed the loops in your code
Try getting that column via ResultSet.getBigDecimal() rather than via ResultSet.getString(). Then put your retrieved BigDecimal.toPlainString() into your table cell.
Example:
data_rows.addElement(rs.getBigDecimal("pTotalDue").toPlainString());//Assuming your select returns a pTotalDue Column (e.g. SELECT pTotalDue,... FROM ...)
Try to Use an TableCellRenderer.
Implement the Renderer and render the Column with the Money Type in the form you wish.
Regards,
HL
Related
I want to get the data from the two dates in MySQL and display only the range, however even if it is blank it won't display anything. Moreover, even if I change the simple date format to MM/dd/yyyy the table only display one row and date even I have 2 rows in the database daated 07/14/2022
Here is my code
private void table_stocks(String date_from, String date_to) {
try {
int table;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
con = DriverManager.getConnection(url, username, password);
if(date_from.equals("") || date_to.equals("")){
pst = con.prepareStatement("SELECT `sales_number`, `date`, `amount_due` FROM `dnk_database`.`sales`;");
}
else{
pst = con.prepareStatement("SELECT `sales_number`, `date`, `amount_due`, SUM(`amount_due`) AS `total_sales` FROM `dnk_database`.`sales` WHERE `date` BETWEEN ? AND ?;");
pst.setString(1, date_from);
pst.setString(2, date_to);
}
ResultSet rs = pst.executeQuery();
ResultSetMetaData rsd = rs.getMetaData();
table = rsd.getColumnCount();
DefaultTableModel load = (DefaultTableModel)jTable_salesValue.getModel();
load.setRowCount(0);
while(rs.next()) {
Vector v2 = new Vector();
for(int i = 1; i <= table; i++){
v2.add(rs.getString("sales_number"));
v2.add(rs.getString("date"));
v2.add(rs.getString("amount_due"));
}
load.addRow(v2);
}
} catch (ClassNotFoundException ex) {
Logger.getLogger(Add_Items.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (SQLException ex) {
Logger.getLogger(Add_Items.class.getName()).log(Level.SEVERE, null, ex);
}
}
Also, want to display the SUM of the amount_due column from my SQL to a textfield and I don't know where to place this code
if (rs.next()==true) {
String sum_total = rs.getString("total_sales");
jTextField_totalSales.setText(sum_total);
}
You can accumulate the sum to a variable before the while loop, I assume you are using integer data type, then inside the loop sum the value. After the while loop is done display in the text field
int sumTotal = 0;
while(rs.next()) {
Vector v2 = new Vector();
for(int i = 1; i <= table; i++){
v2.add(rs.getString("sales_number"));
v2.add(rs.getString("date"));
v2.add(rs.getString("amount_due"));
sumTotal += rs.getString("amount_due") == null? 0 : Integer.parseInt(rs.getString("amount_due"));
}
load.addRow(v2);
jTextField_totalSales.setText(sumTotal);
}
I asked this question on Stackoverflow on calling a stored procedure with IN and OUT parameters using StoredProcedureItemReader, but unfortunately, the answer was that such support isn't available, and I have to implement my own ItemReader.
Calling stored procedure with an IN and OUT Parameter from Spring Batch
So, I went ahead and wrote this sample code. I am able to call my stored procedure, however, it's being called infinite times whenever the read() method is called in a Batch step.
#Component
public class MyStoredProcItemReader implements ItemReader<MyRow> {
#Autowired DataSource dataSource;
#Override
public MyRow read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
try (
Connection conn = dataSource.getConnection();
CallableStatement statement = conn.prepareCall("{call GetNameCountByFname(?, ?)}");
) {
statement.setString(1, "bob");
statement.registerOutParameter(2, Types.INTEGER);
boolean hadResults = statement.execute();
Integer totalBook = (Integer) statement.getObject(2, Integer.class);
System.out.println("Total: " + totalBook);
Map<String, Object> results = new HashMap<>();
// ResultSet resultSet = statement.getResultSet();
// ResultSetMetaData metaData = resultSet.getMetaData();
// int col = 1;
// while (resultSet.next())
// {
// String columnName = metaData.getColumnName(col);
// Object value = resultSet.getObject(col);
// results.put(columnName, value);
// ++col;
// }
//
// int columnCount = metaData.getColumnCount();
// for (int col = 1; col <= columnCount; col++) {
// String columnName = metaData.getColumnName(col);
// Object value = resultSet.getObject(col);
//
// results.put(columnName, value);
// }
while (hadResults) {
ResultSet resultSet = statement.getResultSet();
// process result set
while (resultSet.next()) {
String title = resultSet.getString("id");
String description = resultSet.getString("name");
int rating = resultSet.getInt("LastSynchronizationVersion");
System.out.println(
"| " + title + " | " + description + " | " + rating + " |");
}
hadResults = statement.getMoreResults();
}
statement.close();
MyRow row = new MyRow();
row.tableName = "tableName";
row.row = results;
return row;
} catch (SQLException ex) {
ex.printStackTrace();
}
return null;
}
}
What did I do wrong, and what's the right approach?
I am able to call my stored procedure, however, it's being called infinite times whenever the read() method is called in a Batch step.
An ItemReader is expected to return null at some point to signal the end of the data set. This is how the driving chunk-oriented step knows that there is no more data to read and gives the control to the enclosing job to move to the next step (if any).
So in your case, you need to make sure your item reader returns null at some point.
I create this code for get column name in sql databases. But now I ant to modify above code for get all table data with column name. Then get all data and convert to jsonarray and pass. How I modify this code for get all table data with column name.
#Override
public JSONArray getarray(String sheetName) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "");
con.setAutoCommit(false);
PreparedStatement pstm = null;
Statement stmt = null;
//-----------------------Drop earliye table -------------------------------------------------------------
try {
String sqldrop = "select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME='" + sheetName.replaceAll(" ", "_") + "'";
System.out.println(sqldrop);
PreparedStatement mypstmt = con.prepareStatement(sqldrop);
ResultSet resultSet = mypstmt.executeQuery();
JSONArray jsonArray = new JSONArray();
while (resultSet.next()) {
int total_rows = resultSet.getMetaData().getColumnCount();
JSONObject obj = new JSONObject();
for (int i = 0; i < total_rows; i++) {
String columnName = resultSet.getMetaData().getColumnLabel(i + 1).toLowerCase();
Object columnValue = resultSet.getObject(i + 1).toString().replaceAll("_", " ");
// if value in DB is null, then we set it to default value
if (columnValue == null) {
columnValue = "null";
}
/*
Next if block is a hack. In case when in db we have values like price and price1 there's a bug in jdbc -
both this names are getting stored as price in ResulSet. Therefore when we store second column value,
we overwrite original value of price. To avoid that, i simply add 1 to be consistent with DB.
*/
if (obj.has(columnName)) {
columnName += "1";
}
obj.put(columnName, columnValue);
}
jsonArray.put(obj);
}
mypstmt.close();
con.commit();
return jsonArray;
} catch (Exception e) {
System.out.println("There is no exist earlyer databases table!..... :( :( :( **************** " + sheetName.replaceAll(" ", "_"));
}
//----------------------------------------------------------------------------
} catch (ClassNotFoundException e) {
System.out.println(e);
} catch (SQLException ex) {
Logger.getLogger(PassArrayDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("%%%%%%%%%%");
return null;
}
My target is get all data with column name and above data pass html page as a json. So if you have any method for get all data with column name is suitable for me.
// code starts here
// This method retrieves all data from a mysql table...
public void retrieveAllData( String host, String user, String pass, String query) {
JTextArea textArea = new JTextArea();
try(
Connection connection = DriverManager.getConnection( host, user, pass )
Statement statement = connection.createStatement()
ResultSet resultSet = statement.executeQuery(query)) {
ResultSetMetaData metaData = resultSet.getMetaData();
int totalColumns = metaData.getColumnCount();
for( int i = 1; i <= totalColumns; i++ ) {
textArea.append( String.format( "%-8s\t", metaData.getColumnName(i) ) );
}
textArea.append( "\n" );
while( resultSet.next() ) {
for( int i = 1; i <= totalColumns; i++ ) {
Object object = resultSet.getObject(i).toString();
textArea.append( String.format("%-8s\t", object) );
}
textArea.append( "\n" );
}
}
}
I coded Auto Suggesting Combo boxes. Functionality is,
*when a user type the first letter in either combo box , data retrieves from the MySQL database and show in a popup list, when a user click on a suggested item ,then press Add button that item added to the J Table and clears the combo boxes
But when I select another item from the combo box and click Add button before added one disappears
*How can I keep Both or many items in the J Table according to above situation *
I'll post my code:
private void NamecomboActionPerformed(java.awt.event.ActionEvent evt) {
String drugname = (String) Namecombo.getSelectedItem();
try{
String name = "SELECT * FROM druginfo WHERE ItemName LIKE '"+drugname+"%'";
PreparedStatement pstmt = conn.prepareStatement(name);
ResultSet rs = pstmt.executeQuery();
while (rs.next()){
IDcombo.setSelectedItem(rs.getString("ItemID"));
}
}catch(Exception e){
JOptionPane.showMessageDialog(null,"error "+ e);
}
}
private void IDcomboActionPerformed(java.awt.event.ActionEvent evt) {
String drugid = (String) IDcombo.getSelectedItem();
try{
String name = "SELECT * FROM druginfo WHERE ItemID LIKE '"+drugid+"%'";
PreparedStatement pstmt = conn.prepareStatement(name);
ResultSet rs = pstmt.executeQuery();
while (rs.next()){
Namecombo.setSelectedItem(rs.getString("ItemName"));
}
}catch(Exception e){
JOptionPane.showMessageDialog(null,"error "+ e);
}
try{
String exp = "SELECT ExpDate FROM druginfo WHERE ItemID LIKE '"+drugid+"%'";
PreparedStatement pstmt = conn.prepareStatement(exp);
ResultSet rs2 = pstmt.executeQuery();
while (rs2.next()){
String date = rs2.getString("ExpDate");
exptxt.setText(date);
}
}catch(Exception e){
JOptionPane.showMessageDialog(null,"error "+ e);
}
}
add button action performed for adding item to JTable;
private void add_btnActionPerformed(java.awt.event.ActionEvent evt) {
String temp = (String) IDcombo.getSelectedItem();
String sql = "select ItemID,ItemName,CostPrice,InStock from druginfo where ItemID=?";
try {
pst=conn.prepareStatement(sql);
pst.setString(1, temp);
rs=pst.executeQuery();
tableSale.setModel(DbUtils.resultSetToTableModel(rs));
IDcombo.setSelectedItem(null);
Namecombo.setSelectedItem(null);
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex);
}
Add the current selection(resultset data) to JTable object without replacing the old data.
rs=pst.executeQuery();
addDataToTable(tableSale,DbUtils.resultSetToTableModel(rs));
IDcombo.setSelectedItem(null);
Namecombo.setSelectedItem(null);
//ADD this method
public void addDataToTable(JTable table,TableModel model) {
DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
DefaultTableModel resultSetModel = (DefaultTableModel) model;
for (int i = 0; i < resultSetModel.getRowCount(); i++) {
Vector row=new Vector();
for (int j = 0; j < resultSetModel.getColumnCount(); j++) {
row.addElement(resultSetModel.getValueAt(i, j));
}
tableModel.addRow(row);
}
tableModel.fireTableDataChanged();
}
This tableSale.setModel(DbUtils.resultSetToTableModel(rs)); will replace the old model with new model.So obviously datas will be lost.You have to add values to the existing model.I have added a snippet which will help you.
Replace tableSale.setModel(DbUtils.resultSetToTableModel(rs)); with addValuesToModel(DbUtils.resultSetToTableModel(rs));
addValuesToModel(DbUtils.resultSetToTableModel(rs));
public void addValuesToModel(TableModel resultModel) {
DefaultTableModel tmodel = (DefaultTableModel) tableSale.getModel();
DefaultTableModel rmodel = (DefaultTableModel) resultModel;
for (int i = 0; i < rmodel.getRowCount(); i++) {
Object[] row = new Object[rmodel.getColumnCount()];
for (int j = 0; j < rmodel.getColumnCount(); j++) {
row[j] = rmodel.getValueAt(i, j);
}
tmodel.addRow(row);
}
}
I am new to Java and I am practicing some new stuff.. I've started working with the database. therefore I made a to do list application with the MVC pattern.
In my Model I get all the results. In My view I try to output this data as a nice table. The problem is that I don't get any output except for a hardcoded piece of code..
here is the code of my view
JTable table = null;
public ToDoListView(ToDoListModel model) {
this.model = model;
setBackground(Color.WHITE);
JTable table = new JTable();
DefaultTableModel tableModel = new DefaultTableModel(new Object[][]{},new String[]{"To do","Date added"});
table.setModel(tableModel);
// this one below is outputted
tableModel.addRow(new Object[]{"something","1-1-2012"});
// this should give me all the results..
for(int i = 0; i < model.getRows().size(); i++) {
tableModel.addRow(model.getRows());
System.out.println("added");
}
add(table);
}
in my Model I have this
private Vector<String> rijen = new Vector<String>();
public void getValue() {
Connection con = null;
Statement st = null;
ResultSet rs = null;
try {
con = db.connectToAndQueryDatabase("test", "root", "root");
System.out.println("connection established");
st = con.createStatement();
String query = "SELECT id, item, datum FROM toDoList";
rs = st.executeQuery(query);
while(rs.next()) {
System.out.println(rs.getInt("id") + "\n" + rs.getString("item") + "\n" + rs.getDate("datum"));
rijen.add(rs.getInt("id") + "");
rijen.add(rs.getString("item"));
rijen.add(rs.getDate("datum") + "");
}
public Vector<String> getRows() {
return rijen;
}
This is all the relevant code.. I don't know what I miss or what I do wrong. Could someone show me how I could solve it :)?
// This JTable attribut ...
JTable table = null;
public ToDoListView (ToDoListModel model) {
this.model = model;
setBackground (Color.WHITE);
// is hidden by this local variable:
JTable table = new JTable();
In your ToDoModel class you add all data in one large Vector
while(rs.next()) {
System.out.println(rs.getInt("id") + "\n" + rs.getString("item") + "\n" + rs.getDate("datum"));
rijen.add(rs.getInt("id") + "");
rijen.add(rs.getString("item"));
rijen.add(rs.getDate("datum") + "");
}
Then you loop over that Vector to add all those items to the TableModel, but that loop is incorrect
for(int i = 0; i < model.getRows().size(); i++) {
tableModel.addRow(model.getRows());
System.out.println("added");
}
You always add the whole vector instead of just the data for that row.
Combine that with the answer of #user unknown and you might be able to fix your problem