1 Star 2 Fork 0

GCC1566 / Conscript

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

Conscript 数据库初始化工具

Conscript基于Spring-boot-starter的方式提供数据库初始化功能,可以随项目初次启动,自动创建相关数据库,后续系统升级所引发的数据库变化及升级也可由此完成,拆箱即用,随系统程序代码运行,省去额外的数据库升级操作,

支持数据库种类可扩展,目前支持通用mysql、postgreSQL、 国产数据库达梦和金仓

支持执行失败回滚机制

1.支持数据库类型

数据库类型 是否支持 db-driver参数
mysql mysql
mariadb mariadb
PostgreSQL pgsql
达梦数据库 dm
人大金仓8 kingbase8

2.实现设计

核心代码结构:

+---action                                     #基础功能包 
|   +---mysql                                 #mysql数据库实现
----initDataBase                              #数据库初始化接口
----DataBaseInitorFactory                      #数据库初始器工厂
----AbstractInitDataBase                      #数据库初始器基类
介绍
initDataBase 初始化接口
AbstractInitDataBase 初始化基类,定义核心逻辑
MySqlDataBase Mysql实现,具体执行方式
DataBaseInitorFactory 工厂类
classDiagram
direction TD
class initDataBase{
    <<interface>>
    isInitEd()
    startCoreJob()
    createConnection()
    databaseIsExitd()
    getCurrenDbVersion()
    excuteSQL(Map<String, String> sqlcontent)
    close()
}
class AbstractInitDataBase {
    <<abstract>>
    +void : startCoreJob()
  }
class MySqlDataBase {
    +void : createConnection()
    +boolean:databaseIsExitd()
    +Float:getCurrenDbVersion()
    +void:excuteSQL(Map<String, String> sqlcontent)
  }
class DataBaseInitorFactory {
    +InitDataBase : createInitiator(DbConConfiguration config)
    +String:getClassUrlValue(DbType dbType)
  }
  class DbConConfiguration {
    +DbConConfiguration : builder()
    +void:set()
    +Object:get()
  }
initDataBase <-- AbstractInitDataBase : 
AbstractInitDataBase <|-- MySqlDataBase
DbConConfiguration <.. DataBaseInitorFactory
initDataBase -- DataBaseInitorFactory

扩展其他类型数据库:在action目录下新建相应的数据库类型目录,然后继承AbstractInitDataBase类,实现对应的几个数据库操作方法,在DatabaseProperties的getDbDeriver()中新增对应的映射

3.使用方式

可直接集成至SpringBoot项目中使用

SpringBoot版本要求
SpringBoot version >= 2.3.6.RELEASE

1.引入Conscript

1.1.使用jar引入

本地编译源码后,install到本地的maven私仓后,直接引入项目

<dependency>
    <groupId>com.gcc.airbase</groupId>
    <artifactId>Conscript</artifactId>
    <version>1.0</version>
</dependency>

2.配置yml文件

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/test?user=root&password=1234
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver
    db-config-file-url: sql/mysql/dbconfig.json
    db-driver: mysql
    db-name: test

配置内容遵循标准的spring.datasource配置,并进行了增强

字段 含义 是否必填
url 必选字段,遵循标准datasource即可,若使用mybaits,则按照mybaits标准填写
username 必选字段,标准datasource即可,填写数据库账号
password 必选字段,标准datasource即可,填写数据库连接密码
driver-class-name 必选字段,标准datasource即可,填写数据库连接驱动类
db-config-file-url 必选字段,指定静态SQL文件存放位置
db-driver 必选字段,指定数据库类型,扩展时,可填写类路径,默认填写mysql,详细见扩展用法章节
dbport 非必选字段,数据库服务端口,若url填写,可省略该字段
db-name 非必选字段,需要连接的数据库名称,若url中填写,可省略该字段
schema 非必须字段,若url中填写,则可省略,主要用于对部分数据库的模式配置
root-user 非必选字段,若存在对数据库权限分离有要求的需求,可以在此填写专门用于建库的高权限账号
root-pass 非必选字段,若存在对数据库权限分离有要求的需求,可以在此填写专门用于建库的高权限账号密码

此处配置相较 spring.datasource的基础的 url、username、password、driver-class-name外,增加了独有的db-driver、db-config-file-url,原则上只需要满足此6项配置即可使用Conscript,但建议将配置补全使用

使用该组件,必须确保拥有较高的数据库角色权限,例如mysql的root、pgsql的postgres,否则无法使用创建数据库的功能,如需清晰划分权限,则可以通过配置项中的root-user,root-pass来将系统数据库的使用区分开来

3.建立配置文件及SQL文件

以标准maven项目为例

​ 1.根据 yml中spring.datasource.db-config-file-url配置的值,在resource目录下新建相应路径json文件

XX.json文件样例如下:

 [
   {
      "version": "1.0",
      "sqlfile": "a.sql",
      "desc": "基础数据库结构"
   },
    {
       "version": "1.1",
       "sqlfile": "ddd.sql",
       "desc": "第一版升级数据库"
    }
 ]
字段 含义
version 数据库的版本,数字类型
sqlfile 数据库升级的sql文件,叠加式追加,注:这里要写清楚sql文件的路径(基于resource目录为基准),此处的配置决定后续sql文件的存放位置
desc 维护使用的描述信息

​ 2.根据XX.json配置文件中的sqlfile配置项,新建相应目录追加需要预制的SQL文件

4.提供一个标准的用例

yml配置文件如下:

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/test?user=root&password=1234?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&serverTimezone=GMT%2B8
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver
    db-dirver: mysql
    db-config-file-url: sql/mysql-dbconfig.json
    db-name: test

mysql-dbconfig.json配置如下:

 [
   {
      "version": "1.0",
      "sqlfile": "sql/a.sql",
      "desc": "基础数据库结构"
   },
    {
       "version": "1.1",
       "sqlfile": "sql/ddd.sql",
       "desc": "第一版升级数据库"
    }
 ]

目录结构如下:

+-java                                        #java源码 
+-resource                                    #资源文件
|   +---sql                                   #sql初始化配置内容
        |+---mysql-dbconfig.json                     #sql初始化配置内容
        |+---a.sql                                   #sql初始化配置内容
        |+---ddd.sql                                 #sql初始化配置内容

yml配置中的db-config-file-url配置决定着json配置文件的存放,如填写的路径为:sql/mysql/a.json,则需要在resource目录下新建sql文件夹,并在sql文件夹下新建mysql文件夹,然后在mysql文件夹中按照样例创建json文件;json配置文件中的sqlfile属性决定着需要执行的sql文件存放位置;

为了方便,建议json文件中的sql文件存放位置和json文件在同级目录

5.其他说明

使用过程中获取建库结果,需要在代码中获取数据库的升级结果以便后续操作,可直接获取bean DbIsExist 的值来进行判定:

@Service
public class AfterStartProcess{

    @Qualifier("DbIsExid")
    @Autowired
    Boolean dbIsOk;


      public void test(){
       if(dbIsOk){
         System.out.print("数据库升级完成!")
       }
      }
}

默认数据库版本表名称修改,需要新增配置 conscript.table-name 配置项:

conscript:
    table-Name: xxxx

4.扩展

若支持的数据库类型不满足要求,需要自行进行扩展,项目引入后,可新建类继承 AbstractInitDataBase类,仅实现对应的 initCommConn() initDbConn() databaseIsExitd()

createDataBase() 方法,并将新建的类路径配置到db-driver中即可

method:initCommConn()

创建数据库基础JDBC连接,

AbstractInitDataBase类中定义了 commConn dbConn 两个Connection 变量,该方法主要用于对 commConn变量进行初始化,建立基础的数据库连接,用于测试数据库联通以及执行数据库建库语句,例如MySQL中,需要建立连接mysql数据库的JDBC

 @Override
    public void initCommConn() {
        try {
            Class.forName(dataBaseProperties.getDriverClassName());
            String jdbc_url = "jdbc:mysql://" + dataBaseProperties.getHost() + ":" + dataBaseProperties.getDbport() + "/mysql?characterEncoding=utf8&serverTimezone=GMT%2B8";
            commConn = DriverManager.getConnection(jdbc_url, dataBaseProperties.getUsername(), dataBaseProperties.getPassword());
        }catch (Exception e){
            log.error("【Conscript】Database initialization :data base is not connection.....");
        }
    }

method: initDbConn()

创建数据库基础JDBC连接,

AbstractInitDataBase类中定义了 commConn dbConn 两个Connection 变量,该方法主要用于对 dbConn变量进行初始化,建立对目标数据库(配置中指定的数据库)实例的JDBC连接,用于执行SQL语句

 @Override
    public void initDbConn() {
        try{
            String url = "jdbc:mysql://"+ dataBaseProperties.getHost()+":"+ dataBaseProperties.getDbport()+"/"+ dataBaseProperties.getDbName()+"?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&serverTimezone=GMT%2B8";
            dbConn = DriverManager.getConnection(url, dataBaseProperties.getUsername(), dataBaseProperties.getPassword());
        }catch (Exception e){
            log.warn("");
        }
    }

method:databaseIsExitd(Connection connection)

确定需要连接的目标数据库实例((配置中指定的数据库))是否存在,使用commConn进行确认,不同的数据库确认实例的方式不同,可根据具体要扩展的数据库类型自行进行定义

@Override
    public boolean databaseIsExitd(Connection connection){
        try {
            Statement stmt = connection.createStatement();
            ResultSet res = stmt.executeQuery("SELECT COUNT(*) FROM information_schema.schemata WHERE schema_name= \""+ dataBaseProperties.getDbName()+"\"");
            if(res.next() && res.getInt(1) == 0){
                stmt.close();
                return false;
            }
            return true;
        }catch (Exception e){
            log.error("【Conscript】Database initialization :database base query is error");
        }
        return false;
    }

method:createDataBaseSQL()

创建指定的数据库的建库语句,仅返回对应的建库语句即可

@Override
    public String createDataBaseSQL() {
        return "CREATE DATABASE IF NOT EXISTS "+ dataBaseProperties.getDbName()+" DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci";
    }

5.回滚保护机制

为防止用户自定义的sql文件中存在错误的语法,导致升级建库过程因部分sql错误而失败,但正常SQL却已经执行,污染了原始数据库;Conscript进行了加强,可以将升级过程停止于错误sql文件之前,保证存在错误语法的sql文件不会被执行,从而保证不会污染原始数据库

graph LR;
 sql文件 --> 语法校验;
 语法校验 --> 数据事务操作保护

保护机制为两层防护,第一层为语法保护,保证执行的sql语法都是正确的,能够被数据库执行的,其次进行一次数据操作的回滚,当正确的SQL满足了语法要求,但是如果存在语义错误(主键冲突、字段和值不匹配等造成的数据操作失败),则进行数据 增删改的回滚机制,保证数据不被污染

注:因开启回滚保护机制,需要对sql文件进行语法校验,sql文件数量较大时会有较高的性能损耗,可根据实际情况使用,默认是不开启状态

使用方法

yml文件中新增conscript.parse-enable属性,取值范围为布尔,不配置时默认为 false

conscript:
    parse-enable: true

6.其他问题

6.1 与Mybatis-plus一起使用时,会出现Conscript在Mybatis-Plus之后加载的情况,此时会因为未创建数据库,导致Mybatis-plus的SqlSession创建失败,解决方案需要在启动类上使用注解@DependsOn,手动干预starter加载顺序,先加载Conscript的 DbIsExist bean,如下:

@SpringBootApplication
@DependsOn("DbIsExist")
public class Application {

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

}

空文件

简介

取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/gcc1566/conscript.git
git@gitee.com:gcc1566/conscript.git
gcc1566
conscript
Conscript
master

搜索帮助