閑話少說,直接列舉問題: ①AB兩台資料庫伺服器做集群,由於兩台伺服器配置不一樣,如何在代碼中要實現每訪問伺服器A的資料庫2次,才能訪問伺服器B的資料庫1次。 ②AB兩台資料庫伺服器做讀寫分離,如何在代碼中控制,查詢數據使用伺服器A的資料庫連接,增刪改使用伺服器B的資料庫連接。 代碼結構: 代碼實現 ...
閑話少說,直接列舉問題:
①AB兩台資料庫伺服器做集群,由於兩台伺服器配置不一樣,如何在代碼中要實現每訪問伺服器A的資料庫2次,才能訪問伺服器B的資料庫1次。
②AB兩台資料庫伺服器做讀寫分離,如何在代碼中控制,查詢數據使用伺服器A的資料庫連接,增刪改使用伺服器B的資料庫連接。
代碼結構:
代碼實現:
①資料庫連接信息預設值
package com.keji10.core.jdbc.properties; /** * 類描述: 資料庫連接信息預設值 * * @since 1.5 * @version 1.0 * @author xuanly * */ public interface JdbcPropertiesContants { /** * jdbc.maxActive最大活躍數(預設值) */ public static final int JDBC_MAXACTIVE_DEFAULT = 20; /** * jdbc.maxIdle最大連接數(預設值) */ public static final int JDBC_MAXIDLE_DEFAULT = 20; /** * jdbc.maxWait預設等待時間(預設值) */ public static final int JDBC_MAXWAIT_DEFAULT = 10000; /** * jdbc.weight預設資料庫連接池權重(預設值) */ public static final int JDBC_WEIGHT_DEFAULT = 1; }
package com.keji10.core.jdbc.properties; /** * 類描述: 資料庫配置文件實體類 * * @since 1.5 * @version 1.0 * @author xuanly * */ public class JdbcPropertiesBean implements JdbcPropertiesContants { private String jdbcDriver; private String jdbcUrl; private String jdbcUserName; private String jdbcPassword; private int jdbcMaxactive; private int jdbcMaxidle; private int jdbcMaxwait; private int jdbcWeight; public String getJdbcDriver() { return jdbcDriver; } public void setJdbcDriver(String jdbcDriver) { this.jdbcDriver = jdbcDriver; } public String getJdbcUrl() { return jdbcUrl; } public void setJdbcUrl(String jdbcUrl) { this.jdbcUrl = jdbcUrl; } public String getJdbcUserName() { return jdbcUserName; } public void setJdbcUserName(String jdbcUserName) { this.jdbcUserName = jdbcUserName; } public String getJdbcPassword() { return jdbcPassword; } public void setJdbcPassword(String jdbcPassword) { this.jdbcPassword = jdbcPassword; } public int getJdbcWeight() { if (jdbcWeight == 0) { // 返回預設值 return JDBC_WEIGHT_DEFAULT; } return jdbcWeight; } public void setJdbcWeight(int jdbcWeight) { this.jdbcWeight = jdbcWeight; } public int getJdbcMaxactive() { if (jdbcMaxactive == 0) { // 返回預設值 return JDBC_MAXACTIVE_DEFAULT; } return jdbcMaxactive; } public void setJdbcMaxactive(int jdbcMaxactive) { this.jdbcMaxactive = jdbcMaxactive; } public int getJdbcMaxidle() { if (jdbcMaxidle == 0) { // 返回預設值 return JDBC_MAXIDLE_DEFAULT; } return jdbcMaxidle; } public void setJdbcMaxidle(int jdbcMaxidle) { this.jdbcMaxidle = jdbcMaxidle; } public int getJdbcMaxwait() { if (jdbcMaxwait == 0) { // 返回預設值 return JDBC_MAXWAIT_DEFAULT; } return jdbcMaxwait; } public void setJdbcMaxwait(int jdbcMaxwait) { this.jdbcMaxwait = jdbcMaxwait; } public String toString() { StringBuffer s = new StringBuffer(); s.append("jdbcDriver =" + jdbcDriver); s.append("jdbcUrl =" + jdbcUrl); s.append("jdbcUserName =" + jdbcUserName); s.append("jdbcPassword =" + jdbcPassword); s.append("jdbcMaxactive =" + jdbcMaxactive); s.append("jdbcMaxidle =" + jdbcMaxidle); s.append("jdbcMaxwait =" + jdbcMaxwait); s.append("jdbcWeight =" + jdbcWeight); return s.toString(); } }
③資料庫配置文件信息獲取
package com.keji10.core.jdbc.properties; import java.util.ResourceBundle; import org.apache.log4j.Logger; import com.keji10.core.exception.DBException; /** * 類描述: 資料庫配置文件信息獲取 * * @since 1.5 * @version 1.0 * @author xuanly * */ public class JdbcPropertiesManager { private Logger logger = Logger.getLogger(JdbcPropertiesManager.class.getName()); // 單例模式Begin private static JdbcPropertiesManager instance = new JdbcPropertiesManager(); private JdbcPropertiesManager() { } public static JdbcPropertiesManager getInstance() { return instance; } // 單例模式End private JdbcPropertiesBean jdbcPropertiesBean; /** * 獲取jdbc.propertiesBean配置文件 * * @return JdbcPropertiesBean * @throws DBException */ public JdbcPropertiesBean getJdbcPropertiesBean() throws DBException { return getJdbcPropertiesBean("jdbc"); } public JdbcPropertiesBean getJdbcPropertiesBean(String propertieFile) throws DBException { ResourceBundle rb = ResourceBundle.getBundle(propertieFile); jdbcPropertiesBean = new JdbcPropertiesBean(); try { jdbcPropertiesBean.setJdbcDriver(rb.getString("jdbc.driver")); jdbcPropertiesBean.setJdbcUrl(rb.getString("jdbc.url")); jdbcPropertiesBean.setJdbcUserName(rb.getString("jdbc.username")); jdbcPropertiesBean.setJdbcPassword(rb.getString("jdbc.password")); } catch (Exception e) { logger.warn("獲取資料庫連接配置文件【jdbc.driver】失敗,執行無法啟動!"); logger.warn("獲取資料庫連接配置文件【jdbc.url】失敗,執行無法啟動!"); logger.warn("獲取資料庫連接配置文件【jdbc.username】失敗,執行無法啟動!"); logger.warn("獲取資料庫連接配置文件【jdbc.password】失敗,執行無法啟動!"); logger.error(e); throw new DBException(e); } try { jdbcPropertiesBean.setJdbcMaxactive(Integer.valueOf(rb.getString("jdbc.maxActive"))); jdbcPropertiesBean.setJdbcMaxidle(Integer.valueOf(rb.getString("jdbc.maxIdle"))); jdbcPropertiesBean.setJdbcMaxwait(Integer.valueOf(rb.getString("jdbc.maxWait"))); jdbcPropertiesBean.setJdbcWeight(Integer.valueOf(rb.getString("jdbc.weight"))); } catch (Exception e) { logger.warn("獲取資料庫連接配置文件【jdbc.maxActive】失敗,系統將執行預設配置"); logger.warn("獲取資料庫連接配置文件【jdbc.maxIdle】失敗,系統將執行預設配置"); logger.warn("獲取資料庫連接配置文件【jdbc.maxWait】失敗,系統將執行預設配置"); logger.warn("獲取資料庫連接配置文件【jdbc.weight】失敗,系統將執行預設配置"); } return jdbcPropertiesBean; } }
④資料庫連接池管理
package com.keji10.core.jdbc.dataSource; import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; import org.apache.log4j.Logger; import com.keji10.core.commons.ConfigBean; import com.keji10.core.exception.DBException; import com.keji10.core.jdbc.properties.JdbcPropertiesBean; import com.keji10.core.jdbc.properties.JdbcPropertiesManager; /** * 類描述:資料庫連接池管理 * * @since 1.5 * @version 1.0 * @author chenairu * */ public class DBDataSource { private Logger logger = Logger.getLogger(DBDataSource.class.getName()); // 單例模式begin private static DBDataSource instance = new DBDataSource(); private DBDataSource() { } public static DBDataSource getInstance() { return instance; } // 單例模式end // 非主資料庫連接池集群池 private Map<String, DataSource> otherDataSourceMap = new HashMap<String, DataSource>(); // 主資料庫連接池集群池 private Map<Integer, DataSource> mainDataSourceMap = new HashMap<Integer, DataSource>(); // 記錄資料庫負載均衡的配置 private Map<Integer, Integer> mainDataSourceWeightMap = new HashMap<Integer, Integer>(); // 記錄獲取資料庫連接的指針 private int mainDataSourceWeightIndex = 0; /** * 獲取連接池 * * @param bean * @return * @throws DBException */ public DataSource getDataSource(JdbcPropertiesBean bean) throws DBException { if (bean == null) { return getDataSource(); } if (bean.getJdbcDriver() == null || bean.getJdbcUrl() == null || bean.getJdbcUserName() == null || bean.getJdbcPassword() == null) { logger.error("********資料庫配置信息不完整!!!*********"); logger.error("*********載入預設資料庫配置!!!*********"); return getDataSource(); } DataSource dataSource = (DataSource) otherDataSourceMap.get(bean.toString()); if (dataSource != null) { return dataSource; } logger.info("*********載入資料庫配置***********************"); logger.info("JdbcDriver =" + bean.getJdbcDriver()); logger.info("JdbcUrl =" + bean.getJdbcUrl()); logger.info("JdbcUserName =" + bean.getJdbcUserName()); logger.info("JdbcPassword =" + bean.getJdbcPassword()); logger.info("JdbcMaxactive=" + bean.getJdbcMaxactive()); logger.info("JdbcMaxidle =" + bean.getJdbcMaxidle()); logger.info("JdbcMaxwait =" + bean.getJdbcMaxwait()); BasicDataSource basicDataSource = new BasicDataSource(); basicDataSource.setDriverClassName(bean.getJdbcDriver()); basicDataSource.setUrl(bean.getJdbcUrl()); basicDataSource.setUsername(bean.getJdbcUserName()); basicDataSource.setPassword(bean.getJdbcPassword()); basicDataSource.setMaxActive(bean.getJdbcMaxactive()); basicDataSource.setMaxIdle(bean.getJdbcMaxidle()); basicDataSource.setMaxWait(bean.getJdbcMaxwait()); dataSource = basicDataSource; logger.info("*********載入資料庫配置完成************************"); otherDataSourceMap.put(bean.toString(), dataSource); return dataSource; } /** * 獲取連接池 * * @return 連接池 * @throws DBException */ public DataSource getDataSource() throws DBException { String jdbcFileName; JdbcPropertiesBean bean; DataSource dataSource; String jdbcs = ConfigBean.getInstance().getJdbcs(); if (mainDataSourceMap.isEmpty()) { for (int i = 0; i < jdbcs.split(",").length; i++) { jdbcFileName = jdbcs.split(",")[i]; bean = JdbcPropertiesManager.getInstance().getJdbcPropertiesBean(jdbcFileName); logger.info("*********載入資料庫配置***********************"); logger.info("JdbcDriver =" + bean.getJdbcDriver()); logger.info("JdbcUrl =" + bean.getJdbcUrl()); logger.info("JdbcUserName =" + bean.getJdbcUserName()); logger.info("JdbcPassword =" + bean.getJdbcPassword()); logger.info("JdbcMaxactive=" + bean.getJdbcMaxactive()); logger.info("JdbcMaxidle =" + bean.getJdbcMaxidle()); logger.info("JdbcMaxwait =" + bean.getJdbcMaxwait()); logger.info("JdbcWeight =" + bean.getJdbcWeight()); BasicDataSource basicDataSource = new BasicDataSource(); basicDataSource.setDriverClassName(bean.getJdbcDriver()); basicDataSource.setUrl(bean.getJdbcUrl()); basicDataSource.setUsername(bean.getJdbcUserName()); basicDataSource.setPassword(bean.getJdbcPassword()); basicDataSource.setMaxActive(bean.getJdbcMaxactive()); basicDataSource.setMaxIdle(bean.getJdbcMaxidle()); basicDataSource.setMaxWait(bean.getJdbcMaxwait()); dataSource = basicDataSource; //負載設置關鍵代碼---begin mainDataSourceMap.put(i, dataSource); for (int j = 0; j < bean.getJdbcWeight(); j++) { mainDataSourceWeightMap.put(mainDataSourceWeightMap.size() + 1, i); } //負載設置關鍵代碼---end logger.info("*********載入資料庫配置完成************************"); } } int mainDataSourceNowIndex; try { mainDataSourceNowIndex = mainDataSourceWeightMap.get(mainDataSourceWeightIndex % (mainDataSourceWeightMap.size())); mainDataSourceWeightIndex++; if (mainDataSourceWeightIndex >= mainDataSourceWeightMap.size()) { mainDataSourceWeightIndex = 0; } } catch (Exception e) { mainDataSourceNowIndex = 0; } return (DataSource) mainDataSourceMap.get(mainDataSourceNowIndex); } /** * 清空資料庫連接池 */ public void clear() { otherDataSourceMap.clear(); mainDataSourceMap.clear(); mainDataSourceWeightMap.clear(); mainDataSourceWeightIndex = 0; } }
⑤資料庫連接實現
package com.keji10.core.jdbc.dataSource; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import org.apache.log4j.Logger; import com.keji10.core.exception.DBException; import com.keji10.core.jdbc.properties.JdbcPropertiesBean; /** * 類描述:資料庫連接實現 * * @since 1.5 * @version 1.0 * @author xuanly * */ public class DBConnection { private Logger logger = Logger.getLogger(DBConnection.class.getName()); // 單例模式begin private static DBConnection instance = new DBConnection(); private DBConnection() { } public static DBConnection getInstance() { return instance; } // 單例模式end /** * 獲取預設資料庫連接 * * @return 資料庫連接 * @throws DBException */ public Connection getConnection() throws DBException { try { return DBDataSource.getInstance().getDataSource().getConnection(); } catch (SQLException e) { logger.error(e); throw new DBException(e); } } /** * 根據配置文件獲取自定義資料庫連接 * * @param JdbcPropertiesBean * @return * @throws DBException */ public Connection getConnection(JdbcPropertiesBean JdbcPropertiesBean) throws DBException { DataSource dataSource = DBDataSource.getInstance().getDataSource(JdbcPropertiesBean); try { return dataSource.getConnection(); } catch (SQLException e) { logger.error(e); throw new DBException(e); } } /** * 關閉資料庫連接 * * @throws DBException */ public void close(Connection connection) throws DBException { try { if (connection == null) { return; } if (connection.isClosed()) { return; } if (connection != null) { connection.close(); connection = null; } } catch (SQLException e) { logger.error(e); throw new DBException(e); } finally { connection = null; } } /** * 清空資料庫連接池 */ public void clear() { DBDataSource.getInstance().clear(); } }
封裝框架最核心的部分,莫過於資料庫連接的封裝。資料庫連接就像一條管道,一端連著資料庫,一端連接java程式。
如果一個框架,能夠像資料庫連接一樣,一端連著資料庫,一端連著用戶的界面,中間無需編輯java代碼,即可完成項目開發。
那這套框架的思路將會為以後的開發,開闢一個新模式。
計劃安排,下一編先把對象映射完成,再寫資料庫查詢的封裝。