1. 程式人生 > >java配置多資料來源多連線池的工具類,這裡是mysql和mongoDB

java配置多資料來源多連線池的工具類,這裡是mysql和mongoDB

public class DBManager {
	
	private static final String PREFIX="jdbc:apache:commons:dbcp:"; 
	private static Log log =LogFactory.getLog(DBManager.class);
	
	private static Map<String,Mongo> mongoMap;   //已經初始化的mongoDB的map資訊
	//已經初始化的mongoDB中 db名稱資訊 key:mongodb.id  value:mongodb.dbname
	private static Map<String,String> mongoDbMap;   
	private static Set<String> dbNames;                   //已經初始化資料庫伺服器標識
	
	private static DBManager instance;
	
	//執行緒變數儲存連線
	protected static ThreadLocal<Connection> threadConnection=new ThreadLocal<Connection>();
	
	
	/**
	 * 返回DBManager例項
	 * @return
	 * @throws Exception
	 */
	public static DBManager getInstance() throws Exception{
		if(instance==null){
			instance=new DBManager();
		}
		return instance;
	}
	
	private DBManager() throws Exception{
		initDB();
	}
	
	/**
	 * 返回所有初始化的資料庫伺服器標識
	 * @return 伺服器標識陣列
	 */
	public  String[] getDBNames(){
		String[] dbs=(String[]) dbNames.toArray();
		String[] clones=Arrays.copyOf(dbs, dbs.length);
		return clones;
	}
	
	/**
	 * 獲取資料庫連線
	 * @param dbKey 資料庫連線池標識
	 * @return  資料庫連線
	 * @throws SQLException 
	 */
	public  Connection getConnection(String dbKey) throws SQLException{
		Connection conn=threadConnection.get();
		if(conn==null||conn.isClosed()){
			//如果連線不存在建立連線放入執行緒變數中
			conn=DriverManager.getConnection(PREFIX+dbKey);
			threadConnection.set(conn);
		}
		return conn;
	}
	
	/**
	 * 獲取資料庫連線
	 * @param dbKey	資料庫連線池標識
	 * @param autoCommit 是否自動提交  true是  false否
	 * @return 資料庫連線
	 * @throws SQLException 
	 */
	public  Connection getConnection(String dbKey,boolean autoCommit) throws SQLException{
		Connection conn=getConnection(dbKey);
		conn.setAutoCommit(autoCommit);
		return conn;
	}
	
	/**
	 * 初始化資料庫連線池
	 * @throws Exception 初始化失敗
	 */
	public  void initDB() throws Exception{
		mongoMap=new HashMap<String,Mongo>();
		mongoDbMap=new HashMap<String,String>();
		dbNames=new HashSet<String>();
		setupPool();
		setupMongoDB();
	}
	
	/**
	 * 初始化資料庫連線池
	 * 關係型資料庫 使用DBCP建立
	 * @throws IOException 
	 * @throws FileNotFoundException 
	 */
	private void setupPool() throws Exception{
		String filePath=this.getClass().getClassLoader().getResource("").getFile();
		File f=new File(filePath+"conf/db");
		File[] files=f.listFiles(new FilenameFilter(){
			//過濾關係型資料庫的配置檔案
			public boolean accept(File dir, String name) {
				return name.matches("^db\\w*fu\\w*.properties$"); //是關係型資料庫的配置檔案
			}
		});		
		for(int i=0;i<files.length;i++){
			
			log.debug("db configure file path"+(i+1)+":"+files[i].getAbsolutePath());
			Properties p=new Properties();
			p.load(new FileInputStream(files[i]));

			String driverClassName=p.getProperty("jdbc.driverClassName");
			String dbId=p.getProperty("jdbc.id");
			if(driverClassName==null||dbId==null)
				throw new Exception("db pool setup error!");
			Class.forName(p.getProperty("jdbc.driverClassName")); //載入驅動類
			
			//建立關係型資料庫連線池
			String connectURI=p.getProperty("jdbc.url");
			
			//連線池相關設定
			GenericObjectPool connectionPool=new GenericObjectPool(null,
					Integer.parseInt(p.getProperty("dbcp.maxActive")),
					GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
					Long.parseLong(p.getProperty("dbcp.maxWait")),
					Integer.parseInt(p.getProperty("dbcp.maxIdle")),
					Integer.parseInt(p.getProperty("dbcp.minIdle")),
					Boolean.parseBoolean(p.getProperty("dbcp.testOnBorrow")),
					GenericObjectPool.DEFAULT_TEST_ON_RETURN,
					Long.parseLong(p.getProperty("dbcp.timeBetweenEvictionRunsMillis")),
					GenericObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
					Long.parseLong(p.getProperty("dbcp.minEvictableIdleTimeMillis")),
					Boolean.parseBoolean(p.getProperty("dbcp.testWhileIdle"))
					);
			ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(connectURI,p.getProperty("jdbc.username"),p.getProperty("jdbc.password"));
			PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,connectionPool,null,null,false,true);
			poolableConnectionFactory.setValidationQuery(p.getProperty("validationQuery"));
			
	        Class.forName("org.apache.commons.dbcp.PoolingDriver");
	        PoolingDriver driver = (PoolingDriver) DriverManager.getDriver(PREFIX);

	        driver.registerPool(dbId,connectionPool);
	        dbNames.add(dbId);   //加入已經初始化的關係型資料庫伺服器標識中
		}
	}
	
	/**
	 * 日誌輸出連線池狀態
	 * 使用log info級別輸出
	 * @param dbKey 資料庫伺服器標識
	 */
	public  void showConnectionPoolStatus(String dbKey){
        PoolingDriver driver;
		try {
			driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
	        ObjectPool connectionPool = driver.getConnectionPool(dbKey);
	        log.info("NumActive: "+connectionPool.getNumActive()+"| NumIdle: "+connectionPool.getNumIdle());
		} catch (SQLException e) {
			log.error("connection pool error:",e);
		}
	}
	
	/**
	 * 非關係型使用mongoDB
	 * 簡歷mongoDB連線池
	 * @throws Exception 
	 */
	private  void setupMongoDB() throws Exception{
		String filePath=this.getClass().getClassLoader().getResource("").getFile();
		File f=new File(filePath+"conf/db");
		File[] files=f.listFiles(new FilenameFilter(){
			//過濾Mongodb的配置檔案
			public boolean accept(File dir, String name) {
				return name.matches("^mongodb\\w*fu.properties$"); //是mongodb 的配置檔案
			}
		});
		for(int i=0;i<files.length;i++){
			log.debug("mongodb configure file path"+(i+1)+":"+files[i].getAbsolutePath());
			Properties p=new Properties();
			p.load(new FileInputStream(files[i]));
			String ip=p.getProperty("mongodb.ip");
			String port=p.getProperty("mongodb.port");
			String username=p.getProperty("mongodb.username");
			String password=p.getProperty("mongodb.password");
			String dbId=p.getProperty("mongodb.id");
			String dbName=p.getProperty("mongodb.dbname");
			Mongo mongo=new Mongo(ip,Integer.parseInt(port));
			boolean auth=mongo.getDB(dbName).authenticate(username, password.toCharArray());
			if(!auth){
				throw new Exception("unauthorized");
			}
			else{
				mongoMap.put(dbId, mongo);
				mongoDbMap.put(dbId, dbName);
			}
		}
	}
	
	/**
	 * 獲取mongoDb DB物件
	 * @param mongoId mongodb伺服器的id標誌
	 * @param dbName  db名稱
	 * @return DB物件
	 */
	public  DB getMongoDB(String mongoId,String dbName){
		Mongo mongdo=mongoMap.get(mongoId);
		mongdo.setWriteConcern(WriteConcern.SAFE);
		if(mongdo!=null)
			return mongdo.getDB(dbName);
		else
			return null;
	}
	/**
	 * 獲取mongoDb DB物件
	 * @param dbName  db名稱
	 * @return DB物件
	 */
	public  DB getMongoDB(String dbName){
		Mongo mongdo=mongoMap.get(SystemVar.DEFAULT_MONGO_DB_KEY);
		mongdo.setWriteConcern(WriteConcern.SAFE);
		if(mongdo!=null)
			return mongdo.getDB(dbName);
		else
			return null;
	}
	
	
	/**
	 * 獲取mongo db資料庫預設資料庫名稱 
	 * @param dbKey mongodb.id
	 * @return mongodb.dbname
	 */
	public String getMongoDefaultDbName(String dbKey){
		return mongoDbMap.get(dbKey);
	}

}