golang查询mysql,查询并写入20万数据到excel中

1、较上午写的,mysql类有进一步完善,没有使用interface类型处理,而是将数据存储到mobile结构体中,同时暂存到一个切片中,后再去写入

2、数据表格式

CREATE TABLE `mobile` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `mobile` char(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2000001 DEFAULT CHARSET=utf8;

```go
package main

// 引入关键包
import (
	"fmt"
	"database/sql"
	"github.com/360EntSecGroup-Skylar/excelize"
	"strconv"
	"time"

	_ "github.com/go-sql-driver/mysql"
)

// 定义全局变量,主要方便后续操作数据库
var (
	db *sql.DB
	err error
)

// 定义表机构类型的结构体
type Mobile struct {
	id int
	mobile string
}

// 初始化链接mysql
func initDB() (err error) {

	conn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8;", "root", "root", "localhost:3306", "mobile")

	db, err = sql.Open("mysql", conn)

	if err != nil {

		panic(err)
	}

	err = db.Ping()

	if err != nil {

		fmt.Printf("open %s invaild ,err'=", err)
		return nil
	}

	fmt.Println("connect database succsed")
	return nil
}

// 主方法
func main() {

	fmt.Println("start", time.Now())

	// 调用mysql链接
	initDB()

	// 定义表名
	var table string = "mobile"
	// 定义查询连接条件
	var typeOr string = "and"

	// 定义key => value 类型的map
	var where = make(map[string]string)

	//where["id"] = "1"
	//where["name"] = "ceshi"

	// 调用方法查询,其中where,采用引用传递
	data := querySelect(table, &where, typeOr)

	writeExcel(&data)
}

// 写入 小于 等于10000 耗时不到1秒
// 写入 等于100000 耗时19秒
// 写入 200000 耗时约2分16秒
func writeExcel(data *[]Mobile) {

	fmt.Println("调用资源文件开始时间", time.Now())

	f := excelize.NewFile()
	// 创建新的sheet.
	index := f.NewSheet("Sheet1")

	// 设置行内数据
	f.SetCellValue("Sheet1", "A1", "id")
	f.SetCellValue("Sheet1", "B1", "手机号")

	for k, v := range *data {
		k = k+1
		// 将int类型强转成字符串类型
		str := "A" + strconv.Itoa(k)
		str1 := "B" + strconv.Itoa(k)
		// 向单元格中设置值
		f.SetCellValue("Sheet1", str, v.id)
		f.SetCellValue("Sheet1", str1, v.mobile)
	}

	// 设置激活的sheet
	f.SetActiveSheet(index)
	// 将电子表格进行保存
	if err := f.SaveAs("./Book1.xlsx"); err != nil {
		fmt.Println(err)
	}
	// 将电子表格转成 buffer
	f.WriteToBuffer()

	fmt.Println("调用资源文件结束时间", time.Now())

	fmt.Println("end")
}

// 查询方法  返回对应的Mobile类型的数据
func querySelect(table string, where *map[string]string, typeOr string) []Mobile {

	// 获取当前的查询条件数量
	var count = len(*where)

	// 定义最终生成的sql变量
	var finalSql string

	// 如果不等于0则表明有多个 进行where查询,否则进行全表查询
	if count != 0 {
		// 预定义sql变量,用来接受传递的数据内容
		var sql string

		// 循环获取key 和 value
		for key, value := range *where {

			// 连接组合成想要的数据格式
			sql += key + " = '" + value + "' " + typeOr + " "
		}

		// 使用rune采用数组的方式 截取多余的字符
		newSql := []rune(sql)

		// 截取多余字符
		sql = string(newSql[0:len(sql) - 4])

		// 生成最终sql
		finalSql = "select * from "+ table + " where " + sql
	} else {

		// 排序方式,默认
		finalSql = "select * from "+ table + " order by id asc limit 0,1000;"
	}

	fmt.Println("查询数据库前的时间", time.Now())

	// 查询结果集
	rows, err := db.Query(finalSql)

	fmt.Println("查询数据库后的时间", time.Now())

	// 定义数组,传递对应的结构体
	var Data []Mobile

	// 判断查询失败的情况返回false
	if err != nil {

		fmt.Println(err)
		return Data
	}

	// 创建mysql的结构体
	var mobileObj Mobile

	fmt.Println("整理数据格式时间", time.Now())

	// 使用for循环,一直查询到所有的数据
	for rows.Next() {

		// 通过方法,将查询到的数据追加到当前的结构体中
		rows.Scan(&mobileObj.id, &mobileObj.mobile)

		// 将当前查询到的数据追加到预定义的切片中
		Data = append(Data, mobileObj)
	}


	// 返回对应的数据
	return Data
}

// 删除方法
func delData(id int) interface{} {

	sql := "delete from demo where id=?;"

	res, err := db.Exec(sql, id)

	if err != nil {

		fmt.Printf("delete failed, err:%v\n", err)
		return false
	}

	nes, err := res.RowsAffected()

	if err != nil {
		fmt.Printf("get RowsAffected failed, err:%v\n", err)
		return false

	}

	fmt.Println(nes)
	fmt.Println(res)
	return nes

}

// 更新方法
func updateData(id int) interface{} {

	sql := "update demo set title = ? where id = ?"

	ret, err := db.Exec(sql, "哈哈哈1", id)

	if err != nil {

		panic(err)
	}
	return ret
}


// 新增方法
func insertData(str string) interface{} {

	insertSql := "insert into demo(id, title) value(?, ?)"

	ret, err := db.Exec(insertSql, nil, str)

	if err != nil {
		panic(err)
	}
	newId, err := ret.LastInsertId()

	return newId
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值