访问数据库并写入Bean |最佳实践

时间:2015-07-20 21:51:33

标签: java jdbc javabeans

我有一些付款必须加载到TableView。为此,我写了两个课程。

这个创建与数据库的连接,并从.properties文件

获取此信息
package jdbc;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
/**
 * JDBCAccess bietet Zugriff auf eine Datenbank.
 * Hierzu werden die Zugangsdaten aus einer Properties Datei geladen welche sich im im Ordner
 * 'db' befinden.
 * @author Christian
 *
 */
public final class JDBCAccess {

    private Connection connection;
    private String username;
    private String password;
    private String dbURL;
    private String driverURL;

    private static final String dbPropsPath = "db/db-props.properties";

    /**
     * Standar Konstrukter der Klasse.
     * Beim Aufruf dieses Konstruktors wird die connectTo Methode automatisch mit aufgerufen
     */
    public JDBCAccess() {
        super();
    }

     /**
      * Lädt die Parameter aus der Properties Datei direkt in die Variabeln
      */
    private void loadParameters() throws FileNotFoundException, IOException {
        Properties dbProps = new Properties();
        File dbPropsFile = new File(dbPropsPath);
        dbProps.load(new FileInputStream(dbPropsFile));
        username = dbProps.getProperty("username");
        password = dbProps.getProperty("password");
        dbURL = dbProps.getProperty("dbURL");
        driverURL = dbProps.getProperty("driverURL");
    }

    /**
     * Verbindung zur Datenbank herstellen
     * 
     * @throws FileNotFoundException db-props.properties Datei konnte nicht gefunden werden
     * @throws IOException db-props.properties Datei, laden fehlgeschlagen
     * @throws ClassNotFoundException Fehler in Treiber URL
     * @throws SQLException Verbindungsaufbau zur Datenbank fehlgeschlagen
     */
    public void connectTo() throws FileNotFoundException, IOException, ClassNotFoundException, SQLException {
        if (connection == null || connection.isClosed()) {
            loadParameters();
            Class.forName(driverURL);
            connection = DriverManager.getConnection(dbURL, username, password);
        }

    }

    /**
     * Schließt die Datenbankverbindung
     * 
     * @throws SQLException Schließen der Datenbank fehlgeschlagen
     */
    public void close() throws SQLException {
        if (connection != null && !connection.isClosed()) {
            connection.close();
        }
    }

    public Connection getConnection() {
        return connection;
    }

}

这个加载并将bean保存在数据库中:

package beans;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import jdbc.JDBCAccess;

public class PaymentBean {

    private SimpleIntegerProperty id; //ID
    private SimpleDoubleProperty payment; //Betrag
    private SimpleStringProperty category; //Kategories
    private SimpleStringProperty usage; //Verwendungszweck
    private SimpleStringProperty date; //Datum

    private static Connection connection;

    private static final String EARNINGS_SQL = "SELECT * FROM PAYMENT WHERE PAYMENT >= 0;";
    private static final String SPENDING_SQL = "SELECT * FROM PAYMENT WHERE PAYMENT < 0;";
    private static final String ALL_SQL = "SELECT * FROM PAYMENT;";

    /**
     * Standarkonstruktor, initialisiert alle privaten Felder, sodass sie
     * benutzt werden können
     */
    public PaymentBean() {
        super();
        id = new SimpleIntegerProperty();
        payment = new SimpleDoubleProperty();
        category = new SimpleStringProperty();
        usage = new SimpleStringProperty();
        date = new SimpleStringProperty();
    }


    public final int getId() {
        return id.get();
    }

    public final void setId(int id) {
        this.id.set(id);
    }

    public final double getPayment() {
        return payment.get();
    }

    public final void setPayment(double payment) {
        this.payment.set(payment);
    }

    public final String getCategory() {
        return category.get();
    }

    public final void setCategory(String category) {
        this.category.set(category);
    }

    public final String getUsage() {
        return usage.get();
    }

    public final void setUsage(String usage) {
        this.usage.set(usage);
    }

    public final String getDate() {
        return date.get();
    }

    public final void setDate(String date) {
        this.date.set(date);
    }


    /******************************
     * DATENBANK ZUGRIFFEDER BEAN *
     *****************************/

    /**
     * Diese Methode wird von allen Methoden benutzt, die Daten aus
     * der Datenbank in ein ResultSet laden. Dieses ResultSet wird in eine
     * ObservableList<PaymentBean> geladen, um somit ein Abbild in einer Tabelle zu erstellen
     * @param connection Datenbankverbindung, muss schon geöffnet sein
     * @param sql SQL Befehl, welcherv ausgeführt werden soll
     * @return Liste mit Datenbankergebnissen
     * @throws SQLException
     * @throws IOException 
     * @throws ClassNotFoundException 
     * @throws FileNotFoundException 
     */
    private static ObservableList<PaymentBean> loadFromDB(final JDBCAccess jdbc, String sql) throws SQLException, FileNotFoundException, ClassNotFoundException, IOException {
        jdbc.connectTo();
        connection = jdbc.getConnection();
        if (connection != null) {
            ObservableList<PaymentBean> data = FXCollections.observableArrayList();
            Statement stmt = connection.createStatement();
            ResultSet rs = stmt.executeQuery(sql);
            while (rs.next()) {
                PaymentBean pb = new PaymentBean();
                pb.setId(rs.getInt(1));
                pb.setPayment(rs.getDouble(2));
                pb.setDate(rs.getString(3));
                pb.setUsage(rs.getString(4));
                pb.setCategory(rs.getString(5));
                data.add(pb);
            }

            stmt.close();
            rs.close();
            jdbc.close();
            return data;
        }

        return null;
    }

    /**
     * Statische Methode um alle PaymentBeans aus der angegebenen Datenbank zu laden
     * @param connection Verbindung zur Datenbank
     * @return Gibt alle Zahlungen in Form einer ObservableList<PaymentBean> zurück 
     * @throws SQLException
     * @throws IOException 
     * @throws ClassNotFoundException 
     * @throws FileNotFoundException 
     */
    public static ObservableList<PaymentBean> loadBeansFromDB(JDBCAccess jdbc) throws SQLException, FileNotFoundException, ClassNotFoundException, IOException {
        return loadFromDB(jdbc, ALL_SQL);
    }

    /**
     * Statische Methode um alle Einzahlungen aus der angegebenen Datenbank zu laden
     * @param connection Datenbankverbindung
     * @return Gibt alle Einzahlungen in Form einer ObservableList<PaymentBean> zurück 
     * @throws SQLException
     * @throws IOException 
     * @throws ClassNotFoundException 
     * @throws FileNotFoundException 
     */
    public static ObservableList<PaymentBean> loadEarningsFromDB(JDBCAccess jdbc) throws SQLException, FileNotFoundException, ClassNotFoundException, IOException {
        return loadFromDB(jdbc, EARNINGS_SQL);
    }

    /**
     * Statische Methode um alle Auszahlungen aus der angegebenen Datenbank zu laden 
     * @param connection Datenbankverbindung
     * @return Gibt alle Auszahlungen in Form einer ObservableList<PaymentBean> zurück
     * @throws SQLException
     * @throws IOException 
     * @throws ClassNotFoundException 
     * @throws FileNotFoundException 
     */
    public static ObservableList<PaymentBean> loadSpendingsFromDB(JDBCAccess jdbc) throws SQLException, FileNotFoundException, ClassNotFoundException, IOException {
        return loadFromDB(jdbc, SPENDING_SQL);
    }

    public static double getTotalSum(JDBCAccess jdbc) throws SQLException, FileNotFoundException, ClassNotFoundException, IOException {
        jdbc.connectTo();
        connection = jdbc.getConnection();
        String sql = "SELECT SUM(PAYMENT) FROM PAYMENT;";
        Statement stmt = connection.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        rs.next();
        jdbc.close();
        return rs.getDouble(1);
    }

    /**
     * Speichert die Bean in der Datenbank ab
     * @param connection Datanbankverbindung
     * @throws SQLException
     * @throws IOException 
     * @throws ClassNotFoundException 
     * @throws FileNotFoundException 
     */
    public void saveInDB(JDBCAccess jdbc) throws SQLException, FileNotFoundException, ClassNotFoundException, IOException {
        jdbc.connectTo();
        connection = jdbc.getConnection();
        if (connection != null) {
            String sql = "INSERT INTO PAYMENT (PAYMENT,DATE,USAGE,CATEGORY) "
                    + "VALUES (?,?,?,?);";
            PreparedStatement insert = connection.prepareStatement(sql);
            insert.setDouble(1, payment.get());
            insert.setString(2, date.get());
            insert.setString(3, usage.get());
            insert.setString(4, category.get());
            insert.executeUpdate();
            insert.close();
            jdbc.close();
        }
    }

    /**
     * Updatet die Bean in der Datenbank
     * @param connection Verbindung zur Datenbank
     * @param id ID der zu updatenden Bean
     * @throws SQLException
     * @throws IOException 
     * @throws ClassNotFoundException 
     * @throws FileNotFoundException 
     */
    public void updateBeanInDB(JDBCAccess jdbc, int id) throws SQLException, FileNotFoundException, ClassNotFoundException, IOException {
        jdbc.connectTo();
        connection = jdbc.getConnection();
        if (connection != null) {
            String sql = "UPDATE PAYMENT "
                    + "SET PAYMENT = ? ,DATE = ? ,USAGE=? ,CATEGORY=?  "
                    + "WHERE ID = ?;";
            PreparedStatement insert = connection.prepareStatement(sql);
            insert.setDouble(1, payment.get());
            insert.setString(2, date.get());
            insert.setString(3, usage.get());
            insert.setString(4, category.get());
            insert.setInt(5, id);
            insert.executeUpdate();
            insert.close();
            jdbc.close();
        }

    }

    /**
     * Löscht die Bean aus der Datenbank
     * @param connection Verbindung zur Datenbank
     * @throws SQLException
     * @throws IOException 
     * @throws ClassNotFoundException 
     * @throws FileNotFoundException 
     */
    public void delete(JDBCAccess jdbc) throws SQLException, FileNotFoundException, ClassNotFoundException, IOException {
        jdbc.connectTo();
        connection = jdbc.getConnection();
        String sql = "DELETE FROM PAYMENT WHERE ID = ?;";
        PreparedStatement stmt = connection.prepareStatement(sql);
        stmt.setInt(1, this.id.get());
        stmt.executeUpdate();
        stmt.close();
        jdbc.close();
    }

}

使用SimpleXXXProperty,可以在TableView中没有任何代码的情况下表示属性。

我能做得更好吗?我可以从支付bean方法写入数据库,还是应该从这个bean外部访问数据库?

1 个答案:

答案 0 :(得分:1)

  

我能做得更好吗?

为什么不使用类似休眠的ORM

  

我可以从支付bean方法写入数据库,或者   我应该从这个bean的外部访问数据库吗?

您正在执行的数据库访问不完全包含在bean中。客户端需要传递JDBCAccess对象来执行任何数据库任务 - 所以不太方便。它只是结合了模型和dao into 1 class。

另外要考虑这个bean是否是分发API的一部分,或者仅作为持久性模型在您的应用程序中使用。如果是API,则将持久性逻辑的内部分发给客户端,并强制依赖JDBCAccess类。

对代码的评论:考虑不要抛弃已检查的异常。最后进行connection.close()之类的操作。