java生成mysql数据库建表语句、字段、字段类型、字段注释,可实现不用mysqldump备份数据库

举报
IT 叶新东老师 发表于 2021/12/30 00:25:13 2021/12/30
【摘要】 使用 mysqldump 备份数据库也是可行的,因为每次备份的时候都需要mysqldump这个文件, 我在windows备份时没问题,但是放到linux上面时,centos系统死活不认这个文件,但又不想装mysql,一气之下自己研究了个不需要mysqldump就可以备份的程序, 如果看了以下代码还有不懂的地方,这个网站有我的联系方式h...

使用 mysqldump 备份数据库也是可行的,因为每次备份的时候都需要mysqldump这个文件, 我在windows备份时没问题,但是放到linux上面时,centos系统死活不认这个文件,但又不想装mysql,一气之下自己研究了个不需要mysqldump就可以备份的程序,

如果看了以下代码还有不懂的地方,这个网站有我的联系方式http://www.huashuku.top/about.htm, 站长就是我本人

废话不多说,直接上代码

添加jdbc驱动 和httpClient的 maven依赖


  
  1. <dependency>
  2. <groupId>org.apache.httpcomponents</groupId>
  3. <artifactId>httpclient</artifactId>
  4. <version>4.1.2</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.httpcomponents</groupId>
  8. <artifactId>httpclient-cache</artifactId>
  9. <version>4.1.2</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.apache.httpcomponents</groupId>
  13. <artifactId>httpmime</artifactId>
  14. <version>4.1.2</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>mysql</groupId>
  18. <artifactId>mysql-connector-java</artifactId>
  19. <version>5.1.15</version>
  20. <scope>runtime</scope>
  21. </dependency>

备份程序


  
  1. package com.mysql.bak;
  2. import java.math.BigDecimal;
  3. import java.sql.Connection;
  4. import java.sql.DatabaseMetaData;
  5. import java.sql.DriverManager;
  6. import java.sql.PreparedStatement;
  7. import java.sql.ResultSet;
  8. import java.sql.ResultSetMetaData;
  9. import java.sql.SQLException;
  10. import java.text.SimpleDateFormat;
  11. import java.util.ArrayList;
  12. import java.util.List;
  13. import com.utils.FileUtils;
  14. /**
  15. * 利用jdbc备份mysql数据库--不用mysqldump
  16. *
  17. */
  18. public class BakDateBase {
  19. private String DRIVER = "com.mysql.jdbc.Driver";
  20. private String URL = null; // "jdbc:mysql://182.xxx.xxx.xxx:3306/xd_love_dev?useUnicode=true&characterEncoding=utf8";
  21. private String USERNAME = null;// "root";
  22. private String PASSWORD = null;//"woaini";
  23. // 备份的文件地址
  24. private String filePath;
  25. private Connection conn = null;
  26. private String SQL = "SELECT * FROM ";// 数据库操作
  27. /**
  28. *
  29. * <构造函数>
  30. *
  31. * @param ip
  32. * 数据库ip地址
  33. * @param database
  34. * 数据库名称
  35. * @param userName
  36. * 数据库用户名
  37. * @param password
  38. * 密码
  39. * @param bakFilePath
  40. * 备份的地址
  41. */
  42. public BakDateBase(String ip, String database, String userName, String password, String bakFilePath) {
  43. try {
  44. Class.forName(this.DRIVER);
  45. this.URL = String.format("jdbc:mysql://%s:3306/%s?useUnicode=true&characterEncoding=utf8", ip, database);
  46. this.USERNAME = userName;
  47. this.PASSWORD = password;
  48. SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-ddHH时mm分ss秒");
  49. String datetime = tempDate.format(new java.util.Date());
  50. //自动加上时间戳
  51. datetime = datetime + "_数据库名称:" + database ;
  52. if(bakFilePath.indexOf(".") != -1) {
  53. bakFilePath = bakFilePath.replace(".", datetime+".");
  54. } else {
  55. bakFilePath = datetime + ".sql";
  56. }
  57. this.filePath = bakFilePath;
  58. } catch (ClassNotFoundException e) {
  59. e.printStackTrace();
  60. System.err.println("can not load jdbc driver");
  61. }
  62. }
  63. /**
  64. * 获取数据库连接
  65. *
  66. * @return
  67. */
  68. private Connection getConnection() {
  69. try {
  70. if (null == conn) {
  71. conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
  72. }
  73. } catch (SQLException e) {
  74. e.printStackTrace();
  75. System.err.println("get connection failure");
  76. }
  77. return conn;
  78. }
  79. /**
  80. * 关闭数据库连接
  81. *
  82. * @param conn
  83. */
  84. private void closeConnection(Connection conn) {
  85. if (conn != null) {
  86. try {
  87. conn.close();
  88. } catch (SQLException e) {
  89. e.printStackTrace();
  90. System.err.println("close connection failure");
  91. }
  92. }
  93. }
  94. /**
  95. * 获取数据库下的所有表名
  96. */
  97. private List<String> getTableNames() {
  98. List<String> tableNames = new ArrayList<String>();
  99. Connection conn = getConnection();
  100. ResultSet rs = null;
  101. try {
  102. // 获取数据库的元数据
  103. DatabaseMetaData db = conn.getMetaData();
  104. // 从元数据中获取到所有的表名
  105. rs = db.getTables(null, null, null, new String[] { "TABLE" });
  106. while (rs.next()) {
  107. tableNames.add(rs.getString(3));
  108. }
  109. } catch (SQLException e) {
  110. e.printStackTrace();
  111. System.err.println("getTableNames failure");
  112. } finally {
  113. try {
  114. if (null != rs) {
  115. rs.close();
  116. }
  117. } catch (SQLException e) {
  118. e.printStackTrace();
  119. System.err.println("close ResultSet failure");
  120. }
  121. }
  122. return tableNames;
  123. }
  124. /**
  125. * 获取表中所有字段名称
  126. *
  127. * @param tableName
  128. * 表名
  129. * @return
  130. */
  131. private List<String> getColumnNames(String tableName) {
  132. List<String> columnNames = new ArrayList<String>();
  133. // 与数据库的连接
  134. Connection conn = getConnection();
  135. PreparedStatement pStemt = null;
  136. String tableSql = SQL + tableName;
  137. try {
  138. pStemt = conn.prepareStatement(tableSql);
  139. // 结果集元数据
  140. ResultSetMetaData rsmd = pStemt.getMetaData();
  141. // 表列数
  142. int size = rsmd.getColumnCount();
  143. for (int i = 0; i < size; i++) {
  144. columnNames.add(rsmd.getColumnName(i + 1));
  145. }
  146. } catch (SQLException e) {
  147. System.err.println("getColumnNames failure");
  148. e.printStackTrace();
  149. } finally {
  150. if (pStemt != null) {
  151. try {
  152. pStemt.close();
  153. } catch (SQLException e) {
  154. e.printStackTrace();
  155. System.err.println("getColumnNames close pstem and connection failure");
  156. }
  157. }
  158. }
  159. return columnNames;
  160. }
  161. /**
  162. * 获取表中所有字段类型
  163. *
  164. * @param tableName
  165. * @return
  166. */
  167. private List<String> getColumnTypes(String tableName) {
  168. List<String> columnTypes = new ArrayList<String>();
  169. // 与数据库的连接
  170. Connection conn = getConnection();
  171. PreparedStatement pStemt = null;
  172. String tableSql = SQL + tableName;
  173. try {
  174. pStemt = conn.prepareStatement(tableSql);
  175. // 结果集元数据
  176. ResultSetMetaData rsmd = pStemt.getMetaData();
  177. // 表列数
  178. int size = rsmd.getColumnCount();
  179. for (int i = 0; i < size; i++) {
  180. columnTypes.add(rsmd.getColumnTypeName(i + 1));
  181. }
  182. } catch (SQLException e) {
  183. e.printStackTrace();
  184. System.err.println("getColumnTypes failure");
  185. } finally {
  186. if (pStemt != null) {
  187. try {
  188. pStemt.close();
  189. } catch (SQLException e) {
  190. e.printStackTrace();
  191. System.err.println("getColumnTypes close pstem and connection failure");
  192. }
  193. }
  194. }
  195. return columnTypes;
  196. }
  197. /**
  198. *
  199. * <p>
  200. * 生成建表语句
  201. * </p>
  202. *
  203. * @param tableName
  204. * @return
  205. * @author 叶新东(18126064335) 2018年9月6日 上午9:35:49
  206. */
  207. private String generateCreateTableSql(String tableName) {
  208. String sql = String.format("SHOW CREATE TABLE %s", tableName);
  209. Connection conn = null;
  210. PreparedStatement pstmt = null;
  211. try {
  212. conn = getConnection();
  213. pstmt = (PreparedStatement) conn.prepareStatement(sql);
  214. ResultSet rs = pstmt.executeQuery();
  215. while (rs.next()) {
  216. // 返回建表语句语句,查询结果的第二列是建表语句,第一列是表名
  217. return rs.getString(2);
  218. }
  219. } catch (Exception e) {
  220. e.printStackTrace();
  221. try {
  222. if (null != pstmt) {
  223. pstmt.close();
  224. }
  225. } catch (Exception e2) {
  226. e.printStackTrace();
  227. System.err.println("关闭流异常");
  228. }
  229. }
  230. return null;
  231. }
  232. /**
  233. * 获取表中字段的所有注释
  234. *
  235. * @param tableName
  236. * @return
  237. */
  238. private List<String> getColumnComments(String tableName) {
  239. // 与数据库的连接
  240. Connection conn = getConnection();
  241. PreparedStatement pStemt = null;
  242. String tableSql = SQL + tableName;
  243. List<String> columnComments = new ArrayList<String>();// 列名注释集合
  244. ResultSet rs = null;
  245. try {
  246. pStemt = conn.prepareStatement(tableSql);
  247. rs = pStemt.executeQuery("show full columns from " + tableName);
  248. while (rs.next()) {
  249. columnComments.add(rs.getString("Comment"));
  250. }
  251. } catch (SQLException e) {
  252. e.printStackTrace();
  253. } finally {
  254. if (rs != null) {
  255. try {
  256. rs.close();
  257. } catch (SQLException e) {
  258. e.printStackTrace();
  259. System.err.println("getColumnComments close ResultSet and connection failure");
  260. }
  261. }
  262. }
  263. return columnComments;
  264. }
  265. /**
  266. *
  267. * <p>
  268. * 备份表数据
  269. * </p>
  270. *
  271. * @param tableName
  272. * @return
  273. * @author () 2018年9月6日 上午10:18:07
  274. */
  275. private String bakTableData(String tableName) {
  276. Connection conn = null;
  277. PreparedStatement pstmt = null;
  278. try {
  279. // 备份建表语句
  280. String createTableSql = generateCreateTableSql(tableName);
  281. createTableSql = String.format(
  282. "\n\n\n/**\n * table name :<%s>\n *\n */\n%s\n",
  283. tableName, createTableSql);
  284. FileUtils.writeFileContent(filePath, createTableSql);
  285. // 获取字段类型
  286. List<String> columnTypes = getColumnTypes(tableName);
  287. // 获取所有 字段
  288. List<String> columnNames = getColumnNames(tableName);
  289. String columnArrayStr = null;
  290. for (String column : columnNames) {
  291. if (null == columnArrayStr) {
  292. columnArrayStr = "`" + column + "`";
  293. } else {
  294. columnArrayStr = columnArrayStr + "," + "`" + column + "`";
  295. }
  296. }
  297. String sql = String.format("select %s from %s", columnArrayStr, tableName);
  298. conn = getConnection();
  299. pstmt = (PreparedStatement) conn.prepareStatement(sql);
  300. ResultSet rs = pstmt.executeQuery();
  301. while (rs.next()) {
  302. String rowValues = getRowValues(rs, columnNames.size(), columnTypes);
  303. // 返回建表语句语句,查询结果的第二列是建表语句,第一列是表名
  304. String insertSql = String.format("insert into %s (%s) values(%s);", tableName, columnArrayStr,
  305. rowValues);
  306. System.out.println(insertSql);
  307. insertSql = insertSql.replaceAll("\n", "<br/>");
  308. insertSql = insertSql + "\n";
  309. FileUtils.writeFileContent(filePath, insertSql);
  310. }
  311. } catch (Exception e) {
  312. e.printStackTrace();
  313. try {
  314. if (null != pstmt) {
  315. pstmt.close();
  316. }
  317. } catch (Exception e2) {
  318. e.printStackTrace();
  319. System.err.println("关闭流异常");
  320. }
  321. }
  322. return null;
  323. }
  324. /**
  325. *
  326. * <p>
  327. * 获取表数据一行的所有值
  328. * </p>
  329. *
  330. * @param rs
  331. * @param size
  332. * @author 2018年9月6日 上午11:03:05
  333. */
  334. private String getRowValues(ResultSet rs, int size, List<String> columnTypeList) {
  335. try {
  336. String rowValues = null;
  337. for (int i = 1; i <= size; i++) {
  338. String columnValue = null;
  339. // 获取字段值
  340. columnValue = getValue(rs, i, columnTypeList.get(i - 1));
  341. // 如果是空值不添加单引号
  342. if (null != columnValue) {
  343. columnValue = "'" + columnValue + "'";
  344. }
  345. // 拼接字段值
  346. if (null == rowValues) {
  347. rowValues = columnValue;
  348. } else {
  349. rowValues = rowValues + "," + columnValue;
  350. }
  351. }
  352. return rowValues;
  353. } catch (Exception e) {
  354. e.printStackTrace();
  355. System.out.println("获取表数据一行的所有值异常");
  356. return null;
  357. }
  358. }
  359. /**
  360. *
  361. * <p>
  362. * 根据类型获取字段值
  363. * </p>
  364. *
  365. * @param obj
  366. * @return
  367. * @author 2018年9月6日 上午11:16:00
  368. */
  369. private String getValue(ResultSet resultSet, Integer index, String columnType) {
  370. try {
  371. if ("int".equals(columnType) || "INT".equals(columnType)) {
  372. // 整数
  373. Object intValue = resultSet.getObject(index);
  374. if (null == intValue) {
  375. return null;
  376. }
  377. return intValue + "";
  378. } else if ("bigint".equals(columnType) || "BIGINT".equals(columnType)) {
  379. // 长整形
  380. Object value = resultSet.getObject(index);
  381. if (null == value) {
  382. return null;
  383. }
  384. return value + "";
  385. } else if ("smallint".equals(columnType) || "SMALLINT".equals(columnType)) {
  386. // 整数
  387. Object value = resultSet.getObject(index);
  388. if (null == value) {
  389. return null;
  390. }
  391. return value + "";
  392. } else if ("tinyint".equals(columnType) || "TINYINT".equals(columnType)) {
  393. // 整数
  394. Object value = resultSet.getObject(index);
  395. if (null == value) {
  396. return null;
  397. }
  398. return value + "";
  399. } else if ("mediumint".equals(columnType) || "MEDIUMINT".equals(columnType)) {
  400. // 长整形
  401. Object value = resultSet.getObject(index);
  402. if (null == value) {
  403. return null;
  404. }
  405. return value + "";
  406. } else if ("integer".equals(columnType) || "INTEGER".equals(columnType)) {
  407. // 整数
  408. Object value = resultSet.getObject(index);
  409. if (null == value) {
  410. return null;
  411. }
  412. return value + "";
  413. } else if ("float".equals(columnType) || "FLOAT".equals(columnType)) {
  414. // 浮点数
  415. Object value = resultSet.getObject(index);
  416. if (null == value) {
  417. return null;
  418. }
  419. return value + "";
  420. } else if ("double".equals(columnType) || "DOUBLE".equals(columnType)) {
  421. // 浮点数
  422. Object value = resultSet.getObject(index);
  423. if (null == value) {
  424. return null;
  425. }
  426. return value + "";
  427. } else if ("decimal".equals(columnType) || "DECIMAL".equals(columnType)) {
  428. // 浮点数-金额类型
  429. BigDecimal value = resultSet.getBigDecimal(index);
  430. if (null == value) {
  431. return null;
  432. }
  433. return value.toString();
  434. } else if ("char".equals(columnType) || "CHAR".equals(columnType)) {
  435. // 字符串类型
  436. String value = resultSet.getString(index);
  437. return value;
  438. } else if ("varchar".equals(columnType) || "VARCHAR".equals(columnType)) {
  439. // 字符串类型
  440. String value = resultSet.getString(index);
  441. return value;
  442. } else if ("tinytext".equals(columnType) || "TINYTEXT".equals(columnType)) {
  443. // 字符串类型
  444. String value = resultSet.getString(index);
  445. return value;
  446. } else if ("text".equals(columnType) || "TEXT".equals(columnType)) {
  447. // 字符串类型
  448. String value = resultSet.getString(index);
  449. return value;
  450. } else if ("mediumtext".equals(columnType) || "MEDIUMTEXT".equals(columnType)) {
  451. // 字符串类型
  452. String value = resultSet.getString(index);
  453. return value;
  454. } else if ("longtext".equals(columnType) || "LONGTEXT".equals(columnType)) {
  455. // 字符串类型
  456. String value = resultSet.getString(index);
  457. return value;
  458. } else if ("year".equals(columnType) || "YEAR".equals(columnType)) {
  459. // 时间类型:范围 1901/2155 格式 YYYY
  460. String year = resultSet.getString(index);
  461. if (null == year) {
  462. return null;
  463. }
  464. // 只需要年的字符即可,
  465. return year.substring(0, 4);
  466. } else if ("date".equals(columnType) || "DATE".equals(columnType)) {
  467. // 时间类型:范围 '1000-01-01'--'9999-12-31' 格式 YYYY-MM-DD
  468. return resultSet.getString(index);
  469. } else if ("time".equals(columnType) || "TIME".equals(columnType)) {
  470. // 时间类型:范围 '-838:59:59'到'838:59:59' 格式 HH:MM:SS
  471. return resultSet.getString(index);
  472. } else if ("datetime".equals(columnType) || "DATETIME".equals(columnType)) {
  473. // 时间类型:范围 '1000-01-01 00:00:00'--'9999-12-31 23:59:59' 格式 YYYY-MM-DD HH:MM:SS
  474. return resultSet.getString(index);
  475. } else if ("timestamp".equals(columnType) || "TIMESTAMP".equals(columnType)) {
  476. // 时间类型:范围 1970-01-01 00:00:00/2037 年某时 格式 YYYYMMDD HHMMSS 混合日期和时间值,时间戳
  477. return resultSet.getString(index);
  478. } else {
  479. return null;
  480. }
  481. } catch (Exception e) {
  482. e.printStackTrace();
  483. System.err.println("获取数据库类型值异常");
  484. return null;
  485. }
  486. }
  487. /**
  488. *
  489. * <开始备份>
  490. *
  491. * @author 2018年9月6日 下午3:30:43
  492. */
  493. public void startBak() {
  494. try {
  495. List<String> tableNames = getTableNames();
  496. System.out.println("tableNames:" + tableNames);
  497. for (String tableName : tableNames) {
  498. bakTableData(tableName);
  499. // System.out.println(generateCreateTableSql(tableName));
  500. // System.out.println("ColumnNames:" + getColumnNames(tableName));
  501. // System.out.println("ColumnTypes:" + getColumnTypes(tableName));
  502. // System.out.println("ColumnComments:" + getColumnComments(tableName));
  503. }
  504. // 统一关闭连接
  505. closeConnection(conn);
  506. } catch (Exception e) {
  507. e.printStackTrace();
  508. }
  509. }
  510. public static void main(String[] args) {
  511. new BakDateBase("182.xxx.xxx.xxx", "xd_love_dev", "root", "woaini", "f:\\bak.sql").startBak();
  512. }
  513. }

 

 

执行 main 方法后会在磁盘指定位置生成 .sql  的文件,内容如下:

文章来源: yexindong.blog.csdn.net,作者:java叶新东老师,版权归原作者所有,如需转载,请联系作者。

原文链接:yexindong.blog.csdn.net/article/details/82454997

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。