前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >screw 再升级,备份你的数据库,直接帮你写好的代码还不拿走!!!

screw 再升级,备份你的数据库,直接帮你写好的代码还不拿走!!!

作者头像
香菜聊游戏
发布2021-05-26 11:00:49
2980
发布2021-05-26 11:00:49
举报
文章被收录于专栏:香菜聊游戏

今天有空整了下之前写的数据库备份的代码。

1、工作中的问题

数据库开发流程一般是先在power design 中新建表结构(因为pd其他部门要看的),然后拷贝生成的DDL建表语句,在数据库中执行,然后才算创建了一张表。这样的工作流程中间有一些问题。

1、不方便修改,打断了代码开发的专注。

如果在开发的过程中想要修改表,我会直接在数据库中通过Navicat修改表结构,进行增删改,正常的情况下然后还要同步到pd中。这样的流程打断了我开发代码的专注度,因此需要将我们从这样的繁琐事中解脱出来。

2、容易遗忘,会有心理负担

修改数据是基本操作,如果在开发功能的过程中频繁修改,去同步pd,会给开发产生负担,这样的情况下就会产生遗忘,在功能开发完成的情况下,基本上很少去再次补全pd,一份不完整的pd意义是不大的。毕竟不想每次都有人问表的结构怎么样,也不想费口舌,也会有自己没有维护好,没有做好的感觉。

3、游戏版本更新频繁,无法回滚数据库

在最忙的时候,游戏基本上是两周一个新版本,每个版本都会伴随一些表的变更,虽然我们的游戏代码都会有版本记录,但是数据的表结构一直没有好的备份,这样的情况下造成数据库表结构很难回滚,所以需要想办法对数据库进行备份。

2、解决方案

有这样的问题,必然想要解决。解决问题了才能提升工作效率(有时间划水),减少犯错的可能性(不想背锅)。下面是我写的整理数据的工具,使用了screw,我新增了对数据库表结构的备份,下载代码,简单改下配置就可以直接运行,拿去不谢。

优化点:

1、对生成的文件加了日期作为版本号

2、在表结构中新加了删除表的语句

3、新增了建表sql备份

下面的代码直接拷贝放在编辑器修改数据库连接信息后,可直接运行

代码语言:javascript
复制
package screw;

import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.engine.EngineFileType;
import cn.smallbun.screw.core.engine.EngineTemplateType;
import cn.smallbun.screw.core.execute.DocumentationExecute;
import cn.smallbun.screw.core.process.ProcessConfig;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import javax.sql.DataSource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class App {


    public static void main(String[] ags) throws IOException, SQLException {

        String dbName = "fate";
        HikariConfig config = new HikariConfig();
        config.setDriverClassName("com.mysql.cj.jdbc.Driver");
        config.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/" + dbName +" ?serverTimezone=UTC");
        config.setUsername("root");
        config.setPassword("root");
        config.addDataSourceProperty("useInformationSchema", "true");
        config.setMinimumIdle(2);
        config.setMaximumPoolSize(5);
        DataSource ds = new HikariDataSource(config);
        String userDir = System.getProperty("user.dir") + "\\src\\test\\java\\com\\pdool\\";
        System.out.println(userDir);
        SimpleDateFormat dataFormat = new SimpleDateFormat("yyMMdd");
        String versionStr = dataFormat.format(new Date());
        List<String> ignoreTable = new ArrayList<>();
        List<String> ignorePrefix = new ArrayList<>();
        List<String> ignoreSuffix = new ArrayList<>();
        ignoreSuffix.add("_test");
        ignoreSuffix.add("test");

        for (int i = 0; i < 10; i++) {
            ignoreSuffix.add(String.valueOf(i));
        }
        createHtml(ds, userDir, versionStr, ignoreTable, ignorePrefix, ignoreSuffix);
        createSql(dbName, ds, userDir, versionStr, ignoreTable, ignorePrefix, ignoreSuffix);
    }

    public static void createHtml(DataSource dataSource, String userDir, String versionStr, List<String> ignoreTable, List<String> ignorePrefix, List<String> ignoreSuffix) {

        EngineConfig engineConfig = EngineConfig.builder()
                .fileOutputDir(userDir)
                .openOutputDir(false)
                .fileType(EngineFileType.HTML)
                .produceType(EngineTemplateType.freemarker)
                .build();

        ProcessConfig processConfig = ProcessConfig.builder()
                .ignoreTableName(ignoreTable)
                .ignoreTablePrefix(ignorePrefix)
                .ignoreTableSuffix(ignoreSuffix)
                .build();

        Configuration config = Configuration.builder()
                .version(versionStr)
                .description("数据库文档")
                .dataSource(dataSource)
                .engineConfig(engineConfig)
                .produceConfig(processConfig).build();

        new DocumentationExecute(config).execute();
    }

    public static void createSql(String dbName, DataSource dataSource, String userDir, String versionStr, List<String> ignoreTable, List<String> ignorePrefix, List<String> ignoreSuffix) throws IOException, SQLException {
        Statement tmt = null;
        PreparedStatement pstmt = null;
        List<String> createSqlList = new ArrayList<>();
        String sql = "select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = '"+dbName+"' and TABLE_TYPE = 'BASE TABLE'";
        tmt = dataSource.getConnection().createStatement();
        pstmt = dataSource.getConnection().prepareStatement(sql);
        ResultSet res = tmt.executeQuery(sql);
        while (res.next()) {
            String tableName = res.getString(1);
            if (tableName.contains("`")) {
                continue;
            }
            if (ignoreTable.contains(tableName)) {
                continue;
            }
            boolean isContinue = false;
            for (String prefix : ignorePrefix) {

                if (tableName.startsWith(prefix)) {
                    isContinue = true;
                    break;
                }
            }
            if (isContinue) {
                continue;
            }
            for (String suffix : ignoreSuffix) {
                if (tableName.startsWith(suffix)) {
                    isContinue = true;
                    break;
                }
            }
            if (isContinue) {
                continue;
            }
            ResultSet rs = pstmt.executeQuery("show create Table `" + tableName + "`");

            while (rs.next()) {
                createSqlList.add("DROP TABLE IF EXISTS '" + tableName + "'");
                createSqlList.add(rs.getString(2));
            }
        }

        String head = "-- 数据库建表语句 \r\n";
        head += "-- db:" + dbName + " version: " + versionStr + "\r\n";
        String collect = String.join(";\r\n", createSqlList);
        collect = head + collect + ";";
        string2file(collect, userDir + dbName + "_" + versionStr + ".sql");
    }

    public static void string2file(String collect, String dirStr) throws IOException {
        System.out.println("文件地址  "+ dirStr);
        OutputStreamWriter osw = null;
        try {
            osw = new OutputStreamWriter(new FileOutputStream(new File(dirStr)), StandardCharsets.UTF_8);
            osw.write(collect);
            osw.flush();
        } finally {
            if (osw != null) {
                osw.close();
            }
        }
    }


}

3、运行的结果

生成的文件如下图

文件地址:控制台也有打印文件地址

文件说明:fate_20210304.sql :数据库名 fate ,生成日期是20210304,内容是建表语句。主要用来和代码对应,恢复数据库。

fate_数据库文档__20210304.html::数据库名 fate ,生成日期是20210304,内容是html,主要用来给其他部门交流。

总结

本来在公司已经写好的工具,可惜公司内网没办法拿出来,自己又重写了一遍,也花费了不少时间,挺晚了,准备睡觉。

PS:原创不易,点个在看,我需要你的关注,点个关注吧,不粘人还可以领取编程资料和游戏源码。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 香菜聊游戏 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、工作中的问题
    • 1、不方便修改,打断了代码开发的专注。
      • 2、容易遗忘,会有心理负担
        • 3、游戏版本更新频繁,无法回滚数据库
        • 2、解决方案
        • 3、运行的结果
        • 总结
        相关产品与服务
        数据库
        云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档