springboot項(xiàng)目實(shí)現(xiàn)定時(shí)備份數(shù)據(jù)庫(kù)導(dǎo)出sql文件方式
之所以做這個(gè)功能的原因是我的服務(wù)器上的數(shù)據(jù)庫(kù)被攻擊了,還好服務(wù)器上沒(méi)有什么重要的數(shù)據(jù),但是數(shù)據(jù)沒(méi)了就很肉疼,因此做了這個(gè)功能,用來(lái)定時(shí)備份數(shù)據(jù)庫(kù)數(shù)據(jù)
添加依賴
這里用到了 hutool 工具包 這個(gè)包挺好用的,推薦大家可以多看看他的官方文檔
官方文檔:https://www.hutool.cn/docs/#/
<!-- hutool工具類--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.3.3</version> </dependency>
添加配置文件和配置
因?yàn)檫@里只是需要導(dǎo)出sql 所以就使用了hutool工具中的DB
在resources
目錄下創(chuàng)建db.setting
數(shù)據(jù)庫(kù)配置文件
文件中內(nèi)容:
## url 數(shù)據(jù)庫(kù)連接地址 ## user 連接數(shù)據(jù)庫(kù)賬號(hào) ## pass 連接數(shù)據(jù)庫(kù)密碼 url = jdbc:mysql://localhost:3306/test user = root pass = 123456
緊接著在application.yml
文件中添加sql文件的存放的路徑
# 導(dǎo)出sql文件的位置 sql: dbname: notepad # 數(shù)據(jù)庫(kù)名 filePath: /data/sql/ # 導(dǎo)出sql文件的位置 win下會(huì)直接在項(xiàng)目所在磁盤下建立 data/sql文件
編寫導(dǎo)出SQL的方法
方法直接貼在下面:
package com.an.notepad.task; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DateTime; import cn.hutool.core.io.file.FileWriter; import cn.hutool.core.text.StrBuilder; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.db.Db; import cn.hutool.db.Entity; import cn.hutool.db.ds.DSFactory; import lombok.Data; import lombok.SneakyThrows; import lombok.experimental.Accessors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; import java.io.File; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.util.List; @Configuration public class ExportSQL { // 用于打印執(zhí)行日志 private static final Logger logger = LoggerFactory.getLogger(ExportSQL.class); // 存儲(chǔ)的路徑 @Value("${sql.filePath}") private String filePath; // 數(shù)據(jù)庫(kù)名 @Value("${sql.dbname}") private String database_name; // 需要導(dǎo)出的表名 private final List<TempBean> tempBeanList = CollectionUtil.newArrayList( // 這里寫需要存儲(chǔ)的表名 有幾張表就new幾個(gè) new TempBean().setTable("n_note"), new TempBean().setTable("n_user") ); @SneakyThrows public void export() { //獲取默認(rèn)數(shù)據(jù)源 DataSource ds = DSFactory.get(); // 獲取數(shù)據(jù)庫(kù)連接對(duì)象 Connection connection = ds.getConnection(); // 獲取連接信息 DatabaseMetaData metaData = connection.getMetaData(); // 創(chuàng)建sql文件對(duì)象 FileWriter sqlFileWriter = FileWriter.create(new File(filePath + database_name + ".sql")); sqlFileWriter.write(""); sqlFileWriter.append("USE " + database_name + ";\n"); sqlFileWriter.append("/*\n"); sqlFileWriter.append(" --------------------------------------------------\n"); sqlFileWriter.append(" Target Server Type : " + metaData.getDatabaseProductName() + ";\n"); sqlFileWriter.append(" Target Server Version : " + metaData.getDatabaseProductVersion() + ";\n"); sqlFileWriter.append(" \n"); sqlFileWriter.append(" Target Server Date : " + DateTime.now() + ";\n"); sqlFileWriter.append(" \n"); sqlFileWriter.append(" --------------------------------------------------\n"); sqlFileWriter.append("*/\n"); sqlFileWriter.append("SET NAMES utf8mb4;\n"); sqlFileWriter.append("SET FOREIGN_KEY_CHECKS = 0;\n"); for (TempBean tempBean : tempBeanList) { String table = tempBean.table; sqlFileWriter.append("\n\n\n"); // DROP TABLE sqlFileWriter.append("DROP TABLE IF EXISTS `" + table + "`;\n"); // CREATE TABLE Entity createTableEntity = Db.use().queryOne("SHOW CREATE TABLE " + table); sqlFileWriter.append((String) createTableEntity.get("Create Table")); sqlFileWriter.append(";\n"); // 看配置,是否需要insert語(yǔ)句 if (!tempBean.insert) { continue; } // INSERT INTO List<Entity> dataEntityList = Db.use().query("SELECT * FROM " + table); for (Entity dataEntity : dataEntityList) { StrBuilder field = StrBuilder.create(); StrBuilder data = StrBuilder.create(); dataEntity.forEach((key, value) -> { field.append(key).append(", "); if (ObjectUtil.isNotNull(value)) { if (StrUtil.equals("true", String.valueOf(value))) { data.append("b'1'"); } else if (StrUtil.equals("false", String.valueOf(value))) { data.append("b'0'"); } else { data.append("'").append(value).append("'"); } } else { data.append("NULL"); } data.append(", "); }); sqlFileWriter.append("INSERT INTO `" + table + "`("); String fieldStr = field.subString(0, field.length() - 2); sqlFileWriter.append(fieldStr); sqlFileWriter.append(") VALUES ("); String dataStr = data.subString(0, data.length() - 2); sqlFileWriter.append(dataStr); sqlFileWriter.append(");\n"); } } sqlFileWriter.append("\n\n\n"); sqlFileWriter.append("SET FOREIGN_KEY_CHECKS = 1;\n"); logger.info(">>>>>>>>>> 存儲(chǔ)sql成功" + DateTime.now()); } @Data @Accessors(chain = true) static class TempBean { // 表名 public String table; // 是否需要insert語(yǔ)句,默認(rèn)需要 (表中數(shù)據(jù)) public Boolean insert = true; } }
創(chuàng)建定時(shí)任務(wù)
package com.an.notepad.task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; /** * 定時(shí)導(dǎo)出數(shù)據(jù)庫(kù)sql功能 */ @Configuration @EnableScheduling // 開(kāi)啟定時(shí)任務(wù) public class ExportTask { @Autowired private ExportSQL exportSQL; //@Scheduled(cron = "0 0 1 * * ?") // 每天凌晨1點(diǎn)觸發(fā)一次 @Scheduled(cron = "*/5 * * * * ?") // 5秒觸發(fā)一次 public void task() { exportSQL.export(); } }
編寫完成 運(yùn)行測(cè)試一下
我這里項(xiàng)目在D盤
中,因此D盤
下D:\data\sql
默認(rèn)會(huì)有生成的文件
成功,我這邊測(cè)試了一下,數(shù)據(jù)庫(kù)是可以導(dǎo)入的
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java數(shù)據(jù)庫(kù)連接池連接Oracle過(guò)程詳解
這篇文章主要介紹了Java數(shù)據(jù)庫(kù)連接池連接Oracle過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09jpa?onetomany?使用級(jí)連表刪除被維護(hù)表數(shù)據(jù)時(shí)的坑
這篇文章主要介紹了jpa?onetomany?使用級(jí)連表刪除被維護(hù)表數(shù)據(jù)時(shí)的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12教你在一分鐘之內(nèi)理解Java Lambda表達(dá)式并學(xué)會(huì)使用
今天給大家?guī)У奈恼率荍ava8新特性的相關(guān)知識(shí),文章圍繞著如何在一分鐘之內(nèi)理解Java Lambda表達(dá)式并學(xué)會(huì)使用展開(kāi),文中有非常詳細(xì)的介紹,需要的朋友可以參考下2021-06-06SpringBoot項(xiàng)目嵌入RocketMQ的實(shí)現(xiàn)示例
本文主要介紹了SpringBoot項(xiàng)目嵌入RocketMQ的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05springMVC在restful風(fēng)格的性能優(yōu)化方案
這篇文章主要介紹了springMVC在restful風(fēng)格的性能優(yōu)化方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08@Valid 校驗(yàn)無(wú)效,BindingResult未獲得錯(cuò)誤的解決
這篇文章主要介紹了@Valid 校驗(yàn)無(wú)效,BindingResult未獲得錯(cuò)誤的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10SpringBoot統(tǒng)一功能處理實(shí)現(xiàn)的全過(guò)程
最近在做項(xiàng)目時(shí)需要對(duì)異常進(jìn)行全局統(tǒng)一處理,主要是一些分類入庫(kù)以及記錄日志等,下面這篇文章主要給大家介紹了關(guān)于SpringBoot統(tǒng)一功能處理實(shí)現(xiàn)的相關(guān)資料,文中通過(guò)圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-01-01