import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.Vector;
import javax.sql.DataSource;
import com.bmw.bedarfsplanung.main.Globals;
import oracle.jdbc.pool.OracleDataSource;
/**
* DbHandler ist ein einfacher Connection Pool, der nach Bedarf Verbindungen zu Datenbanken aufmacht,
* aber aus performance Gründen, diese nicht gleich wieder schließst sondern, bei erneuter anfrage, bereits
* offene Verbindungen zurück gibt.
* @author Q240764
*
*/
public class DbHandler {
public static int MIS2 = 0;
public static int LEMO = 1;
private ConnectionData[] connData = {new MIS2Db(), new LemoDb()};
//die offenen verbindungen
private Connection[] connections;
//ist die verbindung in benützung
private boolean[] inUse;
//damit ich weiß welche datenbank eine verbindung gehört
private int[] database;
private static DbHandler instance;
//anzahl der maximal offenen verbindunge
private int maxConnections = 10;
public static synchronized DbHandler getInstance(){
if(instance == null){
instance = new DbHandler();
}
return instance;
}
/**
* Standard konnstruktor, registriert den jdbc Treiber und legt das array für die offenen verbindunge an
*
*/
private DbHandler(){
connections = new Connection[maxConnections];
inUse = new boolean[maxConnections];
database = new int[maxConnections];
try {
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* liefert eine offene Verbindung, für die angeforderte Datenbank aus dem Connection Pool
* ist keine offene vorhanden, wird eine Verbindung aufgebaut
* Es muss sicher gestellt sein, dass eine angeforderte Verbindung über returnConnection wieder zurück gegeben wird
* @param db die Datenbank für die die Verbindung angeforderd wird
* @return eine offenen JDBC Connection
* @throws SQLException wenn ein verbindungsaufbau fehlschlägt
*/
public synchronized Connection getConnection(int db)throws SQLException {
//wenn die verbindung noch null ist: anlegen
for(int i = 0; i < maxConnections; i++){
if(connections[i]==null){
connections[i] = DriverManager.getConnection(connData[db].getHost(), connData[db].getUser(), connData[db].getPass());
inUse[i] = true;
database[i] = db;
return connections[i];
//ist die verbindung, nicht in benützung und von der selben datenbank: zurück geben
}else if((!inUse[i]) && (database[i]==db)){
//ist sie geschlossen muss vorher verbunden werden
if(connections[i].isClosed()){
connections[i] = DriverManager.getConnection(connData[db].getHost(), connData[db].getUser(), connData[db].getPass());
}
database[i] = db;
inUse[i] = true;
return connections[i];
}
}
System.out.println("Max Connections überschritten");
return null;
}
/**
* über getConnection angeforderte Verbindungen, MÜSSEN über diese Methode wieder zurück gegeben werden
* die verbindungen werden nicht geschlossen, sondern über inUse zu Wiederverwendung freigegeben
* @param con
*/
public synchronized void returnConnection(Connection con){
for(int i =0; i < connections.length;i++){
if(con.equals(connections[i])){
inUse[i] = false;
return;
}
}
System.out.println("Connection war nicht vorhanden");
}
/**
* um ein update auszuführen, Connection anfordern, updaten, connection zurück geben
* spart im grunde nur Schreibarbeit
* @param query, die auszuführende abfrage
* @param db die Datenbank, in der die Abfrage ausgeführt werden soll
* @throws SQLException
*/
public static void executeUpdate(String query, int db) throws SQLException{
Connection con = getInstance().getConnection(db);
Statement stmt = null;
try {
stmt = con.createStatement();
if(Globals.debug){
System.out.println(query);
}
stmt.executeUpdate(query);
} catch (SQLException e) {
throw e;
}finally{
if(stmt!=null)
stmt.close();
getInstance().returnConnection(con);
}
}
}