Jste si vědomi skutečnosti, že ve skutečnosti přistupujete k backendu z vašeho GUI? Předáváte parametry z textových polí přímo do vaší databáze. Toto je zdroj pro velké kurvy. Alespoň ověřte svůj vstup nebo Tabulky malého Bobbyho předčasně ukončí vaši pracovní smlouvu.
K vaší chybě:Omlouváme se, ale tento kód potřebuje zásadní refaktoring. Samotný podle počtu řádků dělá tento kód příliš mnoho. První zlaté pravidlo:Udržujte své metody krátké. Druhé zlaté pravidlo:Zkraťte je.
Skutečnost, že vy sami nerozumíte, co se děje, je pro vás velká červená kontrolka a ukazuje, že musíte svůj design přehodnotit.
- Udělejte metody, které zapisují věci pomocí JDBC.putData(), samostatné.
- Udělejte totéž s JDBC.getData().
- Podívejte se na vznikající vzor.
Myslím, že je to předčasné volání connection.close() v JDBC. Rozdělením operací na více atomické můžete svůj kód lépe uvažovat, a tím porozumět dané chybě.
Omlouváme se za nedodání řešení, ale z dlouhodobého hlediska jste na tom lépe, když budete dodržovat některé zásady kódu. Naučte se je! Čím dříve, tím lépe a protože potřebuji více karmy:Přečtěte si „Clean-Code“ od Roberta C. Martina.http://www.amazon.de/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882
Poté se vydáte na cestu osvícení a použijete tedy DAOFactory (napovídání) a návrhový vzor DAO (také napovídání) a stanete se bohem kodérů. Gratulujeme!
No, tady je malý návod, jak by refaktoring mohl vypadat. Nedokončeno a netestováno a myslím, že jsem posral sekvenci vkládání SQL (nevím, kde se používá transakčníId). Ale doufám, že dostanete nápad. Hezký den a vítejte na Jamajce!
package mysqlfix;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTextField;
public class JDBC {
static Connection con = null;
static boolean b;
static PreparedStatement state;
public static void setCon() {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/lottery", "root", "123");
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static Connection getCon() throws Exception {
if (con == null) {
setCon();
}
return con;
}
public static boolean putData(String sql) {
try {
getCon().setAutoCommit(false);
state = getCon().prepareStatement(sql);
state.executeUpdate();
getCon().commit();
b = true;
} catch (Exception e) {
e.printStackTrace();
b = false;
}
return b;
}
// connection commit
public static void commit() {
try {
con.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
// rollback data
public static void rollback() {
if (con != null) {
try {
con.rollback();
} catch (SQLException ex) {
Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
// close statement
public static void putClose() {
try {
state.close();
} catch (SQLException ex) {
Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
}
}
// close connection
public static void conClose() {
try {
con.setAutoCommit(true);
con.close();
} catch (SQLException ex) {
Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
}
}
// clear prepared statement
public static void putClear() {
try {
if (state != null && !state.isClosed()) {
state.close();
}
} catch (SQLException ex) {
Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
}
}
// clear the connection
public static void conClear() {
try {
if (con != null && !con.isClosed()) {
con.setAutoCommit(true);
con.close();
}
} catch (SQLException ex) {
Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static ResultSet getData(String sql) throws Exception {
Statement state = getCon().createStatement();
ResultSet rs = state.executeQuery(sql);
return rs;
}
public void saveTotal(JTextField txtGtotal, JTextField txtPTotal) {
SuperDAO superDAO = new SuperDAO();
if (superDAO.getMaxIdFromOrder() > 0) {
Date date1;
date1 = new Date();
String txtGTotalFromTextField = txtGtotal.getText();
String txtPTotalFromTextField = txtPTotal.getText();
boolean b1 = false;
//regarding the transaction id...
//this changes whilst updating the table transaction.
int transactionId = -1;
if (txtGTotalFromTextField.matches("[a-zA-Z]")) {
transactionId = superDAO.insertOrderIntoTransaction(date1, txtGTotalFromTextField);
//b1 = JDBC.putData("insert into transaction(tr_date, amount, tr_type) values ('" + date1 + "' , '" + txtGTotalFromTextField + "' , 'order')");
}
if (transactionId > 0) {
try {
} catch (Exception ex) {
Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
}
if (txtPTotalFromTextField.matches("[a-zA-Z]")) {
transactionId = superDAO.insertProfitIntoTransaction(date1, txtGTotalFromTextField);
}
JDBC.putData("insert into o_de(or_id, tr_id, oday, gtotal) values ('" + superDAO.getMaxIdFromOrder() + "' , '" + transactionId + "','" + date1 + "','" + txtGtotal.getText() + "' )");
JDBC.putData("insert into order_profit(or_id, tr_id, ptotal) values ('" + superDAO.getMaxIdFromOrder() + "' , '" + transactionId + "','" + txtPTotal.getText() + "' )");
//JDBC.commit();
//JOptionPane.showMessageDialog(null, "Order Saved Sucessfully..");
JDBC.putClose();
JDBC.conClose();
}
}
}
}
package mysqlfix;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author edm
*/
public class SuperDAO {
Connection conn;
public SuperDAO() {
try {
this.conn = JDBC.getCon();
} catch (Exception ex) {
Logger.getLogger(SuperDAO.class.getName()).log(Level.SEVERE, null, ex);
}
}
public int getMaxIdFromOrder() {
try {
ResultSet rs = JDBC.getData("select MAX(or_id) as or_id from `order`");
if (rs.first()) {
return rs.getInt("or_id");
}
} catch (SQLException ex) {
Logger.getLogger(SuperDAO.class.getName()).log(Level.SEVERE, null, ex);
} catch (Exception ex) {
Logger.getLogger(SuperDAO.class.getName()).log(Level.SEVERE, null, ex);
}
return -1;
}
public int getMaxIdFromTransaction() {
ResultSet rs;
try {
rs = JDBC.getData("select MAX(tr_id) as tr_id from transaction");
if (rs.first()) {
return rs.getInt("tr_id");
}
} catch (Exception ex) {
Logger.getLogger(SuperDAO.class.getName()).log(Level.SEVERE, null, ex);
}
return -1;
}
public int insertOrderIntoTransaction(Date date, String text) {
JDBC.putData("insert into transaction(tr_date, amount, tr_type) values ('" + date + "' , '" + text + "' , 'order')");
return getMaxIdFromTransaction();
}
public int insertProfitIntoTransaction(Date date, String text) {
JDBC.putData("insert into transaction(tr_date, amount, tr_type) values ('" + date + "' , '" + text + "' , 'profit')");
return getMaxIdFromTransaction();
}
}
Tím cesta samozřejmě nekončí. Nedokončil jsem JDBC saveTotal(). Právě jsem začal, zbytek uděláš ty.
Vezměte prosím na vědomí, že jsem tento kód netestoval proti databázi (některé soubory SQL ddl chyběly). Také jsem nepoužil mechanismus vrácení zpět. SaveTotal() navíc žije v JDBC, kam nepatří. Použijte saveTotal ve svém GUI (pokud je to potřeba) a nechte všechny přístupy k databázi procházet přes SuperDAO. Toto není nejlepší návrh, ale není příliš abstraktní a můžete snadno vidět, jak oddělení zájmu dělá váš kód o něco čitelnějším a udržitelnějším.