2010-04-15 20:52:34 +00:00
|
|
|
package zutil.db;
|
|
|
|
|
|
|
|
|
|
import java.sql.Connection;
|
|
|
|
|
import java.sql.DriverManager;
|
|
|
|
|
import java.sql.PreparedStatement;
|
|
|
|
|
import java.sql.ResultSet;
|
|
|
|
|
import java.sql.SQLException;
|
|
|
|
|
import java.sql.Statement;
|
2011-03-19 23:04:41 +00:00
|
|
|
import java.util.logging.Level;
|
|
|
|
|
import java.util.logging.Logger;
|
2010-04-15 20:52:34 +00:00
|
|
|
|
|
|
|
|
import javax.naming.InitialContext;
|
|
|
|
|
import javax.naming.NamingException;
|
|
|
|
|
import javax.sql.DataSource;
|
|
|
|
|
|
2011-06-24 23:20:59 +00:00
|
|
|
import zutil.db.handler.SimpleSQLHandler;
|
2011-03-19 23:04:41 +00:00
|
|
|
import zutil.log.LogUtil;
|
2011-01-21 18:34:23 +00:00
|
|
|
|
2010-04-15 20:52:34 +00:00
|
|
|
public class DBConnection{
|
2011-03-19 23:04:41 +00:00
|
|
|
private static final Logger logger = LogUtil.getLogger();
|
|
|
|
|
|
2010-04-15 20:52:34 +00:00
|
|
|
public enum DBMS{
|
|
|
|
|
MySQL
|
|
|
|
|
}
|
|
|
|
|
// The connection
|
|
|
|
|
private Connection conn = null;
|
|
|
|
|
// The pool that this connection belongs to
|
|
|
|
|
private DBConnectionPool pool;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates an Connection from JNDI
|
|
|
|
|
*
|
|
|
|
|
* @param jndi the name of the connection, e.g. "jdbc/mysql"
|
|
|
|
|
*/
|
|
|
|
|
public DBConnection(String jndi) throws NamingException, SQLException{
|
|
|
|
|
InitialContext ctx = new InitialContext();
|
|
|
|
|
DataSource ds = (DataSource)ctx.lookup("java:comp/env/"+jndi);
|
|
|
|
|
conn = ds.getConnection();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates an Connection to a MySQL server
|
|
|
|
|
*
|
|
|
|
|
* @param url is the URL of the MySQL server
|
|
|
|
|
* @param db is the database to connect to
|
|
|
|
|
* @param user is the user name
|
|
|
|
|
* @param password is the password
|
|
|
|
|
*/
|
|
|
|
|
public DBConnection(String url, String db, String user, String password) throws Exception{
|
|
|
|
|
this(DBMS.MySQL, url, db, user, password);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates an Connection to a DB server
|
|
|
|
|
*
|
|
|
|
|
* @param dbms is the DB type
|
|
|
|
|
* @param url is the URL of the MySQL server
|
|
|
|
|
* @param db is the database to connect to
|
|
|
|
|
* @param user is the user name
|
|
|
|
|
* @param password is the password
|
|
|
|
|
*/
|
|
|
|
|
public DBConnection(DBMS dbms, String url, String db, String user, String password) throws Exception{
|
|
|
|
|
String dbms_name = initDriver(dbms);
|
|
|
|
|
conn = DriverManager.getConnection ("jdbc:"+dbms_name+"://"+url+"/"+db, user, password);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return the underlying connection
|
|
|
|
|
*/
|
|
|
|
|
public Connection getConnection(){
|
|
|
|
|
return conn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initiates the DB driver and returns its protocol name.
|
|
|
|
|
*
|
|
|
|
|
* @param db is the DB type
|
|
|
|
|
* @return the protocol name of the DBMS
|
|
|
|
|
*/
|
|
|
|
|
public String initDriver(DBMS db) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
|
|
|
|
|
switch(db){
|
|
|
|
|
case MySQL:
|
|
|
|
|
Class.forName ("com.mysql.jdbc.Driver").newInstance();
|
|
|
|
|
DriverManager.setLoginTimeout(10);
|
|
|
|
|
return "mysql";
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return the last inserted id or -1 if there was an error
|
|
|
|
|
*/
|
2010-10-07 11:27:23 +00:00
|
|
|
public Object getLastInsertID(){
|
2010-04-15 20:52:34 +00:00
|
|
|
try{
|
2011-06-24 23:20:59 +00:00
|
|
|
return exec("SELECT LAST_INSERT_ID()", new SimpleSQLHandler<Object>());
|
2010-05-18 20:36:44 +00:00
|
|
|
}catch(SQLException e){
|
2011-03-19 23:04:41 +00:00
|
|
|
logger.log(Level.WARNING, null, e);
|
|
|
|
|
}
|
|
|
|
|
return null;
|
2010-04-15 20:52:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Runs a Prepared Statement.<br>
|
|
|
|
|
* <b>NOTE:</b> Don't forget to close the PreparedStatement or it can lead to memory leaks
|
|
|
|
|
*
|
|
|
|
|
* @param sql is the SQL query to run
|
|
|
|
|
* @return An PreparedStatement
|
|
|
|
|
*/
|
|
|
|
|
public PreparedStatement getPreparedStatement(String sql) throws SQLException{
|
|
|
|
|
return conn.prepareStatement(sql);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <b>NOTE:</b> Don't forget to close the Statement or it can lead to memory leaks
|
|
|
|
|
*
|
|
|
|
|
* @return an Statement for the DB
|
|
|
|
|
*/
|
|
|
|
|
public Statement getStatement() throws SQLException{
|
|
|
|
|
return conn.createStatement();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Executes an query and cleans up after itself.
|
|
|
|
|
*
|
|
|
|
|
* @param query is the query
|
|
|
|
|
* @return update count or -1 if the query is not an update query
|
|
|
|
|
*/
|
|
|
|
|
public int exec(String query) throws SQLException {
|
|
|
|
|
PreparedStatement stmt = getPreparedStatement( query );
|
|
|
|
|
return exec(stmt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Executes an query and cleans up after itself.
|
|
|
|
|
*
|
|
|
|
|
* @param stmt is the query
|
|
|
|
|
* @return update count or -1 if the query is not an update query
|
|
|
|
|
*/
|
|
|
|
|
public static int exec(PreparedStatement stmt) throws SQLException {
|
|
|
|
|
return exec(stmt, new SQLResultHandler<Integer>(){
|
2010-10-07 11:27:23 +00:00
|
|
|
public Integer handleQueryResult(Statement stmt, ResultSet result) {
|
2010-04-15 20:52:34 +00:00
|
|
|
try {
|
|
|
|
|
return stmt.getUpdateCount();
|
|
|
|
|
} catch (SQLException e) {
|
2011-03-19 23:04:41 +00:00
|
|
|
logger.log(Level.WARNING, null, e);
|
2010-04-15 20:52:34 +00:00
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Executes an query and cleans up after itself.
|
|
|
|
|
* @param <T>
|
|
|
|
|
*
|
|
|
|
|
* @param query is the query
|
|
|
|
|
* @param handler is the result handler
|
|
|
|
|
* @return update count or -1 if the query is not an update query
|
|
|
|
|
*/
|
|
|
|
|
public <T> T exec(String query, SQLResultHandler<T> handler) throws SQLException {
|
|
|
|
|
PreparedStatement stmt = getPreparedStatement( query );
|
|
|
|
|
return exec(stmt, handler);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Executes an query and cleans up after itself.
|
|
|
|
|
*
|
|
|
|
|
* @param stmt is the query
|
|
|
|
|
* @param handler is the result handler
|
|
|
|
|
* @return the object from the handler
|
|
|
|
|
*/
|
|
|
|
|
public static <T> T exec(PreparedStatement stmt, SQLResultHandler<T> handler) throws SQLException{
|
|
|
|
|
try{
|
|
|
|
|
// Execute
|
|
|
|
|
stmt.execute();
|
|
|
|
|
|
|
|
|
|
// Handle result
|
|
|
|
|
if( handler != null ){
|
|
|
|
|
ResultSet result = null;
|
|
|
|
|
try{
|
|
|
|
|
result = stmt.getResultSet();
|
2010-10-07 11:27:23 +00:00
|
|
|
return handler.handleQueryResult(stmt, result);
|
2010-04-15 20:52:34 +00:00
|
|
|
}finally{
|
|
|
|
|
if(result != null){
|
|
|
|
|
try {
|
|
|
|
|
result.close();
|
|
|
|
|
} catch (SQLException e) { }
|
|
|
|
|
result = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Cleanup
|
|
|
|
|
} finally {
|
|
|
|
|
if (stmt != null) {
|
|
|
|
|
try {
|
|
|
|
|
stmt.close();
|
|
|
|
|
} catch (SQLException sqlex) { }
|
|
|
|
|
stmt = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sets the pool that this connection belongs to
|
|
|
|
|
*
|
|
|
|
|
* @param pool is the pool
|
|
|
|
|
*/
|
|
|
|
|
protected void setPool(DBConnectionPool pool){
|
|
|
|
|
if( pool != null )
|
|
|
|
|
pool.removeConnection(this);
|
|
|
|
|
this.pool = pool;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Checks if the DB Connection is valid and functioning
|
|
|
|
|
*
|
|
|
|
|
* @return true or false depending on the validity of the connection
|
|
|
|
|
*/
|
|
|
|
|
public boolean valid(){
|
|
|
|
|
try {
|
|
|
|
|
conn.getMetaData();
|
2010-05-18 20:36:44 +00:00
|
|
|
return !conn.isClosed();
|
2010-04-15 20:52:34 +00:00
|
|
|
}catch (Exception e) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Disconnects from the database or releases the connection back to the pool
|
|
|
|
|
*/
|
2010-05-18 20:36:44 +00:00
|
|
|
public void close(){
|
2010-04-15 20:52:34 +00:00
|
|
|
if(pool!=null){
|
|
|
|
|
pool.releaseConnection(this);
|
2010-05-18 20:36:44 +00:00
|
|
|
conn = null;
|
2010-04-15 20:52:34 +00:00
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
forceClose();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Disconnects from the database
|
|
|
|
|
*/
|
|
|
|
|
public void forceClose(){
|
|
|
|
|
if (conn != null) {
|
|
|
|
|
try {
|
2011-03-27 20:01:36 +00:00
|
|
|
if( !conn.isClosed() )
|
2011-03-19 23:04:41 +00:00
|
|
|
conn.close();
|
|
|
|
|
} catch (SQLException e) {
|
|
|
|
|
logger.log(Level.WARNING, null, e);
|
2010-04-15 20:52:34 +00:00
|
|
|
}
|
|
|
|
|
conn = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean equals(Object o){
|
|
|
|
|
return conn.equals(o);
|
|
|
|
|
}
|
|
|
|
|
}
|