简体   繁体   English

避免使用Java中的静态类进行代码重复

[英]Avoid code duplication with static classes in Java

I'm writing a Java application that will have to manage two different databases (let's say Onebase and Twobase ) created using PostgreSQL . 我正在编写一个Java应用程序 ,它必须管理使用PostgreSQL创建的两个不同的数据库(比如说OnebaseTwobase )。

In order to handle connections and queries, I created for the first one a file (named OnebaseUtil ) with JDBC , that more or less looks like this: 为了处理连接和查询,我为第一个创建了一个带有JDBC的文件(名为OnebaseUtil ),它或多或少看起来像这样:

public class OnebaseUtil {
    private static final String JDBC_DRIVER = "org.postgresql.Driver";
    private static Connection conn = null;
    private static String url = "jdbc:postgresql://localhost:5432/onebase?user=useradmin&password=123456";

    private static void dbConnect() { ... }

    private static void dbDisconnect() { ... }

    public static ResultSet dbExecuteQuery(String queryStmt) { ... }

    public static void dbExecuteUpdate(String sqlStmt) { ... }
}

Then I started writing the TwobaseUtil , just finding out the code was exactly the same, except for the url ( ...twobase... instead of ...onebase... ). 然后我开始编写TwobaseUtil ,只是发现代码完全相同,除了url...twobase...而不是...onebase... )。

How can I avoid having a code duplicate for both databases? 如何避免两个数据库的代码重复? Notice that as you can see all methods are static and I would like to keep using them as static through all the code. 请注意,正如您所看到的,所有方法都是static ,我希望通过所有代码继续使用它们作为static I thought about using a single file (let's say BothbaseUtil ) setting a constructor with the String passed every time I'm using it... but I would have to instantiate it every time! 我想过使用单个文件(比如说BothbaseUtil )设置一个构造函数,每次我使用它时都会传递String ...但我每次都要实例化它! And I really want to avoid this. 我真的想避免这种情况。

Thanks anyone for help! 谢谢任何人的帮助!

In fact this database code pattern is seen very often, but has disadvantages. 实际上,这种数据库代码模式经常被看到,但是有缺点。

One better would use a DataSource and store several datasources declaratively in XML or properties. 最好使用DataSource并以XML或属性声明性地存储多个数据源。 (Different for development/production). (与开发/生产不同)。

One way to use such a DataSource would be using CDI, dependency injection. 使用这种DataSource的一种方法是使用CDI,依赖注入。 Then you would still have the freedom of creating unit tests by test data sources. 然后,您仍然可以自由地通过测试数据源创建单元测试。

The open/close level and execute functions are tempting too, but try-with-resources and PreparedStatement are superior. 开放/关闭级别和执行功能也很诱人,但是try-with-resources和PreparedStatement是优越的。

try (Connection con = ...) {
}

Closes the connection automatically even with return/exception. 即使返回/异常,也会自动关闭连接。

try (PreparedStatement stm = con.prepare...) {
    stm.setString(1, "me");
    try (ResultSet rs = stm.executeQuery()) {
        while (rs.next()) {
            ...
        }
    }
}

Sounds like you're looking for an enum . 听起来你正在寻找一个enum

enum Db {
    One("jdbc:postgresql://localhost:5432/onebase?user=useradmin&password=123456"),
    Two("Something else");
    private static final String JDBC_DRIVER = "org.postgresql.Driver";
    private static Connection conn = null;
    private final String url;


    Db(String url) {
        this.url = url;
    }

    private static void dbConnect() { ... }

    private static void dbDisconnect() { ... }

    public static ResultSet dbExecuteQuery(String queryStmt) { ... }

    public static void dbExecuteUpdate(String sqlStmt) { ... }

}

Note that any methods that use the url filed will have to be removed from static but that shouldn't be a bad thing. 请注意,任何使用url字段的方法都必须从static删除,但这不应该是一件坏事。 You still only need them once in the code. 您仍然只需要在代码中使用一次。

Just pass the url to the method which connects to the database. 只需将url传递给连接数据库的方法即可。 That way you will first connect to the relevant DB and then perform the queries you need. 这样,您将首先连接到相关的数据库,然后执行所需的查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM