游戏版本要回滚,还好我机智备份了数据库,代码直接拿走

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

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


1、工作中的问题


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


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


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


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


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


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


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


2、解决方案


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


优化点:


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


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


3、新增了建表sql备份


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


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,主要用来给其他部门交流。

 

943ae736963f4101a8ee8ae6fad6a22a~tplv-k3u1fbpfcp-zoom-in-crop-mark_1304_0_0_0.webp.jpg


69128802a6d34d4882bb8432f67e9f81~tplv-k3u1fbpfcp-zoom-in-crop-mark_1304_0_0_0.webp.jpg

38a7ef9ece854bca851a5a7a5149198f~tplv-k3u1fbpfcp-zoom-in-crop-mark_1304_0_0_0.webp.jpg


总结


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

目录
相关文章
|
1月前
|
关系型数据库 MySQL Linux
Linux环境下MySQL数据库自动定时备份实践
数据库备份是确保数据安全的重要措施。在Linux环境下,实现MySQL数据库的自动定时备份可以通过多种方式完成。本文将介绍如何使用`cron`定时任务和`mysqldump`工具来实现MySQL数据库的每日自动备份。
108 3
|
1月前
|
监控 关系型数据库 MySQL
Linux环境下MySQL数据库自动定时备份策略
在Linux环境下,MySQL数据库的自动定时备份是确保数据安全和可靠性的重要措施。通过设置定时任务,我们可以每天自动执行数据库备份,从而减少人为错误和提高数据恢复的效率。本文将详细介绍如何在Linux下实现MySQL数据库的自动定时备份。
47 3
|
2月前
|
存储 定位技术 数据库
介绍一下数据库的备份和恢复策略
【10月更文挑战第21】介绍一下数据库的备份和恢复策略
|
1月前
|
数据库
【赵渝强老师】数据库的备份方式
备份数据库是指将数据库中的数据及相关信息保存起来,以便在系统故障时恢复。备份对象不仅限于数据本身,还包括数据库对象、用户权限等。根据备份策略、类型和模式的不同,可分为整体/部分备份、完全/增量备份、一致/非一致备份。文中还附有相关视频讲解。
|
1月前
|
SQL 关系型数据库 数据库连接
"Nacos 2.1.0版本数据库配置写入难题破解攻略:一步步教你排查连接、权限和配置问题,重启服务轻松解决!"
【10月更文挑战第23天】在使用Nacos 2.1.0版本时,可能会遇到无法将配置信息写入数据库的问题。本文将引导你逐步解决这一问题,包括检查数据库连接、用户权限、Nacos配置文件,并提供示例代码和详细步骤。通过这些方法,你可以有效解决配置写入失败的问题。
84 0
|
2月前
|
XML 缓存 数据库
Discuz! X3.0 版本的数据库字典
Discuz! X3.0 版本的数据库字典
64 0
|
2月前
|
JavaScript 前端开发 测试技术
[新手入门]todolist增删改查:vue3+ts版本!
【10月更文挑战第15天】[新手入门]todolist增删改查:vue3+ts版本!
|
3天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
13 3
|
3天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
19 3
|
3天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE &#39;log_%&#39;;`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
22 2