用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 存储方式 ...
随机推荐
- FreeRTOS-05-队列
说明 本文仅作为学习FreeRTOS的记录文档,作为初学者肯定很多理解不对甚至错误的地方,望网友指正. FreeRTOS是一个RTOS(实时操作系统)系统,支持抢占式.合作式和时间片调度.适用于微处理 ...
- 拦截器HandlerInterceptorAdapter的postHandle和afterCompletion无法获取response返回值问题
缘起 有一个需求,在进入controller之前验证调用次数是否超过限制,在响应之后判断是否正常返回,对调用次数进行+1,发现带@RestController的类和带@ResponseBody的方法在 ...
- Asp.Net Core 导入Excel数据到Sqlite数据库并重新导出到Excel
Asp.Net Core 导入Excel数据到Sqlite数据库并重新导出到Excel 在博文"在Asp.Net Core 使用 Sqlite 数据库"中创建了ASP.NET Co ...
- Pikachu-暴力破解模块
一.概述 "暴力破解"是一攻击具手段,在web攻击中,一般会使用这种手段对应用系统的认证信息进行获取. 其过程就是使用大量的认证信息在认证接口进行尝试登录,直到得到正确的结果. 为 ...
- 在java程序中使用protobuf
目录 简介 为什么使用protobuf 定义.proto文件 编译协议文件 详解生成的文件 Builders 和 Messages 序列化和反序列化 协议扩展 总结 简介 Protocol Buffe ...
- .net core 通过动软连接数据库
.net core 与动软 首先创建asp.net core 或者 .net core 控制台程序.不需急着创建web.config 文件. 通过NuGet加个ado的包 System.Data.Sq ...
- idea的properties文件乱码问题解决
设置编码格式: File============>Settings,打开设置后,设置成下面的即可解决:
- webpack编译遇到的问题:Error: Cannot find module 'webpack-cli/bin/config-yargs'
运行npm run dev遇到的问题:Error: Cannot find module 'webpack-cli/bin/config-yargs' // 当前package.json 文件 & ...
- MySQL主从复制与Atlas读写分离
配置主从复制 1. 增加主从配置 # 主库配置文件 server-id = 1 log-bin = /var/lib/mysql/mysql-bin expire_logs_days = 10 ski ...
- flutter学习资料汇总
1.https://github.com/chinabrant/flutter_study 2.https://github.com/zhujian1989/flutter_study 3.https ...