• ff4j spring boot jdbc 基本试用


    官方也提供了spring boot jdbc 的demo,但是文档不是很清晰,在基础上做了修改,方便学习

    环境准备

    • docker-compose 文件
      主要是mysql 数据库的准备, 当然testcontainer也是一个很不错的选择(测试环境使用)
     
    version: "3"
    services:
      mysql:
        image: mysql:5.7.16
        ports:
          - 3306:3306
        command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
        environment:
          MYSQL_ROOT_PASSWORD: dalongrong
          MYSQL_DATABASE: ff4j_v1
          TZ: Asia/Shanghai

    代码使用

    • 简单说明
      默认官方的需要包含数据,但是为了测试的方便,提供了autocreate 以及createSchema,对于schema 也可以自己通过sql 导入
    • 项目结构 
    ├── docker-compose.yaml
    ├── pom.xml
    └── src
        └── main
            ├── java
            └── org
            └── ff4j
            └── sample
            ├── Application.java
            ├── config
            └── FF4JConfiguration.java
            └── resources
            └── SampleResource.java
            └── resources
                └── application.properties
    • pom.xml
      注意版本,默认的shapshot版本好像没有发布?,所以使用了release 版本
     
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns="http://maven.apache.org/POM/4.0.0"
             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>org.ff4j</groupId>
        <artifactId>ff4j-sample-springboot-jdbc</artifactId>
        <packaging>jar</packaging>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.4.RELEASE</version>
        </parent>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <java.version>1.8</java.version>
            <ff4j.version>1.8.4</ff4j.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.ff4j</groupId>
                <artifactId>ff4j-spring-boot-starter</artifactId>
                <version>${ff4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.ff4j</groupId>
                <artifactId>ff4j-store-springjdbc</artifactId>
                <version>${ff4j.version}</version>
            </dependency>
             <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-dbcp2</artifactId>
            </dependency>
             <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
        </dependencies>
        <build>
            <sourceDirectory>src/main/java</sourceDirectory>
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                </resource>
            </resources>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    • application 配置
      主要是关于datasource的配置
     
    spring.datasource.name=ff4j_db
    spring.datasource.url=jdbc:mysql://localhost:3306/ff4j_v1
    spring.datasource.driverClassName=com.mysql.jdbc.Driver 
    spring.datasource.username=root
    spring.datasource.password=dalongrong
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    • Application.java
    package org.ff4j.sample;
    import org.ff4j.FF4j;
    import org.ff4j.core.Feature;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.ComponentScan;
    import javax.annotation.Resource;
    @SpringBootApplication
    public class Application implements CommandLineRunner {
        @Autowired
        FF4j getFF4j;
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    // 使用CommandLineRunner 接口,注册一个feature
        @Override
        public void run(String... strings) throws Exception {
           Feature feature = getFF4j.getFeature("feature_X");
           if(feature==null){
               getFF4j.enable("feature_X");
           }
        }
    }
    • ff4j bean 注册
      FF4JConfiguration.java
      注意开启了审计日志以及自动创建schema以及feature
     
    package org.ff4j.sample.config;
    import javax.sql.DataSource;
    import org.ff4j.FF4j;
    import org.ff4j.springjdbc.store.EventRepositorySpringJdbc;
    import org.ff4j.springjdbc.store.FeatureStoreSpringJdbc;
    import org.ff4j.springjdbc.store.PropertyStoreSpringJdbc;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    @Configuration()
    public class FF4JConfiguration {
        @Autowired
        private DataSource dataSource;
        @Bean
        public FF4j getFF4j() {
            FF4j ff4j = new FF4j();
            ff4j.setFeatureStore(new FeatureStoreSpringJdbc(dataSource));
            ff4j.setPropertiesStore(new PropertyStoreSpringJdbc(dataSource));
            ff4j.setEventRepository(new EventRepositorySpringJdbc(dataSource));
            ff4j.audit(true);
            ff4j.createSchema();
            ff4j.autoCreate(true);
            return ff4j;
        }
    }
     
    • rest api 创建
      引用ff4j bean 以及获取feature
    package org.ff4j.sample.resources;
    import org.ff4j.FF4j;
    import org.ff4j.spring.autowire.FF4JFeature;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    @RestController
    public class SampleResource {
        @Autowired
        private FF4j getFF4j;
        @RequestMapping(value = "/", method = RequestMethod.GET, produces = "text/html")
        public String sayHello() {
            StringBuilder response = new StringBuilder("<html><body><ul>");
            response.append("<p>Is <span style="color:red">Awesome</span> feature activated ? from ff4j.check("feature_X") <span style="color:blue">");
            response.append(getFF4j.check("feature_X"));
            response.append("</span></body></html>");
            return response.toString();
        }
    }
     

    启动&&效果

    • 启动数据库
    docker-compose up -d 
    • 启动服务
    mvn spring-boot:run
    • 效果

    db


    访问


    修改数据(直接从db,合理的方式是通过业务管理或者webconsole)

    说明

    以上是一个关于db的简单试用,实际使用还需要考虑各种性能问题以及安全问题,实际上如果查看ff4j bean 的创建,就会发现我们的
    feature,event,以及properties 理论上都是可以分离的,同时也可以支持多种数据存储

    • 附一个jdbc 的sql schema
    -- Main Table to store Features
    CREATE TABLE FF4J_FEATURES (
      FEAT_UID VARCHAR(100),
      ENABLE INTEGER NOT NULL,
      DESCRIPTION VARCHAR(1000),
      STRATEGY VARCHAR(1000),
      EXPRESSION VARCHAR(255),
      GROUPNAME VARCHAR(100),
      PRIMARY KEY(FEAT_UID)
    );
    -- Roles to store ACL, FK to main table
    CREATE TABLE FF4J_ROLES (
      FEAT_UID VARCHAR(100) REFERENCES FF4J_FEATURES(FEAT_UID),
      ROLE_NAME VARCHAR(100),
      PRIMARY KEY(FEAT_UID, ROLE_NAME)
    );
    -- Feature Internal Custom Properties
    CREATE TABLE FF4J_CUSTOM_PROPERTIES (
      PROPERTY_ID VARCHAR(100) NOT NULL,
      CLAZZ VARCHAR(255) NOT NULL,
      CURRENTVALUE VARCHAR(255),
      FIXEDVALUES VARCHAR(1000),
      DESCRIPTION VARCHAR(1000),
      FEAT_UID VARCHAR(100) REFERENCES FF4J_FEATURES(FEAT_UID),
      PRIMARY KEY(PROPERTY_ID, FEAT_UID)
    );
    -- @PropertyStore (edit general properties)
    CREATE TABLE FF4J_PROPERTIES (
      PROPERTY_ID VARCHAR(100) NOT NULL,
      CLAZZ VARCHAR(255) NOT NULL,
      CURRENTVALUE VARCHAR(255),
      FIXEDVALUES VARCHAR(1000),
      DESCRIPTION VARCHAR(1000),
      PRIMARY KEY(PROPERTY_ID)
    );
    -- @see JdbcEventRepository (audit event)
    CREATE TABLE FF4J_AUDIT (
      EVT_UUID VARCHAR(40) NOT NULL,
      EVT_TIME TIMESTAMP NOT NULL,
      EVT_TYPE VARCHAR(30) NOT NULL,
      EVT_NAME VARCHAR(30) NOT NULL,
      EVT_ACTION VARCHAR(30) NOT NULL,
      EVT_HOSTNAME VARCHAR(100) NOT NULL,
      EVT_SOURCE VARCHAR(30) NOT NULL,
      EVT_DURATION INTEGER,
      EVT_USER VARCHAR(30),
      EVT_VALUE VARCHAR(100),
      EVT_KEYS VARCHAR(255),
      PRIMARY KEY(EVT_UUID, EVT_TIME)
    );

    参考资料

    https://github.com/ff4j/ff4j/wiki/Store-Technologies#springjdbc

  • 相关阅读:
    阿里云服务器配置
    linux 环境变量问题
    docker 常用操作
    docker 安装的nginx 的默认配置
    camera开发相关
    Ubuntu下使用Git
    Java web项目实现多附件上传
    Java web项目实现上传图片及时预览
    SQL Server游标【转】
    SQL Server游标的使用【转】
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/12739844.html
Copyright © 2020-2023  润新知