Skip to content

Instantly share code, notes, and snippets.

@frankies
Created July 3, 2017 03:59
Show Gist options
  • Save frankies/62b2fcc0719e8bc877588928fc43cf71 to your computer and use it in GitHub Desktop.
Save frankies/62b2fcc0719e8bc877588928fc43cf71 to your computer and use it in GitHub Desktop.
问题

问题点

DbStatusHelper.java

  • 是否需要继承 DefCollectionHelperSupport 类?

    我的想法: 这个类在G1是用于用户界面的下拉框数据集合获取的

  • 注入 ServletContext 这个对象?

    我的想法: 应该是不对,因为它只有是Web应用时,这个对象才会的。如果它不是Web应用时,这个DbStatusHelper 不就失效了。

    建议改成: 实现 ApplicationContextAwar接口

      public class DbStatusHelper  implements ApplicationContextAware {
    
        private ApplicationContext applicationContext;
    
        ...
    
              void setApplicationContext(ApplicationContext applicationContext) {
                     this.applicationContext = applicationContext
              }
    
       ... 
     } 
  • apCheckSql这个属性是从外部注入,代码怎么没有使用它?

  • getDbDao 这个方法里 final JdbcSupportDaoImpl dao = new JdbcSupportDaoImpl();,性能问题大。

    想一下,这个DBCheck方法一般是间隔1分钟左右被调用,多个数据源的情况下,内存开销确实有点大,性能问题。

    建议改成: 不要使用 JdbcSupportDaoImpl 这个类,而是直接把它里面调用的代码拿出来,参考:org.apache.commons.dbutils.QueryRunner.query(Connection, String, Object[], ResultSetHandler)

       public Object query(Connection conn, String sql, Object[] params,
              ResultSetHandler rsh) throws SQLException {
    
          PreparedStatement stmt = null;
          ResultSet rs = null;
          Object result = null;
    
          try {
              stmt = this.prepareStatement(conn, sql);
              this.fillStatement(stmt, params);
              rs = this.wrap(stmt.executeQuery());
              result = rsh.handle(rs);
    
          } catch (SQLException e) {
              this.rethrow(e, sql, params);
    
          } finally {
              try {
                  close(rs);
              } finally {
                  close(stmt);
              }
          }
    
          return result;
      }
  • 针对多种数据库的检测语句的对应

    目录代码只定义了 OracleDB2INFORMIX, 其它都走默认的select 1, 将来还有其它数据库怎么办?

    我的想法:

    • 定义一个接口
      public interface DatabaseDetectSQLDefine {
    
          String getDriverName();
          String getDetectSql();
      }
    • 如果有新增数据库且与现有的语句不同,则自定义实现类并把它暴露成Spring bean:
    @Component
    public class XXDetectSQLDefine implements DatabaseDetectSQLDefine  {
    
      public String getDriverName() {
          return "XX";
      }
    
       public String getDetectSql() {
          return "select 1 from dualx";
      }
    
    }
    • 修改 DbStatusHelper
     
    @Component("DbStatusHelper")
     public class DbStatusHelper implements ApplicationContextAware, InitializingBean{
      ...
    
         private final static Map<String, String> KNOWN_DB_DETECT_SQL = new HashMap<>();
         
    
             /* (non-Javadoc)
         * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
         */
         @Override
         public void setApplicationContext(ApplicationContext applicationContext)
             throws BeansException {
             this.applicationContext = applicationContext;
         }
         
         /* (non-Javadoc)
         * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
         */
         @Override
         public void afterPropertiesSet() throws Exception {
                 KNOWN_DB_DETECT_SQL.put(ORACLE_DRIVER, ORACLE_QUERY);
                 KNOWN_DB_DETECT_SQL.put(INFORMIX_DRIVER, INFORMIX_QUERY);
                 KNOWN_DB_DETECT_SQL.put(DB2_DRIVER, DB2_QUERY); 
    
                 //Search from spring container.
                 Map<String, DatabaseDetectSQLDefine> found = this.applicationContext.getBeansOfType(DatabaseDetectSQLDefine.class);
                 for (DatabaseDetectSQLDefine item : found.values()) {
                     KNOWN_DB_DETECT_SQL.put(item.getDriverName(), item.getDetectSql);
                 }
         }
    
    
         /**
         * @param ds
         * @return
         */
         private String checkStatus(DataSource ds) {
             Boolean exceptionFlg = false;
             
             try{
                 String driverName = ds.getConnection().getMetaData().getDriverName();
                 
                 //Use different sql to check connection, depends on datasource type 
                 // if(StringUtils.contains(StringUtils.lowerCase(driverName), ORACLE_DRIVER)){
                 // 	Object[] ret = getDbDao(ds).getRecord(ORACLE_QUERY);
                 // }else if(StringUtils.contains(StringUtils.lowerCase(driverName), INFORMIX_DRIVER)){
                 // 	Object[] ret = getDbDao(ds).getRecord(INFORMIX_QUERY);
                 // }else if(StringUtils.contains(StringUtils.lowerCase(driverName), DB2_DRIVER)){
                 // 	Object[] ret = getDbDao(ds).getRecord(DB2_QUERY);
                 // }else{
                 // 	Object[] ret = getDbDao(ds).getRecord(DEFAULT_QUERY);
                 // }
                 this.getDetectSql(StringUtils.lowerCase(driverName !=null ? driverName : ""), );
    
             } catch(Exception e) {
                 exceptionFlg = true;
             }
    
             String r_status;
             if(exceptionFlg){
                 r_status = STATUS_STATUS_ERROR;
             } else {
                 r_status = STATUS_STATUS_OK;
             }
             
             return r_status;
         } 
         
         private String getDetectSql(String driverName) {
             
             if(KNOWN_DB_DETECT_SQL.contains(driverName)) {
                 return KNOWN_DB_DETECT_SQL.get(driverName);
             }  
             return DEFAULT_QUERY;
         } 
    
     ...
    
    
    
     }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment