Question

Disclaimer: I previously posted this on Stack Overflow, but it seems that perhaps that was not the correct site for the question. If this is still not the correct site, please let me know.

I'm working on a Java project that needs to connect to a database. I don't know what the DBMS is ahead of time (the client could be using postgres, sqlite, mssqlserver, etc.), so I'm going to read in the db connection info from an xml file. To connect to the database, I need to use the correct implementation of DataSource based on what I read in from the config.xml file.

E.g., if the DBMS is postgres, I'll need to use a PGSimpleDataSource, but if it's sqlite, I'll need to use a SQLiteDataSource.

My thought was that I would simply have a bunch of if-statements and declare the DS inside them like this:

String db_engine = readXML(xmldoc, "dbname");
if (db_engine == "postgres")
{
    PGSimpleDataSource ds = new PGSimpleDataSource();
} else {/* set ds for sqlite, mysql, etc. */}

ds.setServerName(<vars>);
//setup, etc.
//calls to db

However, it seems there is no way to do this in Java (see this related question) because any variables declared inside an if-statement are local to that block. And I cannot declare it outside of the if-statements because I won't know which DataSource to use until runtime (and the compiler won't let me re-declare it inside an if-statement).

All leads me to believe that there's something wrong with the way I'm approaching the problem. I could just have a bunch of separate functions with calls to them in the if-statements, but I feel like that's going to lead to a lot of essentially duplicate code, since I'll need to put all the db calls and everything in there as well.

Given this, what is the correct way to dynamically declare the type of a variable? Or if I'm on entirely the wrong track, what's the right way to do what I'm attempting?

Was it helpful?

Solution

You need to declare the variable outside the ifs with type DataSource and assign to it.

DataSource ds;
if (db_engine == "postgres")
{
    ds = new PGSimpleDataSource();
} else {
    /* set ds for sqlite, mysql, etc. */
}

This works because PGSimpleDataSource, SQLiteDataSource, etc all implement the DataSource interface.

However

No two databases support quite the same dialect of SQL. Supporting multiple databases works as long as you stick to really simple SQL. The moment you try to do something more complicated, your SQL will become specific to a particular database.

The consequence is that is almost never a good reason to be database agnostic. Its difficult, a lot of extra works, and gives you pretty much nothing. In almost all cases, you should pick your database and stick with it.

Now, you might be in the 1% of cases where this make sense. If so, carry on. But probably not.

Licensed under: CC-BY-SA with attribution
scroll top