I have a main class, a login class and a gui class.
Within my main I am creating a database connection using the Singleton pattern - only one instance of this connection.
I want to access the database connection from login, to verify users upon logging into the system.
My connection method within main:
/**
* Use the Singleton pattern to create one Connection
*/
private static Connection getConnection() {
if (conn != null) {
return conn;
}
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage() + " load driver error");
System.exit(0);
}
try {
//conn = DriverManager.getConnection(host);
conn = DriverManager.getConnection(host + "create=true", dbUsername, dbPassword);
} catch (SQLException e) {
displayErr("Get connection error: ", e);
System.exit(0);
}
return conn;
}
Now, I want to create a login method where I need to use the connection conn. The method is static and I cannot use conn.
I'm sure this is wrong but I've also tried making a public method which returns the connection conn and then tried calling that method from Main.
conn = Main.returnConnection();
What should I do in this situation? Pretty confused at how I'm supposed to model this.
Your approach is so primitive when it's compared with Connection Pooling. Connection pool means a pool that includes cached, reusable connections those can be used in future requests. As you said opening a connection for each user is an expensive process also giving a static connection for each user occurs conflictions. Connection pooling is the standart that should be used in these kind of circumstances.
connection = connectionPool.getConnection();
Upper code means get a connection from the pool, if all connections are already allocated, mechanism automatically creates a new one.
The most popular libraries are:
BoneCP
Apache DBCP
C3p0
I figured out the purpose of the Singleton pattern is to create one instance of something and allow it to be seen by everyone.
So I made it public static void instead and can now access the connection, without making a new one each time.
Correct me if I am wrong but this works fine.
Related
In the JDBC driver for Postgres, is PGSimpleDataSource thread-safe?
That is, if I use a cached singleton instance of that class, can I pass it out to multiple threads? Each thread may be calling getConnection at the same moment. The documentation makes no mention of thread-safety.
I am trying to avoid both (a) making multi-threaded calls on a Connection and (b) using a connection pool, as discussed in the doc. I want a separate Connection for each servlet thread.
I'm assuming you won't be changing the data source configuration on multiple threads, because then it isn't thread-safe. You can inspect the source code yourself, on https://github.com/pgjdbc/pgjdbc, the specific code for getConnection is in BaseDataSource:
public Connection getConnection(String user, String password) throws SQLException {
try {
Connection con = DriverManager.getConnection(getUrl(), user, password);
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Created a {0} for {1} at {2}", new Object[]{getDescription(), user, getUrl()});
}
return con;
} catch (SQLException e) {
LOGGER.log(Level.SEVERE, "Failed to create a {0} for {1} at {2}: {3}",
new Object[]{getDescription(), user, getUrl(), e});
throw e;
}
}
In other words, it is a thin wrapper around DriverManager. DriverManager itself is thread-safe, so then it becomes a question if org.postgresql.Driver is thread-safe. I don't have time to try to verify that, but lets just say it would be really surprising if that wasn't thread-safe (and otherwise world-wide applications would fail with all kinds of strange race-conditions, etc).
As a side note: PGSimpleDataSource does not provide connection pooling, you might want to consider whether that is right for your use case.
so I am currently working on a java application that is supposed to log specific events into a database. I expect that there will be at most 15 to 20 inserts per minute, basically I was wondering if I should make a new connection for every insert statement or keep one open as long as the application is running.
What I am doing is:
public void logEvent(MyCustomEvent e) {
Connection con = null;
Statement st = null;
ResultSet rs = null;
try {
con = DriverManager.getConnection(url, user, password);
st = con.createStatement();
st.executeUpdate("INSERT INTO Table(" + e.data + ");");
} catch (SQLException ex) {
Logger lgr = Logger.getLogger(MySQLConnector.class.getName());
lgr.log(Level.SEVERE, ex.getMessage(), ex);
} finally {
try {
if (rs != null) {
rs.close();
}
if (st != null) {
st.close();
}
if (con != null) {
con.close();
}
} catch (SQLException ex) {
Logger lgr = Logger.getLogger(MySQLConnector.class.getName());
lgr.log(Level.SEVERE, ex.getMessage(), ex);
}
}
}
Is there no problem in making a new connection every time or can/should I buffer the inputs somehow?
Making connections is expensive so it's probably best not to keep making them. However, holding one connection open all the time has its own problems ( what happens if it closes for some reason? )
Why not have a look at database connection pooling - google will show up several competing connection pool implementations for you. You'll get the best of both worlds. To your application, the connection will appear to be permanently open, but if the connection fails for some reason, the connection pool will handle re-opening it for you.
You should keep the connection open and reuse it. Starting up and tearing down a JDBC connection is expensive, especially if you are securing it with SSL.
The other option is to use what is known as a connection pool, where the application doesn't create the JDBC connections directly, but acquires one from a pool of preciously opened connections. When it is done, it returns the connection to the pool.
Your database provider could provide a connection pool library, or you could use something like C3PO. This Q&A lists some other options: Java JDBC connection pool library choice in 2011/2012?
There is a gotcha with keeping connections open for a long time in MySQL. The problem is that MySQL has a default "idle connection" timeout of a few hours (10 or so I think). So if your application sits idle for long periods of time, it can find that its connection is broken. A connection pool may take care of reconnecting for you. Otherwise, the standard workaround for this problem is to increase the default timeout to something REALLY large. For example: MySQL connection timeout
I am developing a web application using JSP & Servlet (IDE: Eclipse, Database: Oracle10).
I have developed java class which returns a static connection, and that connection will be used by my entire web application.
public class DBConnection
{
private static Connection con = null;
static Connection getConnection(String str)
{
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection("MyValuesHere");
System.out.println("New instance of Connection is created for: "+str);
}
catch(ClassNotFoundException cnfe)
{
System.out.println("Error loading class!");
cnfe.printStackTrace();
}
catch(SQLException sqle)
{
System.out.println("Error connecting to the database!");
sqle.printStackTrace();
}
return con;
}//getConnection()
}//class
Above class is working fine. Then I have another 4 java classes for
Inserting
Updating
Deleting
Selecting
data from database using the above connection. So in those 4 classes I am getting connection which is created in my DBConnection class, and those four classes are also working fine. This four classes are used in my all Servlet's.
To get Connection in those 4 classes I am writing following line:
private static Connection con = DBConnection.getConnection("UpdateQuery.java");
But problem is that I want to share the same connection in all four classes, but connection is created separately in those 4 classes. So how should I share the same connection in those four classes? is there better way of doing this? and if I use this approach will there be any issues in web application because of sharing the connection for whole application?
You are (implicitly) trying to solve a non-trivial task.
Such things are normally done by the container - taking connections from a pool, then returning them back, reconnection etc...
If you use a fully functional applications server you'd better configure and use data sources.
If your server doesn't support data sources, do not mess up with saving connection into a private field. What for example happenes when your connection is lost? Your private variable will have a non-working connection. Do you have any recovery mechanism?
Your code will be much more robust if you get it in the beginning of the business operation and then close it.
Or try to find a professionally written library that supports connection pools - it will do pretty much the same as a classic container in handling a connection pool.
Or write it yourself, but it will be a separate task with many questions.
Looks like you wanted to turn Connection into a singleton but then forgot to check whether it's been instantiated already. In getConnection you could check if con is not null in the first place and return that instance right away. Only if con is still null, proceed with initialization.
You should save the created connection instance into a private static field in DBConnection, and when getConnection is called, you check if the field is null, then create the connection, then return it:
if (connection == null) {
connection = createConnection();
}
return connection;
where connection is a private static Connection connection field of DBConnection class.
However I strongly suggest to not use this approach as sharing a connection between concurrent threads will cause serious problems. I suggest to use connection pooling
How to handle sql exceptions in Msaccess jdbc connection? I'm retrieving data from msaccess using jdbc connection in java. If connection fail i need to show-up the custom message instead of throwing exception.
public static Connection getConnection() {
Connection connection = null;
try
{
String url = "jdbc:odbc:db1";
String username = "";
String password = "";
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
connection= DriverManager.getConnection(url, username, password);
}
catch(Exception e)
{
System.out.println("Report");
}
return connection;
}
But its not handling the custom message.its throwing error :
java.sql.SQLException: [Microsoft][ODBC Excel Driver] The Microsoft Jet database engine could not find the object
The location where you are calling getConnection, provide custom message there by handling exception:
Connection con = null;
try {
con = DatabaseUtil.getConnection();
...
...
}catch(Exception e) {
//show message, dialog box, whatever
} finally {
if(con != null) {
try{
con.close();
}catch(SQLException sqe){
//yet another message, unable to close connection cleanly.
}
}
}
P.S. Its a bad idea to declare "Exception", you should always try to throw most relevant exception from your method. SQLException makes more sense in DatabaseUtil.getConnection
P.P.S. Class.forName(driver); is only required once per JVM invocation (for JDBC driver registration). Hence, the appropriate place to register your JDBC drivers is in a static initializer (which is called once when your class is loaded for the first time).
You can not avoid exceptions. Instead of throwing them, you can handle them by using
try{
// do Something
} catch(SqlException e){
// catch exception
} finally {
// do something to get recover
}
For more info follow this link
You cannot avoid the SQLException being thrown. The JDBC APIs don't provide a method to test connection liveness.
To test if a JDBC connection is (still) valid, you perform a simple query. The "dummy query" idiom for doing this varies with the database, but any query on any of your tables will suffice. If the connection is not alive you will get an exception ... which you need to handle.
However it is possible for the database connection to die between you testing the connection and then performing your real query (or whatever). So (IMO) you are better off just writing your code so that it can deal with the SQLException in a real query ... and not bother probing. This also gives better performance, because repeatedly testing to see if a JDBC connection is alive is going to add useless load to your application ... and the database.
i'm gonna create class that will operate on database. The class will have functions addRecord(), getAllRecords(), stuff like that. I'm looking for a good approach to design the class. Should i have to:
1) create new Connection for every function. Like this:
void readRecords(){
try {
Connection con = DriverManager.getConnection (connectionURL);
Statement stmt = con.createStatement();
ResultSet rs = stmd.executeQuery("select moviename, releasedate from movies");
while (rs.next())
System.out.println("Name= " + rs.getString("moviename") + " Date= " + rs.getString("releasedate");
}
catch (SQLException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
con.close();
}
}
or
2) it's better to have one connection as a memeber variable
class MyClass{
private Connection con;
public MyClass(){
con = DriverManager.getConnection (connectionURL);
}
}
and create just the statement for every function.
3) or something else...
Both approaches are bad. The first one won't allow you to implement proper transaction management, since you can't call several methods inside the same transaction. The latter one requires unnecessary creation of multiple objects.
The best approach would be to introduce a notion of the current connection, which can be obtained from some kind of transactional context. Basically, it should look like this:
beginTransaction(...); // Opens connection and starts transaction
readRecords(...); // Uses the current connection
addRecord(...);
...
commitTransaction(...); // Commits transaction and closes connection
The simpliest but not very elegant implementation is to open a Connection inside the calling method (which defines boundaries of the transaction) and pass it to your methods as a parameter.
More sophisticated solution is to create a static ThreadLocal storage for the current Connection, place it there when you start a transaction and obtain it from that storage inside your methods. Some frameworks implement this approach implicitly, for example, Spring Framework.
Note that connection pooling is completely orthogonal to these matters.
If there are frequent regular jdbc calls, then use a database connection pool.
Connection pooling is the way to go. The biggest reason is that on average the time it takes for the DB access (DML etc) is much smaller than the time it takes to create a connection and then close the connection. Additionally, don't forget to close your ResultSet, PreparedStatement and Connection variables after the transaction is done.
You can use tomcat or apache connection pooling classes.
THese classes are defined for example in the package
org.apache.commons.dbcp.*;
org.apache.tomcat.dbcp.dbcp.*;
where dbcp stands for database connection pooling.