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
}