package database; import constants.ServerConstants; import tools.FileoutputUtil; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class DatabaseConnection { private static final HashMap<Integer, ConWrapper> connections = new HashMap(); public static final int CLOSE_CURRENT_RESULT = 1; public static final int KEEP_CURRENT_RESULT = 2; public static final int CLOSE_ALL_RESULTS = 3; public static final int SUCCESS_NO_INFO = -2; public static final int EXECUTE_FAILED = -3; public static final int RETURN_GENERATED_KEYS = 1; public static final int NO_GENERATED_KEYS = 2; static { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { FileoutputUtil.log("[数据库信息] 找不到JDBC驱动."); System.exit(0); } } public static Connection getConnection() { Thread cThread = Thread.currentThread(); int threadID = (int) cThread.getId(); ConWrapper ret = (ConWrapper) connections.get(Integer.valueOf(threadID)); if (ret == null) { Connection retCon = connectToDB(); ret = new ConWrapper(retCon); ret.id = threadID; connections.put(threadID, ret); } return ret.getConnection(); } private static long getWaitTimeout(Connection con) { Statement stmt = null; ResultSet rs = null; try { stmt = con.createStatement(); rs = stmt.executeQuery("SHOW VARIABLES LIKE 'wait_timeout'"); long l1; if (rs.next()) { return Math.max(1000, rs.getInt(2) * 1000 - 1000); } return -1L; } catch (SQLException ex) { long l2 = -1L; return l2; } finally { if (stmt != null) { try { stmt.close(); } catch (SQLException ex1) { } finally { if (rs != null) { try { rs.close(); } catch (SQLException ex1) { } } } } } } private static Connection connectToDB() { try { Connection con = DriverManager.getConnection( "jdbc:mysql://" + ServerConstants.SQL_IP + ":" + ServerConstants.SQL_PORT + "/" + ServerConstants.SQL_DATABASE + "?autoReconnect=true&characterEncoding=GBK", ServerConstants.SQL_USER, ServerConstants.SQL_PASSWORD); long timeout = getWaitTimeout(con); if (timeout == -1L) { FileoutputUtil.log("[数据库信息] 无法读取超时时间, using " + ServerConstants.SQL_TIMEOUT + " instead."); } else { ServerConstants.SQL_TIMEOUT = timeout; FileoutputUtil.log("[数据库信息] 连接超时时间为: " + (ServerConstants.SQL_TIMEOUT / 1000 / 60) + " 分钟."); } return con; } catch (SQLException e) { throw new DatabaseException("[数据库信息] 连接到数据库错误,请检查MYSQL数据库是否开启,账号密码数据库名是否正确", e); } } public static void closeAll() throws SQLException { for (ConWrapper con : connections.values()) { con.connection.close(); } connections.clear(); } public static void closeConnection() throws SQLException { Iterator<Map.Entry<Integer, ConWrapper>> con = connections.entrySet().iterator(); Map<Integer, ConWrapper> toclose = new HashMap(); while (con.hasNext()) { Map.Entry<Integer, ConWrapper> temp = con.next(); if (temp.getValue().expiredConnection()) { toclose.put(temp.getKey(), temp.getValue()); FileoutputUtil.log("过时连接已经被清理..."); } } for (Map.Entry<Integer, ConWrapper> t : toclose.entrySet()) { t.getValue().connection.close(); connections.remove(t.getKey()); } } public static class ConWrapper { private long lastAccessTime = 0L; private Connection connection; private int id; public ConWrapper(Connection con) { this.connection = con; } public Connection getConnection() { if (expiredConnection()) { try { this.connection.close(); } catch (SQLException err) { } connection = connectToDB(); } this.lastAccessTime = System.currentTimeMillis(); return this.connection; } public boolean expiredConnection() { if (this.lastAccessTime == 0L) { return false; } try { return (System.currentTimeMillis() - this.lastAccessTime >= ServerConstants.SQL_TIMEOUT) || (this.connection.isClosed()); } catch (SQLException ex) { } return true; } } }