编程笔记

lifelong learning & practice makes perfect

CURD

Create

json自定义字段使用

  1. 如下为system使用自定义字段

    1
    2
    3
    type System struct{
    Version string
    }
  2. 为自定义类型实现接口Value/Scan

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    func (s System)Value()(driver.Value, error) {
    bytes, err := json.Marshal(s)
    return string(bytes), err
    }

    func (s *System) Scan(value interface{}) error {
    var bytes []byte
    switch v := value.(type) {
    case []byte:
    bytes = v
    case string:
    bytes = []byte(v)
    default:
    return fmt.Errorf("解析失败,原始数据:%v", value)
    }

    result := System{}
    if len(bytes) <= 0 {
    *s = result
    return nil
    }
    err := json.Unmarshal(bytes, &result)
    *s = result
    return err
    }
  3. json查询,例如这里要查询version=1.0的System

    1
    2
    select * from table_t
    where system->'$.version' = "1.0"

Update

Retrieve

预加载,preload

外键tag

预加载依赖在领域层结构体变量的gorm tag,需要在结构体上变量上增加外键tag,tag有多种写法,根
领域对象间的不同关系如:belongs to/has one/has many等有不同写法.

  1. belongs to 参考: https://gorm.io/zh_CN/docs/belongs_to.html
  2. has one
  3. has many
  4. many to many
    在项目ForeignKey,References这两个标签最常用,主要用于Preload相关数据
自定义预加载,可在预加载时添加条件实现排序等功能
  1. 排序

    1
    2
    3
    4
    5
    6
    7
    // 文档:https://gorm.io/zh_CN/docs/preload.html
    //您可以通过 func(db *gorm.DB) *gorm.DB 实现自定义预加载 SQL,例如:

    db.Preload("Users", func(db *gorm.DB) *gorm.DB {
    return db.Order("user.age DESC")
    }).Find(&users)
    // SELECT * FROM user WHERE id IN (1,2,3,4) order by user.age DESC;

2.

order by

  1. 常用
    指定从数据库检索记录时的排序方式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    db.Order("age desc, name").Find(&users)
    // SELECT * FROM users ORDER BY age desc, name;

    // 多个 order
    db.Order("age desc").Order("name").Find(&users)
    // SELECT * FROM users ORDER BY age desc, name;

    db.Clauses(clause.OrderBy{
    Expression: clause.Expr{SQL: "FIELD(id,?)", Vars: []interface{}{[]int{1, 2, 3}}, WithoutParentheses: true},
    }).Find(&User{})
    // SELECT * FROM users ORDER BY FIELD(id,1,2,3)
  2. order by field 自定义排序
    使用上面的写法通过自定义字段排序时注意,WithoutParentheses为true,为false是构建的sql为order by field(column,(“f1,f2,f3,…”)),会报错

  3. 组合排序

    1
    2
    3
    select id,status,create_time
    FROM `order`
    ORDER BY FIELD(status,'s3','s2','s1')desc,create_time desc

    如上的sql使用gorm框架可以这么写:

    1
    2
    3
    4
    5
    6
    7
    8
    res:=[]*Order{}
    db.Clauses(clause.OrderBy{
    Expression: clause.Expr{
    SQL: "FIELD(status,?) DESC,create_time DESC",
    Vars: []interface{}{
    []string{"s3","s2","s1"},
    },
    WithoutParentheses: true}}).Find(&res)

    不能使用链式调用(gorm v2版本,版本号:gorm.io/gorm v1.20.11),如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    db.Clauses(clause.OrderBy{
    Expression: clause.Expr{
    SQL: "FIELD(status,?) DESC",
    Vars: []interface{}{
    []string{"s3","s2","s1"},
    },
    WithoutParentheses: true}}).
    Order("create_time DESC").
    Find(&res)
  4. 参考文档

索引

  1. 强制索引

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import "gorm.io/hints"

    db.Clauses(hints.UseIndex("idx_user_name")).Find(&User{})
    // SELECT * FROM `users` USE INDEX (`idx_user_name`)

    db.Clauses(hints.ForceIndex("idx_user_name", "idx_user_id").ForJoin ()).Find(&User{})
    // SELECT * FROM `users` FORCE INDEX FOR JOIN (`idx_user_name`, `idx_user_id`)"

    db.Clauses(
    hints.ForceIndex("idx_user_name", "idx_user_id").ForOrderBy(),
    hints.IgnoreIndex("idx_user_name").ForGroupBy(),
    ).Find(&User{})

    Index 用于提高数据检索和 SQL 查询性能。 Index Hints 向优化器提供了在查询处理过程中如何选择索引的信息。与 optimizer 相比,它可以更灵活地选择更有效的执行计划

    • 加了join
    1
    2
    3
    4
    db.Table("`order` FORCE INDEX (order_create_time_d977ab1e,idx_demand_number,   idx_stocked_number,idx_di)").
    //Clauses(hints.CommentBefore("from", "FORCE INDEX (order_create_time_d977ab1e, idx_demand_number,idx_stocked_number,idx_di)")).
    // 这样写,生成的sql语句有问题,force index位置在where条件中间
    Joins("left join servicelist on order.service_list_id=servicelist.id").Find(& orders)

Delete

Config

ConnPool

  1. gorm 连接池配置通过sql.DB实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    gormDB,err:=gorm.Open(...)
    db,err:=gormDB.DB()
    if err!=nil{
    return
    }
    db.SetConnMaxLifetime() //连接最长复用时间
    db.SetConnMaxIdleTime() //maximum amount of time a connection may be idle,最长空闲时间
    db.SetMaxIdleConns() // 最长空闲时间 maximum number of connections in the idle connection pool
    db.SetMaxOpenConns() // 最大连接数 maximum number of open connections to the database

插件

推荐插件

  1. koroFileHeader

    • 功能: 自动在文件头或函数头增加注释

    • url: https://marketplace.visualstudio.com/items?itemName=OBKoro1.korofileheader

    • 函数

      1
      2
      3
      4
      5
      /**
      * @description:
      * @param {*}
      * @return {*}
      */
    • 文件

      1
      2
      3
      4
      5
      6
      7
      8
      <!--
      * @Author: your name
      * @Date: 2021-06-25 10:10:19
      * @LastEditTime: 2021-10-29 14:24:21
      * @LastEditors: your name
      * @Description: In User Settings Edit
      * @FilePath: /vscode-config.md
      -->

code runner

  1. golang同package下的代码undefined
1
2
3
4
在.vscode下的settigns.json增加配置
"code-runner.executorMap": {
"go": "cd $dir && go run .",
},

go path

  1. vscode同时开发多个项目,每个项目不同路径
    在不同终端下,配置不同gopath,使用 eexport GOPATH=/home/xxx/xxx设置

  1. What

    • 高性能

    • 分布式

      多个分布式节点共享分布式内存,与传统部署方式不同,节点越多,memcached的可用内存越多.

    • memory object caching system

    • key-value

    • LRU (memory manage algorithm)


阅读全文 »

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 用于staff的排序
type StaffWrapper struct {
Staffs []*Staff
Compare func(a, b *Staff) bool
}

func (sw StaffWrapper) Len() int {
return len(sw.Staffs)
}

func (sw StaffWrapper) Swap(a, b int) {
sw.Staffs[a], sw.Staffs[b] = sw.Staffs[b], sw.Staffs[a]
}
func (sw StaffWrapper) Less(i, j int) bool {
return sw.Compare(sw.Staffs[i], sw.Staffs[j])
}

func SortStaff(staffs []*Staff, by SortBy) {
sort.Sort(StaffWrapper{
Staffs: staffs,
Compare: by,
})
}

SortStaff(staffs, func(a, b *Staff) bool {
return a.BelongCorpID < b.BelongCorpID
})

//参考:https://www.cnblogs.com/wangchaowei/p/7802811.html

  • what is it
  • how it looks like
    1
    2


  • how to solve
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import "github.com/astaxie/beego/plugins/cors"
// 跨域问题尝试解决
beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
//允许访问所有源
AllowAllOrigins: true,
//可选参数"GET", "POST", "PUT", "DELETE", "OPTIONS" (*为所有)
//其中Options跨域复杂请求预检
AllowMethods: []string{"*"},
//指的是允许的Header的种类
AllowHeaders: []string{"*"},
//公开的HTTP标头列表
ExposeHeaders: []string{"Content-Length"},
//如果设置,则允许共享身份验证凭据,例如cookie
AllowCredentials: true,
}))



beego.Controller.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Origin",
beego.Controller.Ctx.Request.Header.Get("Origin"))
  • why

连接

  • -i指定密钥

  • -o加option

    1
    2
    -o TCPKeepAlive=yes        //长连接
    -o ServerAliveInterval=30 //

端口转发

1
2
3
4
ssh -L local_port:localhost:remote_port -N -T user@server_address -p   server_ssh_port
如:
ssh -L 9999:localhost:8888 -N -T user_test@111.111.111.111 -p 22
将发送到本地端口9999的请求数据转发到111.111.111.111转发到8888端口

配置

  1. config文件配置: ~/.ssh/config

    1
    2
    3
    4
    5
    6
    7
    8
    #配置
    Host gitee.com
    HostName gitee.com
    IdentityFile xxx/xxx/_id_rsa
    PreferredAuthentications publickey
    User xxx
    TCPKeepAlive=yes
    ServerAliveInterval 60
  2. 配置服务端

  • 件位置,全局位置: /etc/ssh/sshd_config
  • 文件位置,termux: $PREFIX/etc/ssh/sshd_config
  • 配置:
    • PasswordAuthentication (密码验证) yes/no
    • 启用密钥验证
      • RSAAuthentication (rsa秘钥) yes/no
      • PubkeyAuthentication (公钥) yes/no
  1. 认证秘钥,将公钥写入该文件(authorized_keys),就可使用该公钥登陆
    • 位置: ~/.authorized_keys

工具

  • windows terminal

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    连接远程机器使用 ssh 配置
    {
    "guid": "{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}",
    "hidden": false,
    "name": "xxxxxxx",
    //密钥放在本地,-i 指定密钥位置
    "commandline": "ssh -i xxxxxxx_id_rsa user@host -p xxxxxxxx -o TCPKeepAlive=yes -o ServerAliveInterval=30",
    "startingDirectory": "/home/xxxxxxx",
    "icon" : "ms-appx:///ProfileIcons/{9acb9455-ca41-5af7-950f-6bca1bc9722f}.png"
    }

什么是微服务,微服务概览

微服务设计

服务治理

服务发现

grpc

多租户&多集群

service mesh

  1. excelize 介绍
1
2


  1. 时间格式读取

excel表格操作库,对日期格式的数据读写还不是很完善,能识别的日期格式返回一个01-02-06(day-month-day)格式的字符串,无法识别时直接返回的是excel表格中的原始数据,一个浮点型数,在excel中支持很多种日期格式显示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
file,err:=excelize.OpenFile(filepath)
if err!=nil{
return
}

strTime,err:=file.GetCellValue("Sheet1","A1")
if err!=nil{
return
}

// 方式一:正常识别,通过time的库函数转换
resTime, err = time.ParseInLocation("01-02-06", strTime, time.Local)

// 方式二:未正常识别,先转换成int型数据再转换
intTime,err:=strconv.Atoi(strTime)
if err!=nil{
return
}

//转换为time.Time
time.Time=excelize.ExcelDateToTime(float64(intTime),false)
  1. 时间格式写入
    通过excelize写入时间格式的数据到文件,需要设置单元格格式,excelize支持写入的格式包含有time.Time,但是写入时需要使用UTC格式。
1
2
3
4
5
6
7
8
file:=excelize.NewFile()
//style 格式编号
style,err:=file.NewStyle(`{"number_format": 14}`)
if err!=nil{
return
}
file.SetCellValue("Sheet1","A1",time.Now().UTC())
file.SetCellStyle("Sheet1","A1","A1",style)

hexo clean 清除用于部署博客文件
删除.deploygit(也是)

先将themes/下要使用的主题作为git submodule,(git submodule add https://****.git)
添加后可使用git submodule查看子模块

将hexo根目录下的文件(含themes source scaffolds 等的目录)添加到git上传到私有项目

设置workflow等

由于使用了子模块

checkout的workflow最好找对应的submodule checkout

参考