How to switch Databases using Java-JDBC - java

I have 2 databases, Derby DB and Oracle DB. My logic is to check if the Derby DB is active. If yes, I will send SQL queries to it. If the Derby DB is not active I want to create a connection pool to Oracle and perform the SQL updates there.
Is there any way to do this?

You can do it in the following way.
1)Load the Driver for Derby DB and try to connect to the database, if it throws the Exception then u can handle it in catch block.
2) Load the Driver for Oracle DB and connect to the database and do your transactions.
In this way you can do it...

You can used as many database connection as you want. You just need to create the connection provider that will serve the logic. In that connection provider you first create a connection to Derby if fail then try to Oracle.
What you need to assure is that you have proper drivers to both database and proper connection string.
TO assure that you have class
Class.forName("oracle.jdbc.driver.OracleDriver");
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
In case then a class is not found above code will throw Exception
About Derby Connection String
About Oracle Connection String
I also advise you to read JDBC Tutorial, and when your project will evolve you might want to use some ORM.
Good luck!

you could try something like this i suppose:
getDerbyConnection();
if(derbyConnectionActive) {
//execute queries on derbyDb
}
else {
getOracleDBConnection();
//execute queries on Oracle
}

Related

Does JDBC template cache connection?

I have an java-spring web application, which will read, write and delete information from a user upload SQLite DB. I am using JDBCtemplate to set connection, query the DB and update the information.
I observed one behavior during my tests:
Every time,after users uploaded a new SQLite db file(it will has the same name, place at the same directory as the old DB file), if they do not reboot/restart tomcat, jdbcquery will report the db was corrupted exception.
To me this looked like the JDBCtemplate somehow cached the connection and is trying to resume the connection with the old db?
If so, do you know anyway to refresh the connection without rebooting the application?
final SingleConnectionDataSource dataSource = new singleConnectionDataSource();
try {
Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException e) {
throw new applicationException(MessageTemplateNames.GENERAL_UNKNOWN_ERROR, e);
}
createDirectoryForDbIfNotExists();
dataSource.setUrl(String.format("%s%s", JDBC.PREFIX, getDbFileLocation()));
dataSource.setAutoCommit(true);
JDBCTemplate does not handle connection.It obtains the connection from the datasource set to it.
From the reference documentation for SingleConnectionDataSource
Implementation of SmartDataSource that wraps a single JDBC Connection
which is not closed after use. .....
This is primarily intended for testing. For example, it enables easy
testing outside an application server, for code that expects to work
on a DataSource. In contrast to DriverManagerDataSource, it reuses the
same Connection all the time, avoiding excessive creation of physical
Connections.
A DriverManagerDataSource will suite your requirement to get a new connection without reboot
Simple implementation of the standard JDBC DataSource interface,
configuring the plain old JDBC DriverManager via bean properties, and
returning a new Connection from every getConnection call.
Update
My answer might not solve your original problem , but will only answer the question for new connection without reboot. Please go through #Thilo's comment on the same.

Java jdbc - how to execute a statement strictly read only

My server app uses prepared statements in almost all cases, to prevent sql injection. Nevertheless a possibility is needed providing special users executing raw SELECT queries.
How can I more or less securely make sure the query does not modify the database? Is it possible to execute a query read only, or is there any other 'secure' way making sure noone tries any sql injection?
(Using sqlite3, so I cannot use any privileges)
Thanks a lot!
JDBC supports read-only connections by calling Connection.setReadOnly(true). However the javadoc says:
Puts this connection in read-only mode as a hint to the driver to enable database optimizations.
Some JDBC drivers will enforce the read-only request, others will use it for optimizations only, or simply ignore it. I don't know how sqlite3 implements it. You'll have to test that.
Otherwise, you could do a "simple" parse of the SQL statement, to ensure that it's a single valid SELECT statement.
I'm not aware of a general JBDC configuration which specifies readonly. But Sqlite does have special database open modes and this can be leveraged in your connection to your sqlite database. Eg.
Properties config = new Properties();
config.setProperty("open_mode", "1"); //1 == readonly
Connection conn = DriverManager.getConnection("jdbc:sqlite:sample.db", config);
Credit: https://stackoverflow.com/a/18092761/62344
FWIW All supported open modes can be seen here.
If you use some sort of factory class to create or return connections to the database, you can individually set connections to be read-only:
public Connection getReadOnlyConnection() {
// Alternatively this could come from a connection pool:
final Connection conn = DriverManager.getConnection("jdbc:sqlite:sample.db");
conn.setReadOnly(true);
return conn;
}
If you're using a connection pool, then you may also want to provide a method for getting writeable connections too:
public Connection getWriteableConnection() {
final Connection conn = getPooledConnection(); // I'm assuming this method exists!
conn.setReadOnly(false);
return conn;
}
You could also provide just a single getConnection(boolean readOnly) method and simply pass the parameter through to the setReadOnly(boolean) call. I prefer the separate methods personally, as it makes your intent much clearer.
Alternatively, some databases like Oracle provide a read only mode that can be enabled. SQLite doesn't provide one, but you can emulate it by simply setting the actual database files (including directories) to read only on the filesystem itself.
Another way of doing it is as follows (credit goes to deadlock for the below code):
public Connection getReadOnlyConnection() {
SQLiteConfig config = new SQLiteConfig();
config.setReadOnly(true);
Connection conn = DriverManager.getConnection("jdbc:sqlite:sample.db",
config.toProperties());
}

Connection to non existing mongodb server does not throw exception

I'm playing around a bit with the MongoDB driver for Java. So I just created a simple application to connect to a MongoDB server and select a database.
So I created an instance of MongoClient and selected a 'DB':
try
{
MongoClient client = new MongoClient("localhost", 27017);
DB database = client.getDB("example");
}catch(Exception e){
e.printStackTrace();
}
Because of the fact that there is no running instance of mongod on my machine, I expected that client would throw an Exception. Unfortunately that isn't the case.
Even when selecting the database nothing happens. It just behaves like if there was a running mongod instance.
I looked into the documentation about the Java driver but couldn't find anything about it. Same with Google.
Is there anything I missed?
I'm using the latest MongoDB driver (version 2.12.2) from the official website.
It is expected behaviour. The driver does not attempt to connect to the database until it is needed. If you try the mongo shell, you do not get the error if the database does not exist.
When you try to insert a document into a non-existent collection it is created for you automatically and that is when the connection is lazily established. It is first when you actually perform some db operation (find(), insert() etc.) that the connection is checked for.
Try doing an insert to a collection. Connections are lazily initialized and validated.

JDBC opening a new database session

I just want to make sure that if I use the following, I am opening a separate DB session and not resuing the same one (for testing I need individual sessions).
Connection connection = DriverManager.getConnection(URL,USER,PASSWORD);
each time I do the above code, I run my query, then do a connection.close()
So for example:
while(some condition) {
Connection connection = DriverManager.getConnection(URL,USER,PASSWORD);
//now use the connection to generate a ResultSet of some query
connection.close();
}
So, each iteration of the loop (each query) needs its own session.
Is this properly opening separte sessions as I need (and if not, what would I need to add/change)? thanks
The javadoc says:
Attempts to establish a connection to
the given database URL
Slightly woolly language, and I suspect that this is up to the JDBC driver, but I'd be surprised if this did anything other than open a new connection.
I suppose it's possible for a JDBC driver to perform connection pooling under the hood, but I'd be surprised to see that.
In the case of the Oracle JDBC driver, this will open a new connection every time. This is a relatively slow process in Oracle, you may want to consider using a connection pool (e.g. Apache Commons DBCP, or c3p0) to improve performance.

Help me connecting java and oracle

Can anybody explain me these classes and methods?
DriverManager.registerDriver
(new oracle.jdbc.driver.OracleDriver());
conn = java.sql.DriverManager.getConnection(
"jdb:ocracle:thin:username/password#machine.us.company.com:1234:dbSID");
Thanks
Let's decode the lines of your code block:
1. DriverManager.registerDriver
2. (new oracle.jdbc.driver.OracleDriver());
3. conn = java.sql.DriverManager.getConnection(
4. "jdbc:oracle:thin:username/password#machine.us.company.com:1234:dbSID");
Line 2:
Creates a new instance of oracle.jdbc.driver.OracleDriver, a JDBC Driver for the Oracle database. A JDBC driver implements the interfaces and classes defined by the JDBC API that programmers use to connect to a database and perform queries.
Line 1
Registers the instance of the oracle.jdbc.driver.OracleDriver to the DriverManager class which is the traditional management layer of JDBC, working between the user and the drivers. It handles establishing a connection between a database and the appropriate driver.
Line 3:
Now that the communication layer between the JDBC application and the database is ready, you can create a connection by calling getConnection() method of the DriverManager class.
Line 4:
This is the "connection string" or "database URL". This String identifies the database you want to connect to. The scheme of this URL is specific to the database provider and/or the driver (here, Oracle and its "thin" driver).
Note that prior to Java 6, calling Class.forName was the preferred way to load and register a JDBC Driver. It was the responsibility of the Driver to call DriverManager.registerDriver.
[...] All Driver classes should be written with a static section (a static initializer) that creates an instance of the class and then registers it with the DriverManager class when it is loaded. Thus, a user would not normally call DriverManager.registerDriver directly; it should be called automatically by a Driver class when it is loaded.
Check the Driver Manager chapter from the JDBC documentation for more details.
This is JDBC which is the way Java programs talk to a database, and your sample explicitly asks for the Oracle driver which requires their driver in your classpath.
Sun has a good tutorial on the matter at http://java.sun.com/docs/books/tutorial/jdbc/overview/index.html
The DriverManager class in java handles the connections between the database and the jdbc drivers, routing db i/o to the correct jdbc driver (you can have multiple drivers active ie connections to multiple types of database).
Drivers are registered with the DriverManager so that they become part of its working set. The next step is to create a connection to your database, so you can run queries. This is achived by the
Connection conn = DriverManager.getConnection("jdb:ocracle:thin:username/password#machine.us.company.com:1234:dbSID")
method. The connection String passed into the getConnection() method is driver-specific, you need to RTFM for each driver. Note that the DriverManager selects the driver automatically from its list of registered drivers, according to the syntax of the connection string you pass in.
The Connection object returned is your handle for preparing statements and running queries against the database

Categories