mysql数据导出golang实现

Simple install the package to your $GOPATH with the go tool from shell:

$ go get -u github.com/go-sql-driver/mysql

具体说明请看:

库地址:

https://github.com/go-sql-driver/mysql

wiki说明:

https://github.com/go-sql-driver/mysql/wiki/Examples

代码示例如下,用到了go的flag包的能力,传入命令行参数。具体看helpInfo:

flag包的使用可以参考:golang flag包使用笔记

Usage of mysqldataexport:
  -port int
        the port for mysql,default:32085
  -addr string
        the address for mysql,default:10.146.145.67
  -user string
        the username for login mysql,default:dbuser

  -pwd  string
        the password for login mysql by the username,default:Admin@123
  -db   string
        the port for me to listen on,default:auditlogdb
  -tables string
        the tables will export data, multi tables separator by comma, default:op_log,sc_log,sys_log

代码:

package main

// 从Mysql中导出数据到CSV文件。

import (
    "database/sql"
    "encoding/csv"
    "fmt"
    "os"
    _ "github.com/go-sql-driver/mysql"
    "flag"
    "strings"
)

var (
    tables         = make([]string, 0)
    dataSourceName = ""
)

const (
    driverNameMysql = "mysql"

    helpInfo = `Usage of mysqldataexport:
  -port int
        the port for mysql,default:32085
  -addr string
        the address for mysql,default:10.146.145.67
  -user string
        the username for login mysql,default:dbuser

  -pwd  string
        the password for login mysql by the username,default:Admin@123
  -db   string
        the port for me to listen on,default:auditlogdb
  -tables string
        the tables will export data, multi tables separator by comma, default:op_log,sc_log,sys_log
    `
)

func init() {

    port := flag.Int("port", 32085, "the port for mysql,default:32085")
    addr := flag.String("addr", "10.146.145.67", "the address for mysql,default:10.146.145.67")
    user := flag.String("user", "dbuser", "the username for login mysql,default:dbuser")
    pwd := flag.String("pwd", "Admin@123", "the password for login mysql by the username,default:Admin@123")
    db := flag.String("db", "auditlogdb", "the port for me to listen on,default:auditlogdb")
    tabs := flag.String("tables", "op_log,sc_log,sys_log", "the tables will export data, multi tables separator by comma, default:op_log,sc_log,sys_log")

    flag.Usage = usage

    flag.Parse()

    tables = append(tables, strings.Split(*tabs, ",")...)

    dataSourceName = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", *user, *pwd, *addr, *port, *db)
}

func main() {

    count := len(tables)
    ch := make(chan bool, count)

    db, err := sql.Open(driverNameMysql, dataSourceName)
    defer db.Close()
    if err != nil {
        panic(err.Error())
    }

    // Open doesn't open a connection. Validate DSN data:
    err = db.Ping()
    if err != nil {
        panic(err.Error())
    }

    for _, table := range tables {
        go querySQL(db, table, ch)
    }

    for i := 0; i < count; i++ {
        <-ch
    }
    fmt.Println("Done!")
}

func querySQL(db *sql.DB, table string, ch chan bool) {
    fmt.Println("开始处理:", table)
    rows, err := db.Query(fmt.Sprintf("SELECT * from %s", table))

    if err != nil {
        panic(err)
    }

    columns, err := rows.Columns()
    if err != nil {
        panic(err.Error())
    }

    //values:一行的所有值,把每一行的各个字段放到values中,values长度==列数
    values := make([]sql.RawBytes, len(columns))
    // print(len(values))

    scanArgs := make([]interface{}, len(values))
    for i := range values {
        scanArgs[i] = &values[i]
    }

    //存所有行的内容totalValues
    totalValues := make([][]string, 0)
    for rows.Next() {

        //存每一行的内容
        var s []string

        //把每行的内容添加到scanArgs,也添加到了values
        err = rows.Scan(scanArgs...)
        if err != nil {
            panic(err.Error())
        }

        for _, v := range values {
            s = append(s, string(v))
            // print(len(s))
        }
        totalValues = append(totalValues, s)
    }

    if err = rows.Err(); err != nil {
        panic(err.Error())
    }
    writeToCSV(table+".csv", columns, totalValues)
    ch <- true
}

//writeToCSV
func writeToCSV(file string, columns []string, totalValues [][]string) {
    f, err := os.Create(file)
    // fmt.Println(columns)
    defer f.Close()
    if err != nil {
        panic(err)
    }
    //f.WriteString("\xEF\xBB\xBF")
    w := csv.NewWriter(f)
    for i, row := range totalValues {
        //第一次写列名+第一行数据
        if i == 0 {
            w.Write(columns)
            w.Write(row)
        } else {
            w.Write(row)
        }
    }
    w.Flush()
    fmt.Println("处理完毕:", file)
}

func usage() {
    fmt.Fprint(os.Stderr, helpInfo)
    flag.PrintDefaults()
}

操作示例:

编译代码生成可执行文件:

go build mysqldataexport.go

数据库中有test2库下的test表:

导出其中的数据:

.\mysqldataexport.exe -port=3306 -addr="localhost" -user="root" -pwd="mysql" -db="test2" -tables="test"

导出结果如下:

原文发布于微信公众号 - 我的小碗汤(mysmallsoup)

原文发表时间:2018-09-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏IT开发技术与工作效率

VBA常用程序——每个表都应该有

19630
来自专栏landv

实现用VB.Net/(C#)开发K/3 BOS 插件的真正可行方法

16510
来自专栏君赏技术博客

Jekyll-Admin-Mac-列表

接下来我们需要就是做出这个列表数据,我们可以使用 NSTableView来做出这个效果。

16910
来自专栏Golang语言社区

Redis之并发写入

首先需要澄清一个事实:redis服务端是单线程处理客户端请求,也就是说客户端请求在服务端是串行化执行的,因此对服务端来说,并不存在并发问题。但业务方却存在并发操...

75270
来自专栏用户2442861的专栏

Emmet for Dreamweaver:HTML/CSS代码快速编写神器

Emmet的前身是大名鼎鼎的Zen coding,如果你从事Web前端开发的话,对该插件一定不会陌生。它使用仿CSS选择器的语法来生成代码,大大提高了HTML...

25620
来自专栏DOTNET

学会WCF之试错法——超时

服务契约 [ServiceContract] public interface IService { [OperationCon...

33560
来自专栏XAI

ZeroClipboard实现多个浏览器兼容的复制文本到剪贴板的功能

ZeroClipboard实现多个浏览器兼容的复制文本到剪贴板的功能 本人在项目中使用的js版本。为了方便大家下载。直接粘贴代码给大家看。版本是1.2.0 /*...

28970
来自专栏yukong的小专栏

【SpringBoot2.0系列11】SpringBoot之@Elasticsearch完成CURD

【SpringBoot系列02】SpringBoot之使用Thymeleaf视图模板

85530
来自专栏Android知识点总结

Android基于TCP的五子棋双人对战实现

20520
来自专栏Golang语言社区

【转载】记Golang数据库查询封装的坑

前文 golang接触也有一段时间,项目中有用到web api,基本上就是post json格式的,本想用java来写,刚下手想到java太臃肿,各种繁琐。觉得...

55470

扫码关注云+社区

领取腾讯云代金券