1. 程式人生 > >springboot-cache3自定義快取載入資料庫屬性配置

springboot-cache3自定義快取載入資料庫屬性配置

需求:

由於專案中配置項太多,配置檔案維護很不方便,將配置項放在資料庫中維護,通過專案啟動時將資料庫配置載入到環境變數中,其他需要使用的業務直接使用引用的方式是@Value("${欄位}")

專案結構:


pom.xml引入依賴包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
> <modelVersion>4.0.0</modelVersion> <groupId>com.example.springboot</groupId> <artifactId>springboot-cache3</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springboot-cache3</name
> <description>Demo project for Spring Boot</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version
>1.8</java.version> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.12.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- 引入mybatis 資料庫操作包 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- 引入mybatis 分頁外掛 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>4.1.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

配置日誌記錄

log4j.rootLogger=INFO, stdout , R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=${catalina.home}/logs/platform.log
log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L %m%n
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.MaxFileSize=51200KB
log4j.appender.R.MaxBackupIndex=10000
log4j.logger.org.springframework=ERROR
log4j.logger.org.quartz=INFO
#輸出列印SQL語句,其中需要填寫dao所在的包路徑,不能使用模糊匹配
log4j.logger.com.example.spring=DEBUG

配置資料庫連線

#server.port=8090
#標示使用的是mysql/oracle/sqlserver
datasource.type=mysql
#mysql資料連線
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
#spring.datasource.max-active=20
#spring.datasource.max-idle=8
#spring.datasource.min-idle=8
#spring.datasource.initial-size=20
#mybatis 配置
# 配置對映檔案載入
mybatis.mapper-locations=classpath*:mapper/*.xml
# 實體類通過別名使用
#mybatis.type-aliases-package=

表結構:

-- ----------------------------
-- Table structure for `test_tb_propertiesconf`
-- ----------------------------
DROP TABLE IF EXISTS `test_tb_propertiesconf`;
CREATE TABLE `test_tb_propertiesconf` (
  `ConfKey` varchar(50) NOT NULL,
  `Remark` varchar(200) DEFAULT NULL,
  `ConfValue` varchar(50) NOT NULL,
  PRIMARY KEY (`ConfKey`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of test_tb_propertiesconf
-- ----------------------------

建立初始化資料庫配置類

package com.example.springboot.cache3.config;

import com.example.springboot.cache3.dao.PropertiesMapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;

/**
 * @Description: 動態載入資料庫中的配置
 * 然後根據資料庫中的配置欄位資訊同步到上下文中讓其它xml或者類引用,
 * 引用方式是xml通過${欄位},類引用的方式是@Value("${欄位}")
 */
@Configuration
//order 控制初始化載入配置順序,值越小載入越優先
@Order(value = 2)
public class PropertiesConfig {

   private static final Log log = LogFactory.getLog(PropertiesConfig.class);

   // 宣告一個物件用於儲存資料庫中的配置欄位資訊
private Properties properties = new Properties();
   // 上下文環境資訊
@Autowired
private ConfigurableEnvironment env;
   // 呼叫查詢資料庫的dao
@Autowired
private PropertiesMapper propertiesMapper;

   // 查詢配置檔案表的SQL語句
private String query = "select ConfKey,ConfValue,Remark from WFBDCMain.dbo.ISIP_tb_PropertiesConf WITH (NOLOCK) where CurFlag > 0";

   /**
    * 呼叫並初始化資料庫中的配置欄位到全域性物件中
    */
@PostConstruct
private void initProperties() {
      log.info("資料庫表配置-->讀取資料表配置服務:開始!");
      long startTime = System.nanoTime();
      MutablePropertySources propertySources = env.getPropertySources();
      try {
         List<Map<String, Object>> propertyMap = propertiesMapper.queryPropertiesConfg();
         // 列印讀取的資料表配置資料
log.debug(propertyMap.toString());
         // 遍歷所有資料表中的資料,然後把資料新增到properties配置欄位中
for (Map<String, Object> tmp : propertyMap) {
            // 把資料表中的key和value新增到環境中
properties.put(tmp.get("ConfKey").toString(), tmp.get("ConfValue"));
         }
         PropertiesPropertySource dbPropertySource = new PropertiesPropertySource("dbPropertySource", properties);
         // 定義一個正則判斷環境變數中是否存在相關的配置
Pattern p = Pattern.compile("^applicationConfig.*");
         String name = null;
         boolean flag = false;
         for (PropertySource<?> source : propertySources) {
            if (p.matcher(source.getName()).matches()) {
               name = source.getName();
               // 表示環境中存在該環境的配置,可以退出
flag = true;
               break;
            }
         }
         if (flag) {
            propertySources.addBefore(name, dbPropertySource);
         } else {
            propertySources.addFirst(dbPropertySource);
         }
         long endTime = System.nanoTime();
         // 計算載入配置檔案的耗時
double useTime = (endTime - startTime) / 1E9;
         log.info("資料庫表配置-->讀取資料表配置服務:結束,載入耗時:" + useTime + "秒!");
         String key = env.getProperty("init_delay").toString();
         log.info("資料庫表配置-->" + key);
      } catch (Exception e) {
         // 錯誤資訊列印
log.error("資料庫表配置-->讀取資料表配置服務異常: " + e);
      }
   }
}
建立mapper介面
package com.example.springboot.cache3.dao;

import org.apache.ibatis.annotations.Mapper;

import java.util.List;
import java.util.Map;

/**
 * @desc 載入資料庫屬性配置
 * @Author wangsh
 * @date 2018/5/7 21:34
 * @return
*/
@Mapper
public interface PropertiesMapper {

   public List<Map<String, Object>> queryPropertiesConfg();
}

建立mapper配置檔案

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPEmapperPUBLIC"-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.springboot.cache3.dao.PropertiesMapper">
    <!-- 查詢資料配置 -->
<select id="queryPropertiesConfg" resultType="java.util.Map">
       select ConfKey,ConfValue,Remark from test.test_tb_PropertiesConf  where CurFlag > 0
    </select>

</mapper>

建立controller類

package com.example.springboot.cache3.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * @desc 測試讀取資料庫快取配置
 * @Author wangsh
 * @date 2018/5/7 20:57
 */
@RestController
@RequestMapping("/cache")
public class CacheController {

   @Value("${init_delay}")
   private String init_delay;

   @ResponseBody
   @RequestMapping("/hello")
   public String hello() {

      System.out.println(">>>>>測試讀取資料庫快取配置........" + init_delay);
      return init_delay;
   }
}
建立啟動服務類
package com.example.springboot.cache3;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@MapperScan("com.example.springboot.cache3")
@SpringBootApplication
public class SpringbootCache3Application {

   public static void main(String[] args) {
      SpringApplication.run(SpringbootCache3Application.class, args);
   }
}

啟動服務測試如下

瀏覽器訪問: http://localhost:8080/cache/hello


日誌記錄: