java 备份mysql_通过纯java代码备份mysql库

以往java备份mysql数据库需要通过dump工具,不同的服务器需要配置环境变量来实现,不具通用性,能不能使用纯java代码来实现呢?当然可以,先看一下如何使用,以jfinal为例子:PropKit.use("config.txt");

MySqlInfo mySqlInfo = new MySqlInfo(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password"));

MysqlExport mysqlExport = new MysqlExport(mySqlInfo);

try {

mysqlExport.export();

} catch (IOException e) {

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

以上代码是从配置文件中读取mysql的配置信息jdbcUrl,user,password,然后封装到MySqlInfo里.

MySqlInfo的代码:public class MySqlInfo {

private String jdbcUrl="";

private String user="";

private String password="";

private String exportPath= "dbbak";

public String getExportPath() {

return PathKit.getWebRootPath()+"/"+exportPath;

}

public void setExportPath(String exportPath) {

this.exportPath = exportPath;

}

public MySqlInfo(String jdbcUrl,  String user, String password) {

this.jdbcUrl = jdbcUrl;

this.user = user;

this.password = password;

}

public String getJdbcUrl() {

return jdbcUrl;

}

public void setJdbcUrl(String jdbcUrl) {

this.jdbcUrl = jdbcUrl;

}

public String getUser() {

return user;

}

public void setUser(String user) {

this.user = user;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

}

MysqlExport就是实际上的mysql导出备份类。

MysqlExport代码:import org.zeroturnaround.zip.ZipUtil;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.sql.*;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.List;

import java.util.Objects;

public class MysqlExport {

private Statement stmt;

private String database;

private String generatedSql = "";

private String sqlFileName = "";

private String zipFileName = "";

private File generatedZipFile;

private MySqlInfo mySqlInfo = null;

public MysqlExport(MySqlInfo mySqlInfo) {

this.mySqlInfo = mySqlInfo;

}

/**

* 生成create语句

*

* @param table the table concerned

* @return String

* @throws SQLException exception

*/

private String getTableInsertStatement(String table) throws SQLException {

StringBuilder sql = new StringBuilder();

ResultSet rs;

boolean addIfNotExists = true;

if (table != null && !table.isEmpty()) {

rs = stmt.executeQuery("SHOW CREATE TABLE " + "`" + table + "`;");

while (rs.next()) {

String qtbl = rs.getString(1);

String query = rs.getString(2);

sql.append("\n\n--");

sql.append("\n").append(MysqlUtil.SQL_START_PATTERN).append("  table dump : ").append(qtbl);

sql.append("\n--\n\n");

if (addIfNotExists) {

query = query.trim().replace("CREATE TABLE", "CREATE TABLE IF NOT EXISTS");

}

sql.append(query).append(";\n\n");

}

sql.append("\n\n--");

sql.append("\n").append(MysqlUtil.SQL_END_PATTERN).append("  table dump : ").append(table);

sql.append("\n--\n\n");

}

return sql.toString();

}

/**

* 生成insert语句

*

* @param table the table to get inserts statement for

* @return String generated SQL insert

* @throws SQLException exception

*/

private String getDataInsertStatement(String table) throws SQLException {

StringBuilder sql = new StringBuilder();

ResultSet rs = stmt.executeQuery("SELECT * FROM " + "`" + table + "`;");

rs.last();

int rowCount = rs.getRow();

if (rowCount <= 0) {

return sql.toString();

}

sql.append("\n--").append("\n-- Inserts of ").append(table).append("\n--\n\n");

sql.append("\n/*!40000 ALTER TABLE `").append(table).append("` DISABLE KEYS */;\n");

sql.append("\n--\n")

.append(MysqlUtil.SQL_START_PATTERN).append(" table insert : ").append(table)

.append("\n--\n");

sql.append("INSERT INTO `").append(table).append("`(");

ResultSetMetaData metaData = rs.getMetaData();

int columnCount = metaData.getColumnCount();

for (int i = 0; i 

sql.append("`")

.append(metaData.getColumnName(i + 1))

.append("`, ");

}

sql.deleteCharAt(sql.length() - 1).deleteCharAt(sql.length() - 1).append(") VALUES \n");

rs.beforeFirst();

while (rs.next()) {

sql.append("(");

for (int i = 0; i 

int columnType = metaData.getColumnType(i + 1);

int columnIndex = i + 1;

if (Objects.isNull(rs.getObject(columnIndex))) {

sql.append("").append(rs.getObject(columnIndex)).append(", ");

} else if (columnType == Types.INTEGER || columnType == Types.TINYINT || columnType == Types.BIT) {

sql.append(rs.getInt(columnIndex)).append(", ");

} else {

String val = rs.getString(columnIndex);

val = val.replace("'", "\\'");

sql.append("'").append(val).append("', ");

}

}

sql.deleteCharAt(sql.length() - 1).deleteCharAt(sql.length() - 1);

if (rs.isLast()) {

sql.append(")");

} else {

sql.append("),\n");

}

}

sql.append(";");

sql.append("\n--\n")

.append(MysqlUtil.SQL_END_PATTERN).append(" table insert : ").append(table)

.append("\n--\n");

//enable FK constraint

sql.append("\n/*!40000 ALTER TABLE `").append(table).append("` ENABLE KEYS */;\n");

return sql.toString();

}

/**

* 导出所有表的结构和数据

*

* @return String

* @throws SQLException exception

*/

private String exportToSql() throws SQLException {

StringBuilder sql = new StringBuilder();

sql.append("--");

sql.append("\n-- Generated by workbgm");

sql.append("\n-- Date: ").append(new SimpleDateFormat("d-M-Y H:m:s").format(new Date()));

sql.append("\n--");

//these declarations are extracted from HeidiSQL

sql.append("\n\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;")

.append("\n/*!40101 SET NAMES utf8 */;")

.append("\n/*!50503 SET NAMES utf8mb4 */;")

.append("\n/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;")

.append("\n/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;");

List tables = MysqlUtil.getAllTables(database, stmt);

for (String s : tables) {

try {

sql.append(getTableInsertStatement(s.trim()));

sql.append(getDataInsertStatement(s.trim()));

} catch (SQLException e) {

e.printStackTrace();

}

}

sql.append("\n/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;")

.append("\n/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;")

.append("\n/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;");

this.generatedSql = sql.toString();

return sql.toString();

}

/**

* 从jdbcUrl中提取数据库名

*

* @param jdbcUrl

* @return

*/

public String findDBName(String jdbcUrl) {

String dbName = "";

int s = jdbcUrl.lastIndexOf("/") + 1;

int e = jdbcUrl.lastIndexOf("?");

dbName = jdbcUrl.substring(s, e);

return dbName;

}

/**

* 导出入口

*

* @throws IOException            exception

* @throws SQLException           exception

* @throws ClassNotFoundException exception

*/

public void export() throws IOException, SQLException, ClassNotFoundException {

//connect to the database

database = findDBName(this.mySqlInfo.getJdbcUrl());

String driverName = "";

Connection connection;

connection = MysqlUtil.connectWithURL(this.mySqlInfo.getUser(),

this.mySqlInfo.getPassword(), this.mySqlInfo.getJdbcUrl(),

driverName

);

stmt = connection.createStatement();

//generate the final SQL

String sql = exportToSql();

//create a temp dir to store the exported file for processing

String dirName = this.mySqlInfo.getExportPath();

File file = new File(dirName);

if (!file.exists()) {

boolean res = file.mkdir();

if (!res) {

System.out.println("Unable to create temp dir: " + file.getAbsolutePath());

throw new IOException("Unable to create temp dir: " + file.getAbsolutePath());

}

}

//write the sql file out

File sqlFolder = new File(dirName + "/sql");

if (!sqlFolder.exists()) {

boolean res = sqlFolder.mkdir();

if (!res) {

throw new IOException(": Unable to create temp dir: " + file.getAbsolutePath());

}

}

sqlFileName = getSqlFilename();

FileOutputStream outputStream = new FileOutputStream(sqlFolder + "/" + sqlFileName);

outputStream.write(sql.getBytes());

outputStream.close();

//zip the file

zipFileName = dirName + "/" + sqlFileName.replace(".sql", ".zip");

generatedZipFile = new File(zipFileName);

ZipUtil.pack(sqlFolder, generatedZipFile);

//clear the generated temp files

clearTempFiles(true);

}

/**

* 清理临时文件

*

* @param preserveZipFile bool

*/

public void clearTempFiles(boolean preserveZipFile) {

String dirName = this.mySqlInfo.getExportPath();

//delete the temp sql file

File sqlFile = new File(dirName + "/sql/" + sqlFileName);

if (sqlFile.exists()) {

boolean res = sqlFile.delete();

System.out.println(": " + sqlFile.getAbsolutePath() + " deleted successfully? " + (res ? " TRUE " : " FALSE "));

} else {

System.out.println(": " + sqlFile.getAbsolutePath() + " DOES NOT EXIST while clearing Temp Files");

}

File sqlFolder = new File(dirName + "/sql");

if (sqlFolder.exists()) {

boolean res = sqlFolder.delete();

System.out.println(": " + sqlFolder.getAbsolutePath() + " deleted successfully? " + (res ? " TRUE " : " FALSE "));

} else {

System.out.println(": " + sqlFolder.getAbsolutePath() + " DOES NOT EXIST while clearing Temp Files");

}

if (!preserveZipFile) {

//delete the zipFile

File zipFile = new File(zipFileName);

if (zipFile.exists()) {

boolean res = zipFile.delete();

System.out.println(": " + zipFile.getAbsolutePath() + " deleted successfully? " + (res ? " TRUE " : " FALSE "));

} else {

System.out.println(": " + zipFile.getAbsolutePath() + " DOES NOT EXIST while clearing Temp Files");

}

//delete the temp folder

File folder = new File(dirName);

if (folder.exists()) {

boolean res = folder.delete();

System.out.println(": " + folder.getAbsolutePath() + " deleted successfully? " + (res ? " TRUE " : " FALSE "));

} else {

System.out.println(": " + folder.getAbsolutePath() + " DOES NOT EXIST while clearing Temp Files");

}

}

System.out.println(": generated temp files cleared successfully");

}

/**

* 生成文件名

* sql file name.

*

* @return String

*/

public String getSqlFilename() {

return new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss").format(new Date()) + "_" + database + "_database_dump.sql";

}

/**

* 获取备份的sql zip文件

*

* @return

*/

public File getGeneratedZipFile() {

if (generatedZipFile != null && generatedZipFile.exists()) {

return generatedZipFile;

}

return null;

}

}

需要注意的是MysqlExport依赖一个zip打包类ZipUtil和mysql工具类MysqlUtil.

MysqlUtil的代码:import java.sql.*;

import java.util.ArrayList;

import java.util.List;

import java.util.Objects;

public class MysqlUtil {

static final String SQL_START_PATTERN = "-- start";

static final String SQL_END_PATTERN = "-- end";

/**

* 通过jdbcurl连接数据库

* @param username database username

* @param password database password

* @param jdbcURL the user supplied JDBC URL. It's used as is. So ensure you supply the right parameters

* @param driverName the user supplied mysql connector driver class name

* @return Connection

* @throws ClassNotFoundException exception

* @throws SQLException exception

*/

static Connection connectWithURL(String username, String password, String jdbcURL, String driverName) throws ClassNotFoundException, SQLException {

String driver = (Objects.isNull(driverName) || driverName.isEmpty()) ? "com.mysql.jdbc.Driver" : driverName;

return doConnect(driver, jdbcURL, username, password);

}

/**

* 连接数据库

* @param driver the class name for the mysql driver to use

* @param url the url of the database

* @param username database username

* @param password database password

* @return Connection

* @throws SQLException exception

* @throws ClassNotFoundException exception

*/

private static Connection doConnect(String driver, String url, String username, String password) throws SQLException, ClassNotFoundException {

Class.forName(driver);

Connection connection = DriverManager.getConnection(url, username, password);

System.out.println("DB Connected Successfully");

return  connection;

}

/**

* 获取所有表

* @param database the database name

* @param stmt Statement object

* @return List\

* @throws SQLException exception

*/

static List getAllTables(String database, Statement stmt) throws SQLException {

List table = new ArrayList<>();

ResultSet rs;

rs = stmt.executeQuery("SHOW TABLE STATUS FROM `" + database + "`;");

while ( rs.next() ) {

table.add(rs.getString("Name"));

}

return table;

}

}

ZipUtil需要用maven引入一下:

org.zeroturnaround

zt-zip

1.12

jar

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值