用Java写了一个程序,将一个Mysql库中的表,迁移到另外一个server上的Mysql库中
用Navicat做数据迁移,因为数据量比较大,迁移过过程中一个是进展不直观,另外就是cpu占用率高的时候,屏幕跟死机了一样点不动按钮,不好中断。
想了想,干脆自己写一个。
在网上找了一个sqllite迁移mysql数据的基础代码,然后在这基础上做了修改。
1、用这一个程序就能搞定指定数据库表的数据迁移执行工作。
2、目前每次可以执行指定的数据库表数组,但是不能仅仅单独指定库迁移所有表。
3、对于超大表的读取和数据迁移做了优化,每次读取1000条数据,每次迁移1000条数据。
4、整这代码的时间就两个小时左右,所以观赏性不佳,能执行数据迁移就ok。
5、支持mysql中中文数据的迁移,mysql库要求用utf-8编码。
6、如果迁移的表存在,则会先把表删除,然后重建对应的表。
还有很多不足,敬请包涵。
1 package com.alex;
2
3 import java.sql.Connection;
4 import java.sql.DriverManager;
5 import java.sql.PreparedStatement;
6 import java.sql.ResultSet;
7 import java.sql.SQLException;
8 import java.sql.Statement;
9
10
11
12 public class TransDbData {
13 //author 8482322@qq.com
14 private Connection connSource=null;
15 private Connection connDest=null;
16
17 ///transTables=要传输的数据表名字的数组,如果是多个表,则完善此数组即可
18 public static String[] transTables={"table-1","talbe-2","table-3"};
19 private static int curLine=0;
20
21 public static void main(String[] args) {
22 TransDbData test = new TransDbData();
23 int k=0;
24 int tableLineCount=0;
25 int offset=1000;
26 int start=0;
27 int loopTimes=0;
28 try {
29 for(int i=0;i<transTables.length;i++) {
30 test.createDestTable(transTables[i]);
31 tableLineCount=test.getTableLineCount(transTables[i]);
32 int xx=tableLineCount%1000;
33 loopTimes=(int) Math.ceil(tableLineCount/offset);
34 for(int loopN=0;loopN<loopTimes;loopN++) {
35 curLine++;
36 System.out.println("正在处理第"+curLine+"批(每批数据1000条)数据");
37 test.deal(transTables[i],tableLineCount,loopN,offset);
38 }
39 }
40 } catch (SQLException e) {
41 e.printStackTrace();
42 }
43 }
44
45
46
47 private Connection getSourceConn(){
48 try {
49 Class.forName("com.mysql.jdbc.Driver");
50 String connStr="jdbc:mysql://mysql-server-数据源-ip:3306/yourdb?useSSL=false&Charset=utf8&characterEncoding=utf-8";
51 connSource = DriverManager.getConnection(connStr,"root","abcdef");
52 if(connSource!=null) {
53 System.out.println("源数据库连上了"+connStr);
54
55 }
56 return connSource;
57 } catch (ClassNotFoundException | SQLException e) {
58 e.printStackTrace();
59 }
60 return null;
61 }
62
63 private Connection getDestConn(){
64 try {
65 Class.forName("com.mysql.jdbc.Driver");
66 String connStr="jdbc:mysql://mysql-server-目标库-ip:3306/your-db?useSSL=false&Charset=utf8&characterEncoding=utf-8";
67 connDest = DriverManager.getConnection(connStr,"root","123456");
68 if(connDest!=null) {
69 System.out.println("目标数据库连上了"+connStr);
70 }
71 return connDest;
72 } catch (ClassNotFoundException | SQLException e) {
73 e.printStackTrace();
74 }
75 return null;
76 }
77
78 /**
79 * 获得表的数据总量
80 * @param transTableName
81 * @return
82 */
83 public int getTableLineCount(String transTableName) {
84 Connection srcConn = this.getSourceConn();
85 Statement srcStmt;
86 int count=0;
87 try {
88 srcStmt = srcConn.createStatement();
89 ResultSet srcRsCount = srcStmt.executeQuery("select count(*) from "+ transTableName);
90 while(srcRsCount.next()) {
91 count=srcRsCount.getInt(1);
92 System.out.println("一共有["+srcRsCount.getInt(1)+"]条数据要传输");
93 }
94 srcRsCount.close();
95 srcStmt.close();
96 srcConn.close();
97 } catch (SQLException e) {
98 e.printStackTrace();
99 }
100 return count;
101 }
102
103
104 /**
105 *
106 * @param transTableName 被传输的数据库表名称
107 * @throws SQLException
108 */
109 public void deal(String transTableName,int tableLineCount,int loopN,int offset) throws SQLException {
110 //数据源数据库
111 Connection srcConn = this.getSourceConn();
112 Statement srcStmt =srcConn.createStatement();
113
114 int startPosition = loopN*offset +1;
115 ResultSet srcRs = srcStmt.executeQuery("select * from "+ transTableName +" limit "+startPosition+" ,"+offset+" ");
116 //结果集获取到的长度
117 int size = srcRs.getMetaData().getColumnCount();
118 //比较懒,拼接insert into 语句
119 StringBuffer sbf =new StringBuffer();
120 sbf.append("insert into "+transTableName+" values (");
121 String link ="";
122 for (int i = 0; i <size ; i++) {
123 sbf.append(link).append("?");
124 link=",";
125 }
126 sbf.append(")");
127 //MySQL数据库
128 Connection destconn = getDestConn();
129 PreparedStatement destPstmt = destconn.prepareStatement(sbf.toString());
130 //System.out.println(sbf.toString());
131 //取出结果集并向MySQL数据库插入数据 ( 使用批处理 )
132 //完成条数
133 int count =0;
134 int num=0;
135 //取消事务(不写入日志)
136 destconn.setAutoCommit(false);
137 long start = System.currentTimeMillis();
138 //循环原表,从原表中读取数据
139 while (srcRs.next()) {
140 ++count;
141 System.out.print(".");
142 //System.out.println("读取第"+count+"条数据");
143 for (int i=1;i<= size;i++) {
144 destPstmt.setObject(i, srcRs.getObject(i));
145 }
146
147 //将预先语句存储起来,这里还没有向数据库插入
148 destPstmt.addBatch();
149 //当count 到达 20000条时 向数据库提交
150 if (count % 20000 ==0 ){
151 ++num;
152 destPstmt.executeBatch();
153 System.out.println("表【"+transTableName+"】数据传输第"+num+"次提交,耗时:"+(System.currentTimeMillis()-start)/1000.0+"s");
154 }
155 }
156 //防止有数据未提交
157 destPstmt.executeBatch();
158 //提交
159 destconn.commit();
160 System.out.println("本次完成【"+count+"】条数据,耗时:"+(System.currentTimeMillis()-start)/1000.0+"s");
161 //恢复事务
162 // mysqlconn.setAutoCommit(true);
163
164 //关闭资源
165 close(destconn,destPstmt,null);
166 close(srcConn,srcStmt,srcRs);
167
168 }
169
170
171 /**
172 * 根据源表名,在目的库中创建对应表
173 * @param srcTableName
174 */
175 public void createDestTable(String srcTableName) {
176 String tableName = srcTableName;
177 Connection src_conn = this.getSourceConn();
178 Connection dest_conn= this.getDestConn();
179 String sql = String.format("SHOW CREATE TABLE %s", tableName);//查询sql
180 //String sql = "SHOW CREATE TABLE ?";
181 PreparedStatement ps = null;
182 PreparedStatement ps_dest = null;
183 String dropTable="drop table "+srcTableName;
184 try {
185 System.out.println("如果表存在,先删除:"+srcTableName);
186 ps_dest=dest_conn.prepareStatement(dropTable);
187 ps_dest.execute();
188 ps_dest.close();
189 System.out.println("删除成功:"+srcTableName);
190
191 } catch (SQLException e1) {
192 System.err.println(e1.getMessage());
193 System.out.println("表原先不存在:"+srcTableName);
194
195 }
196
197 try {
198
199 ps = src_conn.prepareStatement(sql);
200 //ps.setString(1, tableName);
201 ResultSet resultSet = ps.executeQuery();
202 while (resultSet.next()) {
203 //System.out.println(resultSet.getString(1));//第一个参数获取的是tableName
204 String destTableName=resultSet.getString(1);
205 // System.out.println(resultSet.getString(2));//第二个参数获取的是表的ddl语句
206 String ddl=resultSet.getString(2);
207 ps_dest = dest_conn.prepareStatement(ddl);
208 ps_dest.execute();
209 System.out.println("目标库中创建表成功:" +destTableName);
210 ps_dest.close();
211
212 }
213 } catch (SQLException e) {
214 e.printStackTrace();
215 } finally {
216 if(null != ps){
217 try {
218 ps.close();
219 } catch (SQLException e) {
220 e.printStackTrace();
221 }
222 }
223 if(null != ps_dest){
224 try {
225 ps_dest.close();
226 } catch (SQLException e) {
227 e.printStackTrace();
228 }
229 }
230 if(null != src_conn) {
231 try {
232 src_conn.close();
233 } catch (SQLException e) {
234 e.printStackTrace();
235 }
236 }
237 if(null != dest_conn) {
238 try {
239 dest_conn.close();
240 } catch (SQLException e) {
241 e.printStackTrace();
242 }
243 }
244 }
245
246 }
247
248 //关闭数据库连接
249 public void close(Connection conn,Statement stmt,ResultSet rs){
250
251 if(rs!=null){
252 try {
253 rs.close();
254 } catch (SQLException e) {
255 e.printStackTrace();
256 }
257 }
258 if(stmt!=null){
259 try {
260 stmt.close();
261 } catch (SQLException e) {
262 e.printStackTrace();
263 }
264 }
265 if(conn!=null){
266 try {
267 conn.close();
268 } catch (SQLException e) {
269 e.printStackTrace();
270 }
271 }
272 }
273
274 }
执行过程中的日志输入:
用Java写了一个程序,将一个Mysql库中的表,迁移到另外一个server上的Mysql库中的更多相关文章
- 如何远程连接Windows server上的MySQL服务
废话不多说,直接开干 首先要打开服务器的MySQL端口号:3306(当然,也可以把服务器的防火墙直接关闭,不过不安全) 1.打开服务器管理器,有个高级安全Windows防火墙,下面有一个入站规则, 右 ...
- (转)SqlServer将数据库中的表复制到另一个数据库
本文为转载地址为:http://jingyan.baidu.com/article/d5c4b52bc5c102da570dc547.html 复制表结构 在使用SqlServer的过程中,我们可能需 ...
- SqlServer将数据库中的表复制到另一个数据库
前述: 文章来自百度经验 操作: 在使用SqlServer的过程中,我们可能需要将表从一个数据库复制到另一个数据库中,今天,为大家介绍这种操作的具体方法及步骤. 复制表结构 1 首先,打开并连接Sql ...
- DB迁移:从SQL Server 2005到MySQL
一.工具选择 依工作需要进行老产品升级,其中一项重要工作就是将SQL Server数据库改为MySQL数据库,故而在对<各种主流 SQLServer 迁移到 MySQL 工具对比>文章学习 ...
- mysql Client does not support authentication protocol requested by server; consider upgrading MySQL
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
- Java对比两个数据库中的表和字段,写个冷门的东西
Java对比两个数据库中的表和字段,写个冷门的东西 转载的 来源网络 目前所在的项目组距离下个版本上线已经很近了,就面临了一个问题:开发人员在开发库上根据需要增加数据表.数据字段.或者变更了字段类型或 ...
- python应用(2):写个python程序给自己用
用python写一个程序,然后在命令行上执行,看不到界面(UI),这种程序很常见了,叫命令行程序.然而很多人,特别是不懂程序的人,更需要看到的是一个有界面的,能通过鼠标操作的程序,毕竟已经迈进&quo ...
- Windows Server 2008R2配置MySQL Cluster
目录 配置环境 相关知识 配置过程 配置 ini参数解释 启动集群 检查配置 同步测试 故障测试 写在之后 配置环境 VMware:(版本10.0.01) 操作系统:Windows Server 20 ...
- MySql(一)表类型(存储引擎)
MySql(一)表类型(存储引擎) 一.MYSQL存储引擎概述 二.存储引擎的特性对比 2.1 MyISAM 2.2 InnoDB 2.2.1 自动增长列 2.2.2 外键约束 2.2.3 存储方式 ...
随机推荐
- MySQL 索引使用案例
索引使用案例 支持多种过滤条件 假设要设计一个在线约会网站,用户信息表有很多列,包括国家.地区.城市.性别.眼睛颜色,等等.网站必须支持上面这些特征的各种组合来搜索用户,还必须允许根据用户的最后在线时 ...
- SpringBoot报错:Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
Spring Boot报错:Error starting ApplicationContext. To display the conditions report re-run your applic ...
- 【笔记】多项式回归的思想以及在sklearn中使用多项式回归和pipeline
多项式回归以及在sklearn中使用多项式回归和pipeline 多项式回归 线性回归法有一个很大的局限性,就是假设数据背后是存在线性关系的,但是实际上,具有线性关系的数据集是相对来说比较少的,更多时 ...
- 【Vulnhub】DC-1靶机
一.信息收集 1.1 环境 kali : 192.168.124.141 DC-1 : 192.168.124.150 1.2 nmap进行扫描 :nmap -sV 192.168.124.150 I ...
- 2、二进制安装K8s 之 部署ETCD集群
二进制安装K8s 之 部署ETCD集群 一.下载安装cfssl,用于k8s证书签名 二进制包地址:https://pkg.cfssl.org/ 所需软件包: cfssl 1.6.0 cfssljson ...
- 使用VC6.0开发COM组件 - 傻瓜式,不讲理论,只讲实例
1.创建一个ATL COM AppWizard工程,如图:
- 【springboot】集成Druid 作为数据库连接池
转自:https://blog.csdn.net/cp026la/article/details/86508139 1. 引言 用户的每一次请求几乎都会访问数据库,访问数据库需要向数据库获取链接,而数 ...
- Java Web基础 --- Servlet 综述(理论篇)
摘要: Web 技术成为当今主流的互联网 Web 应用技术之一,而 Servlet 是 Java Web 技术的核心基础.本文首先从请求/响应架构应用的大背景谈起 Servlet 的由来,明确 Ser ...
- 通过location响应头实现重定向
package day08; import java.io.IOException; import javax.servlet.ServletException; import javax.servl ...
- Python - 面向对象编程 - 类变量、实例变量/类属性、实例属性
什么是对象和类 https://www.cnblogs.com/poloyy/p/15178423.html 什么是 Python 类.类对象.实例对象 https://www.cnblogs.com ...