Dependency Injection from an Abstract T type class

Viewed 47

I have configured Oracle and Postgres databases in the code. Since oracle and Postgres have their differences in setting boolean values and others. I want to configure 2 different classes(PostgresSetter and OracleSetter) that set values according to DB type. At the start of the run time, I want to inject the database's setter class according to the driver type. Currently, I comment out the unused database but I want to do that programmatically.

public abstract class DBSetter<T> /*implements DBSetter this interface added later*/{
    public static void setParameter(PreparedStatement statement, int index, Boolean data)
            throws Exception {
        if (data != null) {
            statement.setBoolean(index, data);
        } else {
            //if psql
            statement.setNull(index, Types.BOOLEAN);
            //if oracle
            statement.setNull(index, Types.INTEGER);
        }
        ...//other functions
    }
}

Above is the class that sets the boolean value to the prepared statement. I want to split that into 2 as below.

public interface DBSetter {

    static void setParameter(PreparedStatement statement, int index, Boolean data)
            throws Exception {}

}

public class OracleSetter implements DBSetter {

    public static void setParameter(PreparedStatement statement, int index, Boolean data)
            throws Exception {
        if (data != null) {
            statement.setBoolean(index, data);
        } else {
            statement.setNull(index, Types.INTEGER);
        }
    }
}

public class PostgresSetter implements DBSetter {

    public static void setParameter(PreparedStatement statement, int index, Boolean data)
            throws Exception {
        if (data != null) {
            statement.setBoolean(index, data);
        } else {
            statement.setNull(index, Types.BOOLEAN);
        }
    }
}

I created an interface and created 2 new classes called OracleSetter and PostgreSetter and implemented the interface. Still, the function setParameter is not recognized. How can I inject Setters at the startup according to an if clause?

1 Answers

I will assume that you are using Spring framework for dependency injection, so you are injecting your beans with @Autowired, in your case the interface you are trying to inject is DBSetter.

We will continue using your second code snippet but after removing the static methods:

public interface DBSetter {

    void setParameter(PreparedStatement statement, int index, Boolean data)
            throws Exception;

}

public class OracleSetter implements DBSetter {

    public void setParameter(PreparedStatement statement, int index, Boolean data)
            throws Exception {
        if (data != null) {
            statement.setBoolean(index, data);
        } else {
            statement.setNull(index, Types.INTEGER);
        }
    }
}

public class PostgresSetter implements DBSetter {

    public void setParameter(PreparedStatement statement, int index, Boolean data)
            throws Exception {
        if (data != null) {
            statement.setBoolean(index, data);
        } else {
            statement.setNull(index, Types.BOOLEAN);
        }
    }
}

And you need to configure the bean injection using a configuration class like below:

@Configuration
public class DBSetterConfiguration {
      @Bean
      public DBSetter configureDBSetter() {
            if(isPsql()) { // try to implement isPsql yourself, the method to check if you are using Postgres or not
               return new PostgresSetter();
            }
            else {
                return new OracleSetter();
            }
      }
}

Finally you call DBSetter using @Autowired:

@Autowired
DBSetter dbSetter;
Related