golang入门教程

1.读取配置文件

_serverConfig, err := goconfig.LoadConfigFile("./conf/config.conf")
if err != nil {
    Log.Error("read config.ini error:", err.Error())
}
_serverConfig.MustValue(section, key, defaultVal...)

2.数据库初始化

preFix := "my_" + configs.FACTORY
dbhost = configs.GetServerProp(preFix, "dbhost", "")
dbport = configs.GetServerProp(preFix, "dbport", "")
dbname = configs.GetServerProp(preFix, "dbname", "")
username = configs.GetServerProp(preFix, "username", "")
passwd = configs.GetServerProp(preFix, "passwd", "")
sslmode = configs.GetServerProp(preFix, "sslmode", "")
schema = configs.GetServerProp(preFix, "schema", "")
urlTb := utils.Sprintf("host=%v port=%v user=%v password=%v dbname=%v sslmode=%v search_path=%v", dbhost, dbport, username, passwd, dbname, sslmode, schema)
database, err := sql.Open("postgres", urlTb)
if err != nil {
    configs.Log.Error("open postgre failed, err:", err.Error())
    return
}
database.SetConnMaxLifetime(configs.DB_TIMEOUT_DURATION)
database.SetMaxOpenConns(50)
database.SetMaxIdleConns(5)
Dbmy := database

3.数据库查询

func SelectBySql(myDb *sql.DB, execSql string, args ...any) ([]map[string]string, error) {
    defer func() {
       if er := recover(); er != nil {
          erLog := utils.Sprintf("%v panic:%v", utils.RunFuncName(), er)
          configs.Log.Error(erLog)
       }
    }()
    resArray := []map[string]string{}
     //增加contxt   
    ctx, cancel := context.WithTimeout(context.Background(), configs.DB_TIMEOUT_DURATION)
    defer cancel()
    var rows *sql.Rows
    var err error
    if nil != args && len(args) > 0 {
       rows, err = myDb.QueryContext(ctx, execSql, args...)
    } else {
       rows, err = myDb.QueryContext(ctx, execSql)
    }

    if nil != err {
       return resArray, err
    }
    defer rows.Close()

    cols, err := rows.Columns()
    if err != nil {
       return resArray, err
    }
    colSize := len(cols)
    record := make([]any, colSize)
    container := make([]sql.NullString, colSize)
    for i := 0; i < colSize; i++ {
       record[i] = &container[i]
    }
    row := make(map[string]string)
    for rows.Next() {
       err = rows.Scan(record...)
       if nil != err {
          return resArray, err
       }
       row = make(map[string]string)
       for i, column := range cols {
          if container[i].Valid {
             row[strings.ToUpper(column)] = strings.Replace(container[i].String, "\u0000", "", -1)
          } else {
             row[strings.ToUpper(column)] = ""
          }

       }
       resArray = append(resArray, row)
       row = nil
    }
    record = nil
    container = nil
    return resArray, nil
}

4.数据库插入或者修改

ctx, cancel := context.WithTimeout(context.Background(), configs.DB_TIMEOUT_DURATION)
defer cancel()
tx, errBegin := myDb.BeginTx(ctx, nil)
if nil != errBegin {
    configs.Log.Error("err:", errBegin.Error())
    return errBegin
}
for _, execSql := range execSqls {
    _, errExec := tx.ExecContext(ctx, execSql)
    if nil != errExec {
       configs.Log.Error("err:", errExec.Error())
       return errExec
    }
}
return tx.Commit()

5.日志自动保存

var (
    pointArr model.SafeArray[string]
    //
    lastWriteOn time.Time = time.Now()
)

func init() {
    pointArr.SetAll(make([]string, configs.INFLUX_BATCH))
}

func Write(execsql string) {
    if nil == DbSourceTb {
       return
    }
    currArrLen := pointArr.Push(execsql)
    //
    if currArrLen >= configs.INFLUX_BATCH {
       execSqls := pointArr.PopAndClean(configs.INFLUX_BATCH)
       for i := 0; i < configs.RETRY_COUNT; i++ {
          err := ExecBatchBarcodeD7x(execSqls)
          if nil == err {
             break
          }
       }
       execSqls = nil
       lastWriteOn = time.Now()
    }
    execsql = ""
}

func AutoWriterAfterTime() {
    defer func() {
       if er := recover(); er != nil {
          erLog := utils.Sprintf("AutoWriterAfterTime panic: %v", er)
          configs.Log.Error(erLog)
       }
    }()
    if nil == DbSourceTb {
       return
    }
    currArrLen := pointArr.NowIndex()
    //
    if currArrLen > 0 && time.Now().Sub(lastWriteOn).Milliseconds() >= 30000 {
       execSqls := pointArr.PopAndClean(configs.INFLUX_BATCH)
       for i := 0; i < configs.RETRY_COUNT; i++ {
          err := ExecBatchBarcodeD7x(execSqls)
          if nil == err {
             break
          }
       }
       execSqls = nil
       lastWriteOn = time.Now()
    }
}

func ExecBatchBarcodeD7x(barcodes []string) (err error) {
    var sqlSb strings.Builder
    defer func() {
       if er := recover(); er != nil {
          erLog := utils.Sprintf("%v panic:%v", utils.RunFuncName(), er)
          err = errors.New(erLog)
          configs.Log.Error(erLog)
       }
    }()
    i := 0
    for _, v := range barcodes {
       sqlSb.WriteString(";")
       sqlSb.WriteString(v)
       i++
       if i > configs.DB_BATCH_COMMIT_SIZE {
          sqls := sqlSb.String()
          err = ExecCommit(sqls, true)
          if err != nil {
             err = SingleSqlCommit(sqls)
             if nil != err {
                configs.Log.Error("single sql error", err)
                sqls = ""
                barcodes = nil
                sqlSb.Reset()
                return err
             }
          }
          i = 0
          sqls = ""
          sqlSb.Reset()
       }
    }
    //
    sqls := sqlSb.String()
    sqlSb.Reset()
    if sqls != "" {
       err = ExecCommit(sqls, true)
       if err != nil {
          err = SingleSqlCommit(sqls)
          if nil != err {
             sqls = ""
             barcodes = nil
             sqlSb.Reset()
             configs.Log.Error("single sql error", err)
             return err
          }
       }
    }
    sqls = ""
    barcodes = nil
    return nil
}

func ExecCommit(sqls string, isBatch bool) error {
    defer func() {
       if er := recover(); er != nil {
          erLog := utils.Sprintf("%v panic:%v", utils.RunFuncName(), er)
          configs.Log.Error(erLog)
       }
    }()
    timeOut := 3 * time.Second
    if isBatch {
       timeOut = 12 * time.Second
    }
    ctx, cancel := context.WithTimeout(context.Background(), timeOut)
    defer cancel()
    tx, err := DbSourceTb.BeginTx(ctx, nil)
    if err != nil {
       sqls = ""
       return err
    }
    _, err = tx.ExecContext(ctx, sqls)
    if err != nil {
       _ = tx.Rollback()
       sqls = ""
       return err
    }
    sqls = ""
    return tx.Commit()
}

func SingleSqlCommit(sqls string) (err error) {
    defer func() {
       if er := recover(); er != nil {
          erLog := utils.Sprintf("%v panic:%v, execsql:%s", utils.RunFuncName(), er, sqls)
          err = errors.New(erLog)
          configs.Log.Error(erLog)
       }
    }()
    insqls := strings.Split(sqls, ";")
    for _, v := range insqls {
       if len(v) > 5 {
          err = ExecCommit(v, false)
       }
    }
    sqls = ""
    insqls = nil
    return nil
}

6.中间件

type bodyLogWriter struct {
    gin.ResponseWriter
    body *bytes.Buffer
}

//json
func (w bodyLogWriter) Write(b []byte) (int, error) {
    return w.body.Write(b)
}

//
func (w bodyLogWriter) WriteString(s string) (int, error) {
    return w.body.WriteString(s)
}

func FuckLogger() gin.HandlerFunc {

    return func(ctx *gin.Context) {
        defer func() {
            if err := recover(); err != nil {
                configs.Log.Error(err)
            }
        }()

        bodyLogWrit := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: ctx.Writer}
        ctx.Writer = bodyLogWrit
        var reqStr string
        var resStr string
        var costTime int64
        startTime := time.Now()
        requestPath := ctx.Request.URL.Path

        //开始时间
        defer func() {
            if err := recover(); err != nil {
                resStr, _ = sjson.Set(resStr, "rc", model.API_RESULT_RC_ERR)
                resStr, _ = sjson.Set(resStr, "rm", utils.Sprintf("request [%v] error:%v", requestPath, err))
            }
            //
            resStr, _ = sjson.Set(resStr, "sysDate", time.Now().Format(model.DATE_TIME_FORMAT_SYSDATE))
            costTime = time.Since(startTime).Milliseconds()
            resStr, _ = sjson.Set(resStr, "csTime", utils.Sprintf("%dms", costTime))
            ctx.Writer = bodyLogWrit.ResponseWriter
            ctx.String(http.StatusOK, resStr)

            //log
        }()
        
        //拦截代码
        reqData, _ := io.ReadAll(ctx.Request.Body)
        defer ctx.Request.Body.Close()
        ctx.Request.Body = io.NopCloser(bytes.NewBuffer(reqData)) // 
        reqStr = string(reqData)
        //next
        ctx.Next()
        
        resStr = string(bodyLogWrit.body.Bytes())

    }
}

//gin使用

gin.SetMode(gin.ReleaseMode)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值