首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 連接 Oracle 資料庫:屬性檔配置與 BaseDAO 封裝最佳實踐

     編輯:Java 相關知識

架構概覽

採用三層結構分離關注點:

  1. database.properties:連線參數外部化,支援多環境切換。
  2. ConfigManager:單例模式載入屬性檔,提供型別安全的存取方法。
  3. BaseDao:封裝 JDBC 通用操作(連線、CRUD、資源關閉),子類專注 SQL 與業務邏輯。

1. database.properties

jdbc.driver_class=oracle.jdbc.driver.OracleDriver
jdbc.connection.url=jdbc:oracle:thin:@localhost:1521:orcl
jdbc.connection.username=scott
jdbc.connection.password=tiger

2. ConfigManager(單例 + 快取)


package com.book.util;
import java.io.*;
import java.util.Properties;

public class ConfigManager {
    private static ConfigManager instance;
    private static Properties props = new Properties();

    private ConfigManager() {
        String file = "database.properties";
        try (InputStream is = getClass().getClassLoader().getResourceAsStream(file)) {
            if (is == null) throw new RuntimeException("找不到 " + file);
            props.load(is);
        } catch (IOException e) {
            throw new RuntimeException("載入設定檔失敗", e);
        }
    }

    public static synchronized ConfigManager getInstance() {
        if (instance == null) instance = new ConfigManager();
        return instance;
    }

    public String getString(String key) {
        return props.getProperty(key);
    }
}

3. BaseDao(JDBC 範本)


package com.book.dao;
import java.sql.*;
import com.book.util.ConfigManager;

public class BaseDao {
    protected Connection conn;
    protected PreparedStatement ps;
    protected ResultSet rs;

    // 取得連線
    protected boolean openConnection() {
        try {
            String driver = ConfigManager.getInstance().getString("jdbc.driver_class");
            String url = ConfigManager.getInstance().getString("jdbc.connection.url");
            String user = ConfigManager.getInstance().getString("jdbc.connection.username");
            String pwd = ConfigManager.getInstance().getString("jdbc.connection.password");

            Class.forName(driver);
            conn = DriverManager.getConnection(url, user, pwd);
            return true;
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    // 增刪改
    protected int executeUpdate(String sql, Object... params) {
        int rows = 0;
        if (!openConnection()) return 0;
        try {
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }
            rows = ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            closeAll();
        }
        return rows;
    }

    // 查詢
    protected ResultSet executeQuery(String sql, Object... params) {
        if (!openConnection()) return null;
        try {
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }
            rs = ps.executeQuery();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // 注意:呼叫端必須自行關閉 rs、ps、conn
        return rs;
    }

    // 關閉資源(遵循建立順序逆序關閉)
    protected void closeAll() {
        try { if (rs != null) rs.close(); } catch (SQLException ignored) {}
        try { if (ps != null) ps.close(); } catch (SQLException ignored) {}
        try { if (conn != null) conn.close(); } catch (SQLException ignored) {}
    }
}

4. 子類使用範例


public class BookDao extends BaseDao {
    public int addBook(String name, double price) {
        String sql = "INSERT INTO books(name, price) VALUES(?, ?)";
        return executeUpdate(sql, name, price);
    }

    public List<Book> queryAll() {
        String sql = "SELECT id, name, price FROM books";
        List<Book> list = new ArrayList<>();
        try (ResultSet rs = executeQuery(sql)) {
            while (rs != null && rs.next()) {
                Book b = new Book();
                b.setId(rs.getInt("id"));
                b.setName(rs.getString("name"));
                b.setPrice(rs.getDouble("price"));
                list.add(b);
            }
        } catch (SQLException e) { e.printStackTrace(); }
        return list;
    }
}

進階建議

  • 連線池:生產環境請改用 HikariCP / Druid,避免頻繁建立銷毀連線。
  • Try-with-resources:JDK 7+ 自動關閉資源,減少 finally 碼。
  • 事務控制:在 Service 層管理 conn.setAutoCommit(false),BaseDao 不自行提交/回滾。
  • SQL 注入防護:全程使用 PreparedStatement 參數綁定,絕不拼接 SQL 字串。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved