📄 database.java
字号:
return true; } } return false; } private ConnectionDescr newConnection() { try { Class.forName(dbDriverString); Connection con = DriverManager.getConnection(conStr, user, pw); ConnectionDescr cd = new ConnectionDescr(con); return cd; } catch (ClassNotFoundException e) { System.err.println("createConnection ClassNotFoundExecption error: " + e.getMessage()); } catch (SQLException e) { System.err.println("createConnection error: " + e.getMessage()); } return null; } public void setReturnOnReconnectFail(boolean b) { returnOnReconnectFail = b; } public boolean getReturnOnReconnectFail() { return returnOnReconnectFail; } public void beginTransaction() throws SQLException { //System.out.println("["+Integer.toHexString(Thread.currentThread().hashCode())+"] "+"Entering beginTransaction"); //System.out.println("["+Integer.toHexString(Thread.currentThread().hashCode())+"] "+"* beginTransaction entered"); ConnectionDescr cd = getTransactionCon(true); //System.out.println("["+Integer.toHexString(Thread.currentThread().hashCode())+"] "+"* getTransCont done.."); cd.setAutoCommit(false); } public void commit() throws SQLException { //System.out.println("["+Integer.toHexString(Thread.currentThread().hashCode())+"] "+"Entering sync activeTrans"); //System.out.println("["+Integer.toHexString(Thread.currentThread().hashCode())+"] "+"commit calling getTrans"); ConnectionDescr cd = getTransactionCon(false); //System.out.println("["+Integer.toHexString(Thread.currentThread().hashCode())+"] "+"commit returned from getTrans"); if (cd == null) return; cd.commit(); cd.setAutoCommit(true); freeTransactionCon(cd); } public void rollback() throws SQLException { ConnectionDescr cd = getTransactionCon(false); if (cd == null) return; cd.rollback(); cd.setAutoCommit(true); freeTransactionCon(cd); } private ConnectionDescr getTransactionCon(boolean create) throws SQLException { Thread t = Thread.currentThread(); ConnectionDescr cd = null; //System.out.println("["+Integer.toHexString(Thread.currentThread().hashCode())+"] "+"getTransCon calling getCon"); synchronized (activeTransactions) { cd = (ConnectionDescr)activeTransactions.get(t); } if (cd == null && create) { cd = getTransConnection(); synchronized (activeTransactions) { activeTransactions.put(t, cd); } } //System.out.println("["+Integer.toHexString(Thread.currentThread().hashCode())+"] "+"getTransCon *done*"); return cd; } private void freeTransactionCon(ConnectionDescr cd) { activeTransactions.remove(Thread.currentThread()); freeTransConnection(cd); } private String getConnectString() { return conStr; } private void storeConnectString() { conStr = "jdbc:"; switch (dbDriver) { case MYSQL_DRIVER: dbDriverString = dbDriverMysql; conStr += "mysql"; break; case ORACLE_DRIVER: //"jdbc:oracle:thin:@loiosh.stud.idb.hist.no:1521:orcl"; dbDriverString = dbDriverOracle; conStr += "oracle"; break; case POSTGRESQL_DRIVER: default: dbDriverString = dbDriverPostgresql; conStr += "postgresql"; break; } conStr += "://" + serverName; if (serverPort != null) conStr += ":"+serverPort; conStr += "/" + dbName; } private class ConnectionDescr { private Connection con; private long lastUsed; private Statement updateStatement; public ConnectionDescr(Connection _con) throws SQLException { con = _con; lastUsed = System.currentTimeMillis(); newUpdateStatement(); con.setAutoCommit(true); } public void close() throws SQLException { con.close(); } public void setAutoCommit(boolean autoCommit) throws SQLException { con.setAutoCommit(autoCommit); lastUsed = System.currentTimeMillis(); } public void commit() throws SQLException { con.commit(); lastUsed = System.currentTimeMillis(); } public void rollback() throws SQLException { con.rollback(); lastUsed = System.currentTimeMillis(); } private void newUpdateStatement() throws SQLException { /* XXX: The following if clause has been commented out because * it causes a race condition. The updateStatement instance * may still be held by another thread, and so closing it * explicitly here may cause that thread to throw an * SQLException from using an already closed statement. * According to the Java Docs, a Statement object will be * closed when garbage collected, which seems to be a better * approach in this situation. */// if (updateStatement != null) {// updateStatement.close();// } updateStatement = con.createStatement(); lastUsed = System.currentTimeMillis(); } public Statement getStatement(boolean autoclose) throws SQLException { StatementQ stQ = getOrCreateStatementQ(); synchronized (globStatementQ) { if (globStatementQ.size() > DEFAULT_GLOBAL_STATEMENT_BUFFER) { ((Statement)globStatementQ.removeFirst()).close(); } } return stQ.getStatement(autoclose); } public Statement getUpdateStatement() throws SQLException { newUpdateStatement(); return updateStatement; } private StatementQ getOrCreateStatementQ() { Thread t = Thread.currentThread(); StatementQ q; if ((q=(StatementQ)statementMap.get(t)) == null) statementMap.put(t, q = new StatementQ()); return q; } private class StatementQ { LinkedList statementQ; // FIFO list over statements int bufferSize; public StatementQ() { this(DEFAULT_THREAD_STATEMENT_BUFFER); } public StatementQ(int _bufferSize) { bufferSize = _bufferSize; statementQ = new LinkedList(); } public Statement getStatement(boolean autoclose) throws SQLException { Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); if (autoclose) { statementQ.add(st); if (statementQ.size() > bufferSize) { synchronized (globStatementQ) { globStatementQ.add(statementQ.removeFirst()); } } } lastUsed = System.currentTimeMillis(); return st; } } } } // Changes the active DB that is to be used for subsequent DB calls public static void setActiveDB(String conId) { activeDB.put(Thread.currentThread(), conId); } private static Statement getStatement(String conId, boolean autoclose) throws SQLException { return getDBDescr(conId).getStatement(autoclose); } private static Statement getUpdateStatement(String conId) throws SQLException { return getDBDescr(conId).getUpdateStatement(); } private static DBDescr getDBDescr(String conId) { conId = getConnectionId(conId); DBDescr db = (DBDescr)dbDescrs.get(conId); if (db == null) throw new RuntimeException("DBDescr not found, did you forget to call openConnection?"); return db; } private static boolean removeDBDescr(String conId) { conId = getConnectionId(conId); return dbDescrs.remove(conId) != null; } private static String getConnectionId(String conId) { if (conId != null) return conId; if (activeDB.containsKey(Thread.currentThread())) return (String)activeDB.get(Thread.currentThread()); return (String)activeDB.get(null); } // Contains only static methods private Database() { } public static boolean openConnection(String serverName, String serverPort, String dbName, String user, String pw) { return openConnection(null, DEFAULT_DRIVER, serverName, serverPort, dbName, user, pw); } /** * <p> Open a connection to the database. Note that simultaneous * connections to different databases are not supported; if a * connection is already open when this method is called a * connection will be opened to the same database which is already * connected. </p> * * @param serverName Name of server to connect to * @param serverPort Network port on server to connect to * @param dbName Name of database to connect to * @param user Username to use for login to server * @param pw Password to use for login to server * @return true if connection was opened successfully; false otherwise */ public static boolean openConnection(String conId, int dbDriver, String serverName, String serverPort, String dbName, String user, String pw) { boolean ret = false; if (serverName == null) { ret=true; System.err.println("Database.openConnection(): Error, serverName is null"); } if (dbName == null) { ret=true; System.err.println("Database.openConnection(): Error, dbName is null"); } if (user == null) { ret=true; System.err.println("Database.openConnection(): Error, user is null"); } if (pw == null) { ret=true; System.err.println("Database.openConnection(): Error, pw is null"); } if (ret) return false; DBDescr db; synchronized (dbDescrs) { db = (DBDescr)dbDescrs.get(getConnectionId(conId)); if (db == null) { db = new DBDescr(dbDriver, serverName, serverPort, dbName, user, pw); if (conId == null) { conId = db.getKey(); DBDescr db2 = (DBDescr)dbDescrs.get(getConnectionId(conId)); if (db2 != null) db = db2; } } dbDescrs.put(conId, db); } if (!db.openConnection()) { dbDescrs.remove(conId); return false; } activeDB.put(Thread.currentThread(), conId); if (!activeDB.containsKey(null)) activeDB.put(null, conId); return true; } /** * <p> When returnOnReconnectFail is true and the connection to the * database is lost, only a single reconnect is tried. If it fails * control is returned to the calling method with an error. </p> * * If returnOnReconnectFail is false (default) a reconnect will be * tried every few seconds until the connection is restored. </p> * * @param returnOnReconnectFail New value for returnOnReconnectFail */ public static void setReturnOnReconnectFail(String conId, boolean returnOnReconnectFail) { DBDescr db = getDBDescr(conId); db.setReturnOnReconnectFail(returnOnReconnectFail); } /** * <p> Return the number of database connections. Note that this may * not reflect the number of actual connections to the database, as * they may be shared. </p> * * @return the number of database connections */ public static int getConnectionCount() { synchronized (dbDescrs) { int cnt=0; for (Iterator it = dbDescrs.values().iterator(); it.hasNext();) { cnt += ((DBDescr)it.next()).getConnectionCount(); } return cnt; } } public static void closeConnection() { closeConnection(null); } /** * <p> Close the connection to the database. </p> */ public static void closeConnection(String conId) { synchronized (dbDescrs) { DBDescr db = getDBDescr(conId); db.closeConnection(); removeDBDescr(conId); } } public static Object getConnection() throws SQLException { DBDescr dbd = getDBDescr(null); return dbd.getConnection(); } public static void freeConnection(Object o) { DBDescr dbd = getDBDescr(null); dbd.freeConnection((DBDescr.ConnectionDescr)o); } /** * <p> Execute the given query. </p> * * @param statement The SQL query statement to exectute * @return the result of the query */ public static ResultSet query(String statement) throws SQLException { return query(statement, false); } /** * <p> Free the given resultset. </p> * * @param rs The resultset to free */ public static void free(ResultSet rs) throws SQLException { if (statementMap.containsKey(rs)) { Statement st = (Statement)statementMap.remove(rs); st.close();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -