用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 存储方式 ...
随机推荐
- 2020年Android开发市场真的饱和了吗?
公司在杭州,根据我的不客观数据体验来看,最饱和的是iOS,同样发布一个职位iOS是其他技术岗位10倍的投递量. 当然Android作为一个已经市场化十余年的技术门类,它必然早已经是成熟常态.这样的技术 ...
- postman 常见异常问题的处理
1.postman一直转圈打不开的问题 一般这种问题是因为缓存过多,所以这里需要清理下缓存文件,即:删除%appdata%目录下的postman文件,删除之后可恢复正常. 这个文件夹是隐藏的,对于文件 ...
- GO Time 类型方法处理集合
1.判断2个时间是否超时 package main import ( "fmt" "time" ) func main() { //获取1秒后时间 var No ...
- 零基础学Java之Java学习笔记(四):运算符
算术运算符: 算术运算符是对数值类型的变量进行运算的,在 Java 程序中使用的非常多. 运算符 说明 例子 结果 + 加法-相加运算符两侧的值 9+9 18 - 减法-左操作数减去右操作数 10 ...
- 绕WAF常见思路整理(一)
最*被*台的一些事情搞得心态有点崩,很久没写文了 *期想整理一下常见的各种操作中绕过WAF的思路与免杀的思路(这部分之前没整理完以后有机会再说),受限于个人水*因素所以一定是不完全的,而且在WAF日新 ...
- HDFS 09 - HDFS NameNode 的高可用机制
目录 1 - 为什么要高可用 2 - NameNode 的高可用发展史 3 - HDFS 的高可用架构 3.1 Standby 和 Active 的命名空间保持一致 3.2 同一时刻只有一个 Acti ...
- BUUCTF刷题系列(2)5.27日记
CTF-Bugku-安卓篇1signin Writeup Bugku安卓部分第一题,第七届山东省大学生网络安全技能大赛的题目,属于Android逆向分析.(常用工具:安卓模拟器.JEB.Cyberch ...
- windows上python3安装
下载python 下载地址 https://www.python.org/downloads/windows/ 安装python 1.添加python到环境变量 2.自定义安装 3.下一步 4.选择安 ...
- JSP页面添加当前时间
JSP页面添加当前时间 一.时间格式化 1.引入标签 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/js ...
- 【springcloud】hystrix面试题
1 hystrix是什么? Netflix(国外最大的类似于,爱奇艺,优酷)视频网站,五六年前,也是,感觉自己的系统,整个网站,经常出故障,可用性不太高 有时候一些vip会员不能支付,有时候看视频就卡 ...