I wrote a singleton class for obtaining a database connection.
Now my question is this: assume that there are 100 users accessing the application. If one user closes
package es.sm2.conexion;
import java.sql.Connection;
import java.sql.DriverManager;
public class ConexionTest {
private static Connection conn = null;
static Connection getConnection() throws Exception {
if (conn == null) {
String url = "jdbc:mysql://localhost:3306/";
String dbName = "test";
String driver = "com.mysql.jdbc.Driver";
String userName = "userparatest";
String password = "userparatest";
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url + dbName, userName, password);
}
return conn;
}
}
To close Connection
public static void closeConnection(Connection conn) {
try {
conn.close();
} catch (SQLException e) {
}
}
To call to the connection:
package conexion.uno;
import java.sql.*;
import es.sm2.conexion.ConexionTest;
public class LLamadorConexion {
public void llamada() {
Connection conn = null;
PreparedStatement statement = null;
ResultSet resultado = null;
String query = "SELECT * FROM empleados";
try {
conn = ConexionTest.getConnection();
statement = conn.prepareStatement(query);
resultado = statement.executeQuery();
while (resultado.next()) {
System.out.println(resultado.getString(1) + "\t" + resultado.getString(2) + "\t" + resultado.getString(3) + "\t" );
}
}
catch (Exception e) {
System.err.println("El porque del cascar: " + e.getMessage());
}
finally {
ConexionTest.closeConnection(conn);
}
}
}
Great post, farhangdon! I, however, found it a little troublesome because once you close the connection, you have no other way to start a new one. A little trick will solve it though:
Replace if(con==null)
with if(con==null || con.isClosed())
As long as you don't return the same Connection
instance on getConnection()
call, then there's nothing to worry about. Every caller will then get its own instance. As far now you're creating a brand new connection on every getConnection()
call and thus not returning some static or instance variable. So it's safe.
However, this approach is clumsy. It doesn't need to be a singleton. A helper/utility class is also perfectly fine. Or if you want a bit more abstraction, a connection manager returned by an abstract factory. I'd only change it to obtain the datasource just once during class initialization instead of everytime in getConnection()
. It's the same instance everytime anyway. Keep it cheap. Here's a basic kickoff example:
public class Database {
private static DataSource dataSource;
static {
try {
dataSource = new InitialContext().lookup("jndifordbconc");
}
catch (NamingException e) {
throw new ExceptionInInitializerError("'jndifordbconc' not found in JNDI", e);
}
}
public static Connection getConnection() {
return dataSource.getConnection();
}
}
which is to be used as follows according the normal JDBC idiom.
public List<Entity> list() throws SQLException {
List<Entity> entities = new ArrayList<Entity>();
try (
Connection connection = Database.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT id, foo, bar FROM entity");
ResultSet resultSet = statement.executeQuery();
) {
while (resultSet.next()) {
Entity entity = new Entity();
entity.setId(resultSet.getLong("id"));
entity.setFoo(resultSet.getString("foo"));
entity.setBar(resultSet.getString("bar"));
entities.add(entity);
}
}
return entities;
}
import java.sql.Connection;
import java.sql.DriverManager;
public class sql11 {
static Connection getConnection() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/ics", "root", "077");
return c;
}
}
Below code is a working and tested Singleton Pattern for Java.
public class Database {
private static Database dbIsntance;
private static Connection con ;
private static Statement stmt;
private Database() {
// private constructor //
}
public static Database getInstance(){
if(dbIsntance==null){
dbIsntance= new Database();
}
return dbIsntance;
}
public Connection getConnection(){
if(con==null){
try {
String host = "jdbc:derby://localhost:1527/yourdatabasename";
String username = "yourusername";
String password = "yourpassword";
con = DriverManager.getConnection( host, username, password );
} catch (SQLException ex) {
Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
}
}
return con;
}
While getting Connection in any Class simply use below line
Connection con = Database.getInstance().getConnection();
Hope it may help :)