Interface and inheritance for the java connection class

5

Considering object orientation, would the use of inheritance and interface in this way be correct? But in this way, any request to connect to the database will require a new object. Is there a way to statically access or need a new object created when booting the system using Singleton?

Connection Interface

public interface ConnectionDB {
    public Connection getConnection();
}

GenericConnection class

public class GenericConnection {

    protected static Properties dbProperties = new Properties();    

    public static Properties getDbProperties() {
        if(dbProperties == null){
            try {
                dbProperties.load(new FileInputStream("src/properties/conf.properties"));
            } catch (FileNotFoundException ex) {
                Logger.getLogger(GenericConnection.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(GenericConnection.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return dbProperties;
    }

    public static void setDbProperties(Properties dbProperties) {
        GenericConnection.dbProperties = dbProperties;
    }
}

OracleConnection Class

public class OracleConnection extends GenericConnection implements ConnectionDB {

    private Connection conn;
    private Statement st;

    public Statement getSt() {
        return st;
    }

    public void setSt(Statement st) {
        this.st = st;
    }

    public Connection getConn() {
        return conn;
    }

    public void setConn(Connection conn) {
        this.conn = conn;
    }

    @Override
    public Connection getConnection() {
        if (getConn() != null) {
            return getConn();
        } else {
            try {
                String url = "jdbc:oracle:thin:@" + getDbProperties().getProperty("ServerOracle") + ":" + getDbProperties().getProperty("portOracle") + ":" + getDbProperties().getProperty("sidOracle");
                setConn(DriverManager.getConnection(url, getDbProperties().getProperty("userOracle"), getDbProperties().getProperty("passwdOracle")));
                setSt(getConn().createStatement());
                return getConn();
            } catch (SQLException ex) {
                Logger.getLogger(OracleConnection.class.getName()).log(Level.SEVERE, null, ex);
                return null;
            }
        }
    }

}
    
asked by anonymous 27.07.2016 / 13:38

2 answers

4

It's hard to talk about right, some say it's the right thing to do, others say it's wasteful to have to create new objects all the time.

Particularly I would do a Singleton. But I do not know the specific need. This class is almost one.

There is a serious error in this implementation since the parent class only has static members, so it will not inherit anything.

Maybe even if it were all static, but there would be no point in using inheritance.

What I think is that this interface is unnecessary. It seems to me that the GenericConnection class should be abstract and contain the getConnection() method with no implementation to let the concrete class solve this. Actually I think a lot of what is in the derived class could be in the inherited class.

Example:

public abstract class GenericConnection {

    private Connection conn;
    private Statement st;

    public Statement getSt() {
        return st;
    }

    public void setSt(Statement st) {
        this.st = st;
    }

    public Connection getConn() {
        return conn;
    }

    public void setConn(Connection conn) {
        this.conn = conn;
    }

    protected Properties dbProperties = new Properties();    

    public Properties getDbProperties() {
        if (dbProperties == null) {
            try {
                dbProperties.load(new FileInputStream("src/properties/conf.properties"));
            } catch (FileNotFoundException ex) {
                Logger.getLogger(GenericConnection.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(GenericConnection.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return dbProperties;
    }

    public void setDbProperties(Properties dbProperties) {
        GenericConnection.dbProperties = dbProperties;
    }

    public Connection getConnection();
}

public class OracleConnection extends GenericConnection {

    @Override
    public Connection getConnection() {
        if (getConn() != null) {
            return getConn();
        } else {
            try {
                String url = "jdbc:oracle:thin:@" + getDbProperties().getProperty("ServerOracle") + ":" + getDbProperties().getProperty("portOracle") + ":" + getDbProperties().getProperty("sidOracle");
                setConn(DriverManager.getConnection(url, getDbProperties().getProperty("userOracle"), getDbProperties().getProperty("passwdOracle")));
                setSt(getConn().createStatement());
                return getConn();
            } catch (SQLException ex) {
                Logger.getLogger(OracleConnection.class.getName()).log(Level.SEVERE, null, ex);
                return null;
            }
        }
    }
}

Just an improved example, I'm not saying you should use this exactly.

    
27.07.2016 / 13:52
0

The comment was going to get very big so it turned out to be an answer.

I do not know if I understand the issue of creating objects all the time, but unless you are doing batch operations, it is better that every operation on the database is done with a Connection different. This is because reusing the same connection for two requested operations in a gap range can cause undesirable timeouts .

On the subject of object orientation, I would avoid creating a generic DAO from which the other DAOs inherit. You have a Caelum post explaining that it is a use of unnecessary inheritance .

As for how to get the property strings to create the connections, I would prefer to read them from the file in a separate code and then pass them to a FabricaDeConexoes class via constructor (this class would have a criarConexao() ), and then pass this fabrica object to each DAO also via DAO constructor.

Note that I did not enter into the issue of having a pool of connections, which in your case may not even be necessary.

I accept criticism and suggestions.

    
28.07.2016 / 02:44