I am trying to save some JTable Data into Database: My code is like this:
public void save(){
String invSL = new Mixed_Calculation().invoice_Sl();
jTextField6.setText(invSL);
int rows = jTable1.getRowCount();
for(int row = 0; row<rows ; row++){
String code = (String) jTable1.getValueAt(row, 1);
String name = (String) jTable1.getValueAt(row, 2);
String unit = (String) jTable1.getValueAt(row, 3);
String units[] = unit.split(" ");
int q = Integer.parseInt(units[0]);
String u = units[1];
String rate = (String) jTable1.getValueAt(row, 4);
String total = (String) jTable1.getValueAt(row, 5);
String d_rat = (String) jTable1.getValueAt(row, 6);
String discount = (String) jTable1.getValueAt(row, 7);
String net = (String) jTable1.getValueAt(row, 8);
try{
conn = new connection().db();
conn.setAutoCommit(false);
String query = "INSERT INTO INVOICE(INVOICE_NO, CODE, DESCRIPTION, BONUSABLE,"
+ " TAXABLE, CATEGORY, QNTY, UNIT, RATE, TOTAL , DISC_PERCENTAGE, DISCOUNT, NET_AMOUNT ) "
+ " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) " ;
stmt = conn.prepareStatement(query);
stmt.setString(1, jTextField6.getText()); //Invoice No
stmt.setString(2, code); //Code
stmt.setString(3, name); //Description
stmt.setString(4, ""); //Bonusable
stmt.setString(5, ""); //Taxable
stmt.setString(6, ""); //Category
stmt.setInt(7, q); //Qnty
stmt.setString(8, u); //Unit
stmt.setDouble(9, Double.parseDouble(rate)); //Rate
stmt.setDouble(10, Double.parseDouble(total)); //Total
stmt.setDouble(11, Double.parseDouble(d_rat)); //Disc_%
stmt.setDouble(12, Double.parseDouble(discount)); //Discount
stmt.setDouble(13, Double.parseDouble(net)); //net_Amount
stmt.addBatch(); stmt.executeBatch();
conn.commit();
}
catch(SQLException ex){
JOptionPane.showMessageDialog(null, "Cannot save. "+ ex);
}
finally{try{stmt.close(); conn.close(); conn.setAutoCommit(true);} catch(SQLException ex){} }
}
}
Why this method has no effect at all ? Am I doing something wrong here ? Is there any other system, that I can insert data directly from jTable ?
Take the execution of the batch outside the for-loop, that's the benefit of addBatch() as it hits the database only one time when executeBatch() is called.
for(int row = 0; row<rows ; row++)
{
//......
stmt.addBatch();
}
stmt.executeBatch();
conn.commit();
Related
I want to insert two different rows on two other tables. How can I do that? I have read about batch execution but do not understand it clearly. If it is possible to use batch execution, how?
I have tried this way and got this message "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '?, ?, ?, ?, ?, ?)' at line 1
". Thanks in advance.
/**
* save data from multiple tables
*/
private void customSave() {
// create connection
conn = new DB_Connection().makeConn();
try {
// for invoice table
String product_name = comboProductName.getSelectedItem().toString();
String date_of_sale = textDateOfSale.getText();
String paid_on = textPaidOn.getText();
int quantity = Integer.valueOf(spinnerQuantity.getValue().toString());
int discount = Integer.valueOf(textDiscount.getText());
double total_price = Double.valueOf(lblTotal.getText());
// for customer details table
String name = textFullName.getText();
String email = textEmail.getText();
String mobile = textMobile.getText();
String address = textAddress.getText();
stmnt = conn.createStatement();
// save to invoice
String sql_invoice = "INSERT INTO `invoice`(`product_name`, `date_of_sale`, `paid_on`, `discount`, `total_price`, `quantity`) "
+ "VALUES (?, ?, ?, ?, ?, ?)";
ps = conn.prepareStatement(sql_invoice);
ps.setString(1, product_name);
ps.setString(2, date_of_sale);
ps.setString(3, paid_on);
ps.setInt(4, discount);
ps.setDouble(5, total_price);
ps.setInt(6, quantity);
// save to customer_details
String sql_customer = "insert into customer_details(customer_name, email, mobile, address )"
+ "values (?, ?, ?, ?)";
ps = conn.prepareStatement(sql_customer);
ps.setString(1, name);
ps.setString(2, email);
ps.setString(3, mobile);
ps.setString(4, address);
if ((!textDateOfSale.getText().equals("")) && (!textPaidOn.getText().equals(""))
&& (!textFullName.getText().equals(""))) {
int count = ps.executeUpdate(sql_invoice);
int count1 = ps.executeUpdate(sql_customer);
if (count > 0 && count1 > 0) {
JOptionPane.showMessageDialog(null, "Data saved successfully.", "Success!!!",
JOptionPane.INFORMATION_MESSAGE);
textDateOfSale.setText("");
textPaidOn.setText("");
textFullName.setText("");
textEmail.setText("");
textMobile.setText("");
textAddress.setText("");
} else {
JOptionPane.showMessageDialog(null, "Unable to save data.", "Warning!!!",
JOptionPane.WARNING_MESSAGE);
}
} else {
JOptionPane.showMessageDialog(null, "Please fillup the required fields.", "Warning!",
JOptionPane.WARNING_MESSAGE);
}
stmnt.close();
conn.close();
} catch (Exception ex) {
// JOptionPane.showMessageDialog(null, ex, "Error!", JOptionPane.ERROR_MESSAGE);
System.out.println(ex.getMessage());
ex.getStackTrace();
}
}
I'd like to insert ID(int), title(varchar), plot(varchar), release_date(date), target(varchar) into exsiting database.
Here is the code which showed no data at all.
How can I add a date type value into a connected database?
else if (e.getSource() == this.insert2) {
String n = this.IDField.getInt();
String m = this.titleField.getText();
String f = this.plotField.getText();
String p = this.release_dateField.getText();
String t = this.targetField.getText();
String[] name = {"MOVIE_ID","title","plot","release_date","main_target"};
this.dt = new DefaultTableModel(name, 0);
/**try~catch*/
try{
stmt.executeUpdate("insert into DB2020_MOVIEINFO values('" + n + "', '" + m + "', '" + f + "', '" + p + "', '" + t + "')");
ResultSet rset_mv = stmt.executeQuery("SELECT * FROM DB2020_MOVIEINFO");
while (rset_mv.next()) {
Object[] data = {rset_mv.getString(1), rset_mv.getString(2), rset_mv.getString(3), rset_mv.getString(4), rset_mv.getString(5)};
dt.addRow(data);
}
}
catch(SQLException se) {
se.printStackTrace();
}
this.jt = new JTable(dt);
jt.getTableHeader().setBackground(Color.decode("#b76e79"));
jt.setSelectionBackground(Color.decode("#f7f6f0"));
this.jsp = new JScrollPane(jt);
jt.setPreferredScrollableViewportSize(new Dimension(800,600));
this.add(centerPanel,BorderLayout.CENTER);
this.centerPanel.removeAll();
this.centerPanel.updateUI();
this.centerPanel.add(jsp);
this.centerPanel.setVisible(true);
}
new code I applied after Mureinik's advise. (I extracted date-part)
else if (e.getSource() == this.insert2) {
Int id = this.IDField.getInt();
String title = this.titleField.getText();
String plot = this.plotField.getText();
String target = this.targetField.getText();
String[] name = {"MOVIE_ID","title","plot","main_target"};
this.dt = new DefaultTableModel(name, 0);
/**try~catch*/
try (PreparedStatement ps =
conn.prepareStatement("insert into DB2020_MOVIEINFO values(?, ?, ?, ?)") {
ps.setInt(1, id); // id should be an int
ps.setString(2, title);
ps.setString(3, plot);
ps.setString(4, target);
}
catch(SQLException se) {
se.printStackTrace();
}
this.jt = new JTable(dt);
jt.getTableHeader().setBackground(Color.decode("#b76e79"));
jt.setSelectionBackground(Color.decode("#f7f6f0"));
this.jsp = new JScrollPane(jt);
jt.setPreferredScrollableViewportSize(new Dimension(800,600));
this.add(centerPanel,BorderLayout.CENTER);
this.centerPanel.removeAll();
this.centerPanel.updateUI();
this.centerPanel.add(jsp);
this.centerPanel.setVisible(true);
}
Instead of trying to force these datatypes to strings, you could use a PreparedStatement and let the JDBC driver do the heavy lifting for you. As a side effect, this will also help protect you application from SQL Injection attacks:
try (PreparedStatement ps =
conn.prepareStatement("insert into DB2020_MOVIEINFO values(?, ?, ?, ?, ?)) {
ps.setInt(1, id); // id should be an int
ps.setString(2, title);
ps.setString(3, plot);
ps.setDate(4, releaseDate); // releaseDate should be java.sql.Date
ps.setString(5, target);
}
The update button on my simple stock management system is not updating the stock. When clicked it shows the product updated dialog but nothing happens. It is throwing no errors and i cant find the problem.
It was working when i only had 5 rows but when i added the category and quantity row it stopped.
private void btn_updateActionPerformed(java.awt.event.ActionEvent evt) {
if(checkInputs() && txt_id.getText() != null)
{
String UpdateQuery = null;
PreparedStatement ps = null;
Connection con = getConnection();
//update without image
if(ImgPath == null)
{
try {
UpdateQuery = "UPDATE products SET name = ?, price = ?"
+ ", add_date = ?, category = ?, quantity = ?, WHERE id = ?";
ps = con.prepareStatement(UpdateQuery);
ps.setString(1, txt_name.getText());
ps.setString(2, txt_price.getText());
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String addDate = dateFormat.format(txt_AddDate.getDate());
ps.setString(3, addDate);
ps.setInt(4, Integer.parseInt(txt_id.getText()));
String value = combo_category.getSelectedItem().toString();
ps.setString(5, value);
ps.setString(6, txt_quantity.getText());
ps.executeUpdate();
Show_Products_In_JTable();
JOptionPane.showMessageDialog(null, "Product Updated");
} catch (SQLException ex) {
Logger.getLogger(Main_Window.class.getName()).log(Level.SEVERE, null, ex);
}
}
//update with Image
else{
try{
InputStream img = new FileInputStream(new File(ImgPath));
UpdateQuery = "UPDATE products SET name = ?, price = ?"
+ ", add_date = ?,image = ?, category = ?, quantity = ?, WHERE id = ?";
ps = con.prepareStatement(UpdateQuery);
ps.setString(1, txt_name.getText());
ps.setString(2, txt_price.getText());
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String addDate = dateFormat.format(txt_AddDate.getDate());
ps.setString(3, addDate);
ps.setBlob(4, img);
String value = combo_category.getSelectedItem().toString();
ps.setString(5, value);
ps.setInt(6, Integer.parseInt(txt_id.getText()));
ps.executeUpdate();
Show_Products_In_JTable();
JOptionPane.showMessageDialog(null, "Product Updated");
}catch(Exception ex)
{
JOptionPane.showMessageDialog(null, ex.getMessage());
}
}
}else{
JOptionPane.showMessageDialog(null, "One or More Fields Are Empty Or Wrong");
}
}
At first sight
quantity = ?, WHERE id = ?
shoule be
quantity = ? WHERE id = ?
I want to update about 10K records into MySQL DB in less than a second. I have written below code which takes about 6-8 seconds to update a list of records into DB.
public void updateResultList(List<?> list) {
String user = "root";
String pass = "root";
String jdbcUrl = "jdbc:mysql://12.1.1.1/db_1?useSSL=false";
String driver = "com.mysql.jdbc.Driver";
PreparedStatement pstm = null;
try {
Class.forName(driver);
Connection myConn = DriverManager.getConnection(jdbcUrl, user, pass);
myConn.setAutoCommit(false);
for(int i=0; i<list.size(); i++) {
Object[] row = (Object[]) list.get(i);
int candidateID = Integer.valueOf(String.valueOf(row[0]));
String result = String.valueOf(row[14]);
int score = Integer.valueOf(String.valueOf(row[19]));
String uploadState = (String) row[20];
String sql = "UPDATE personal_info SET result = ?, score = ?, uploadState = ? "
+ " WHERE CandidateID = ?";
pstm = (PreparedStatement) myConn.prepareStatement(sql);
pstm.setString(1, result);
pstm.setInt(2, score);
pstm.setString(3, uploadState);
pstm.setInt(4, candidateID);
pstm.addBatch();
pstm.executeBatch();
}
myConn.commit();
myConn.setAutoCommit(true);
pstm.close();
myConn.close();
}
catch (Exception exc) {
exc.printStackTrace();
try {
throw new ServletException(exc);
} catch (ServletException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Please let me know your inputs to optimize this code for performance improvement.
First, you need to init prepareStatement only once,you need to init it before the for loop
Second,you should avoid excute pstm.executeBatch(); for every loop it will cost much more resource,you need to execute it for a specified amount,such as 100,500 or more,also do not execute it outside the for loop for only once,due to it will cost more memory resource
Class.forName(driver);
Connection myConn = DriverManager.getConnection(jdbcUrl, user, pass);
myConn.setAutoCommit(false);
String sql = "UPDATE personal_info SET result = ?, score = ?, uploadState = ? "
+ " WHERE CandidateID = ?";
pstm = (PreparedStatement) myConn.prepareStatement(sql);
for(int i=0; i<list.size(); i++) {
Object[] row = (Object[]) list.get(i);
int candidateID = Integer.valueOf(String.valueOf(row[0]));
String result = String.valueOf(row[14]);
int score = Integer.valueOf(String.valueOf(row[19]));
String uploadState = (String) row[20];
pstm.setString(1, result);
pstm.setInt(2, score);
pstm.setString(3, uploadState);
pstm.setInt(4, candidateID);
pstm.addBatch();
if(i%500==0){//execute when it meet a specified amount
pstm.executeBatch();
}
}
pstm.executeBatch();
myConn.commit();
myConn.setAutoCommit(true);
Rather than batching the individual UPDATEs, you could batch INSERTs into a temporary table with rewriteBatchedStatements=true and then use a single UPDATE statement to update the main table. On my machine with a local MySQL instance, the following code takes about 2.5 seconds ...
long t0 = System.nanoTime();
conn.setAutoCommit(false);
String sql = null;
sql = "UPDATE personal_info SET result=?, score=?, uploadState=? WHERE CandidateID=?";
PreparedStatement ps = conn.prepareStatement(sql);
String tag = "X";
for (int i = 1; i <= 10000; i++) {
ps.setString(1, String.format("result_%s_%d", tag, i));
ps.setInt(2, 200000 + i);
ps.setString(3, String.format("state_%s_%d", tag, i));
ps.setInt(4, i);
ps.addBatch();
}
ps.executeBatch();
conn.commit();
System.out.printf("%d ms%n", (System.nanoTime() - t0) / 1000000);
... while this version takes about 1.3 seconds:
long t0 = System.nanoTime();
conn.setAutoCommit(false);
String sql = null;
Statement st = conn.createStatement();
st.execute("CREATE TEMPORARY TABLE tmp (CandidateID INT, result VARCHAR(255), score INT, uploadState VARCHAR(255))");
sql = "INSERT INTO tmp (result, score, uploadState, CandidateID) VALUES (?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
String tag = "Y";
for (int i = 1; i <= 10000; i++) {
ps.setString(1, String.format("result_%s_%d", tag, i));
ps.setInt(2, 400000 + i);
ps.setString(3, String.format("state_%s_%d", tag, i));
ps.setInt(4, i);
ps.addBatch();
}
ps.executeBatch();
sql =
"UPDATE personal_info pi INNER JOIN tmp ON tmp.CandidateID=pi.CandidateID "
+ "SET pi.result=tmp.result, pi.score=tmp.score, pi.uploadState=tmp.uploadState";
st.execute(sql);
conn.commit();
System.out.printf("%d ms%n", (System.nanoTime() - t0) / 1000000);
your pstm.executeBatch() should be after forloop
refer How to insert List into database
I am trying to save Multiple row data from JTable into Database, Here is my code for reference:
try{
int rows=tblCO2.getRowCount();
for(int row = 0; row<rows; row++)
{
String coitemname = (String)tblCO2.getValueAt(row, 0);
String cocateg = (String)tblCO2.getValueAt(row, 1);
String codesc = (String)tblCO2.getValueAt(row, 2);
String coloc = (String)tblCO2.getValueAt(row, 3);
String coitemtagno = (String)tblCO2.getValueAt(row, 4);
try
{
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/iotams",user,pass);
conn.setAutoCommit(false);
String queryco = "Insert into tblcheckout(CheckoutID,ItemTagNo,ItemName,Category,Description,Location) values (?,?,?,?,?)";
pst = conn.prepareStatement(queryco);
pst.setString(1, coitemname);
pst.setString(2, cocateg);
pst.setString(3, codesc);
pst.setString(4, coloc);
pst.setString(5, coitemtagno);
pst.addBatch();
}
catch(Exception e)
{
}
}
pst.executeBatch();
conn.commit();
}
catch(Exception e){
JOptionPane.showMessageDialog(this,e.getMessage());
}
The Problem is, it is only inserting one row data into database. Can someone please help me? :( thanks!
Remove following line codes from loop and place before loop
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/iotams",user,pass);
conn.setAutoCommit(false);
String queryco = "Insert into tblcheckout(CheckoutID,ItemTagNo,ItemName,Category,Description,Location) values (?,?,?,?,?)";
pst = conn.prepareStatement(queryco);
Example: Replace your code by following code
try{
int rows=tblCO2.getRowCount();
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/iotams",user,pass);
conn.setAutoCommit(false);
String queryco = "Insert into tblcheckout(CheckoutID,ItemTagNo,ItemName,Category,Description,Location) values (?,?,?,?,?)";
pst = conn.prepareStatement(queryco);
for(int row = 0; row<rows; row++)
{
String coitemname = (String)tblCO2.getValueAt(row, 0);
String cocateg = (String)tblCO2.getValueAt(row, 1);
String codesc = (String)tblCO2.getValueAt(row, 2);
String coloc = (String)tblCO2.getValueAt(row, 3);
String coitemtagno = (String)tblCO2.getValueAt(row, 4);
pst.setString(1, coitemname);
pst.setString(2, cocateg);
pst.setString(3, codesc);
pst.setString(4, coloc);
pst.setString(5, coitemtagno);
pst.addBatch();
}
pst.executeBatch();
conn.commit();
}
catch(Exception e){
JOptionPane.showMessageDialog(this,e.getMessage());
}
Then run it think it work.
For Batch insert example is here https://my.vertica.com/docs/5.0/HTML/Master/14878.htm
the code above is not able to run in netbeans ,
However I made a version for netbeans.
try{
int rows=jTable1.getRowCount();
for(int row = 0; row<rows; row++)
{
Integer qty = (Integer)jTable1.getValueAt(row, 0);
Double unitprice = (Double) jTable1.getValueAt(row, 1);
String description = (String)jTable1.getValueAt(row, 2);
Double total = (Double)jTable1.getValueAt(row, 3);
String queryco = "Insert into invoice(qty,unitprice,description,total) values ('"+qty+"','"+unitprice+"','"+description+"','"+total+"')";
pst = conn.prepareStatement(queryco);
pst.execute();
}
JOptionPane.showMessageDialog(null, "Successfully Save");
}
catch(Exception e){
JOptionPane.showMessageDialog(this,e.getMessage());
}