简体   繁体   中英

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 .

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:

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... ).

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. 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! 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. (Different for development/production).

One way to use such a DataSource would be using CDI, dependency injection. 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 (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 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. You still only need them once in the code.

Just pass the url to the method which connects to the database. That way you will first connect to the relevant DB and then perform the queries you need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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