常用功能函数:大数组分片、sql逗号拼接、字符压缩、切换shell工作目录...

目录

1.将大数组分片处理 

2.用于insert时的sql拼接

3.字符串转md5

4.利用gzip包,压缩字符内容

5.切换当前工作目录

7.读取配置文件path

8.切随机生成uuid


1.将大数组分片处理 

场景:比如sql语法中,使用 IN(?) 条件时,IN的数组中元素个数过多,会导致预编译数超限,此时就需要分块处理

// 1.将大数组分片处理
func SplitArr() {
	taskIds := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	block, yushu, blockCnt := 0, 0, 3 // 分区块数,余数,每个区元素数

	if len(taskIds)%blockCnt == 0 {
		block = len(taskIds) / blockCnt
		yushu = 0
	} else {
		block = len(taskIds)/blockCnt + 1
		yushu = len(taskIds) % blockCnt
	}

	subTaskIds := make([]int, 0)
	for i := 0; i < block; i++ {
		if i == block-1 { // 最后一块
			subTaskIds = taskIds[i*blockCnt : i*blockCnt+yushu]
		} else {
			subTaskIds = taskIds[i*blockCnt : (i+1)*blockCnt]
		}

		// 处理 subTaskIds 数组
		fmt.Printf("the %v subTaskIds: %v\n", i, subTaskIds)
	}
}
/*
	输出:
	the 0 subTaskIds: [0 1 2]
	the 1 subTaskIds: [3 4 5]
	the 2 subTaskIds: [6 7 8]
	the 3 subTaskIds: [9]
*/

// 2.方法2:封装为切割任意interface类型切片的函数方法
// CutSlice 按照指定长度切割切片
func CutSlice(slice interface{}, n int) [][]interface{} {
	var s [][]interface{}

	v := reflect.ValueOf(slice)

	if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
		return nil
	}

	if v.Len() == 0 {
		return nil
	}

	if v.Len() <= n {
		value := make([]interface{}, v.Len())

		for i := 0; i < v.Len(); i++ {
			value[i] = v.Index(i).Interface()
		}

		s = append(s, value)
		return s
	}

	s = make([][]interface{}, int(math.Ceil(float64(v.Len())/float64(n))))

	x := n
	index := 0

	for i := 0; i < v.Len(); i++ {

		if i == x {
			index++
			x += n
		}

		if s[index] == nil {
			s[index] = make([]interface{}, 0)
		}
		s[index] = append(s[index], v.Index(i).Interface())
	}

	return s
}

2.用于insert时的sql拼接

package main

import (
	"fmt"
	"math"
	"reflect"
	"strings"
)

// UserInfo
type UserInfo struct {
	Name string
	Age  int
}

// CombineSql1 利用CutSlice将待插入数组分片,避免一次瞬时插入导致db压力过大;利用strings.Join()进行字符拼接
func CombineSql1(dataArr []*UserInfo) (err error) {
	strSql := "INSERT INTO test_table(`name`, `age`) VALUES"
	blockCnt := 1000 // 以1000为一组分片insert

	for _, iSubDataArr := range CutSlice(dataArr, blockCnt) {
		values := make([]string, 0, blockCnt)
		params := make([]interface{}, 0, blockCnt)
		for i := 0; i < len(iSubDataArr); i++ {
			data := iSubDataArr[i].(*UserInfo)
			values = append(values, "(?,?)")
			params = append(params, data.Name, data.Age)
		}

		strSubSql := strSql + strings.Join(values, ",")

		fmt.Printf("strSubSql: %v	params: %v\n", strSubSql, params)

		// 执行sql...
	}

	return
}

// CutSlice 按照指定长度切割切片
func CutSlice(slice interface{}, n int) [][]interface{} {
	var s [][]interface{}

	v := reflect.ValueOf(slice)

	if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
		return nil
	}

	if v.Len() == 0 {
		return nil
	}

	if v.Len() <= n {
		value := make([]interface{}, v.Len())

		for i := 0; i < v.Len(); i++ {
			value[i] = v.Index(i).Interface()
		}

		s = append(s, value)
		return s
	}

	s = make([][]interface{}, int(math.Ceil(float64(v.Len())/float64(n))))

	x := n
	index := 0

	for i := 0; i < v.Len(); i++ {

		if i == x {
			index++
			x += n
		}

		if s[index] == nil {
			s[index] = make([]interface{}, 0)
		}
		s[index] = append(s[index], v.Index(i).Interface())
	}

	return s
}

// CombineSql2 用于insert时的sql拼接(利用 "+" 字符拼接,此方法未分片仅用于sql拼接)
func CombineSql2(list []*UserInfo) (err error) {
	strSql := "INSERT INTO test_table(`name`, `age`) VALUES"
	params := make([]interface{}, 0)

	for i := 0; i < len(list); i++ {
		strSql += "(?,?)"
		if i < len(list)-1 {
			strSql += "," // 循环拼接逗号
		}
		params = append(params, list[i].Name, list[i].Age)
	}
	fmt.Println("sql: ", strSql, "	params:", params)

	// 执行sql...
	return
}

func main() {
	list := []*UserInfo{
		{"user1", 1},
		{"user2", 2},
		{"user3", 3},
	}
	CombineSql1(list) // 方法1
	CombineSql2(list) // 方法2
	return
}

sql拼接结果示例: 

3.字符串转md5

// 3.字符串转md5
func MD5(s string) string {
	ret := md5.Sum([]byte(s))
	return hex.EncodeToString(ret[:])
}

4.利用gzip包,压缩字符内容

// 压缩内容,by gzip 方式,data用json.Marshal()编码
func CompressTogzip(data []byte) string {
	var buf bytes.Buffer
	gz := gzip.NewWriter(&buf)
	defer gz.Close()

	gz.Write(data)
	gz.Flush()

	return base64.StdEncoding.EncodeToString(buf.Bytes())
}

// 解压缩内容,by gzip 方式
func UnCompressTogzip(str string) ([]byte, error) {
	data, err := base64.StdEncoding.DecodeString(str)
	if err != nil {
		return nil, err
	}

	buf2 := bytes.NewBuffer(data)

	gz, err := gzip.NewReader(buf2)
	if err != nil {
		return nil, err
	}

	defer gz.Close()

	p, err := ioutil.ReadAll(gz)
	if err != nil && err != io.ErrUnexpectedEOF {
		return nil, err
	}

	return p, nil
}

5.切换当前工作目录

func SwitchWorkDir() {
	os.Chdir("/usr/local") // 先切换当前工作目录
	dir, err1 := exec.Command("pwd").Output()
	if err1 != nil {
		fmt.Println("exec.Command err: ", err1)
		return
	}
	fmt.Println("dir: ", string(dir))
	return
}

func main() {
	SwitchWorkDir()
}

 6.遍历指定文件夹,获取所有文件名(folder为指定路径,默认可为当前目录 ".")

func GetFiles(folder string){
	files, _ := ioutil.ReadDir(folder)
	fmt.Println("files length = ", len(files))

	for _,file := range files{
		if file.IsDir(){
			GetFiles(folder + "/" + file.Name())
		}else{
			fmt.Println(folder + "/" + file.Name())
		}
	}
}

7.读取配置文件path

binPath, _ := filepath.Abs(filepath.Dir(os.Args[0]))
rootPath := filepath.Dir(binPath)
fmt.Printf("%s/conf/%s/config.yaml", rootPath, os.Getenv("ENV"))

8.切随机生成uuid

// import "github.com/gofrs/uuid"

// 随机生成uuid
func UUID() (string, error) {
	str, err := uuid.NewV4()
	if err != nil {
		return "", err
	}
	return str.String(), nil
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值