better2021 / Blog

个人博客
https://feiyuweb.me/Blog
1 stars 0 forks source link

golang 学习笔记 #15

Open better2021 opened 5 years ago

better2021 commented 5 years ago

到底传指针有什么好处呢?

better2021 commented 5 years ago

defer

Go语言中有种不错的设计,即延迟(defer)语句,你可以在函数中添加多个defer语句。当函数执行到最后时,这些defer语句会按照逆序执行,最后该函数返回。特别是当你在进行一些打开资源的操作时,遇到错误需要提前返回,在返回前你需要关闭相应的资源,不然很容易造成资源泄露等问题

使用它后,不但代码量减少了很多,而且程序变得更优雅。在defer后指定的函数会在函数退出前调用

func ReadWrite() bool {
    file.Open("file")
    defer file.Close()
    if failureX {
        return false
    }
    if failureY {
        return false
    }
    return true
}

如果有很多调用defer,那么defer是采用后进先出模式,所以如下代码会输出4 3 2 1 0

for i := 0; i < 5; i++ {
    defer fmt.Printf("%d ", i)
}
better2021 commented 5 years ago

import常用的几种方式

better2021 commented 5 years ago

go语言string,int,int64的互相转换

#string到int
int,err:=strconv.Atoi(string)
#string到int64
int64, err := strconv.ParseInt(string, 10, 64)
#int到string
string:=strconv.Itoa(int)
#int64到string
string:=strconv.FormatInt(int64,10)
better2021 commented 5 years ago

[]byte和string相互转换

  str2 := "hello"
  data2 := []byte(str2)
  fmt.Println(data2)  // [104 101 108 108 111] 
  str3 := string(data2)  // hello
  fmt.Println(str3)
better2021 commented 5 years ago

gorm常用的增删改查语句

查询语句

 db.Select("user_name").Find(&users) // 只查询数据中的user_name字段
 db.Where("sex=?","boy").Find(&users) // 查询sex为boy的数据
 db.Where("id > ?",3).Find(&users) // 查询id大于3的数据
 db.Raw("select * from users").Scan(&users) // 原生的sql查询

db.First(&users) // 获取第一条数据
db.Last(&users) // 获取最后一条数据

// 根据名字模糊查询数据
db.Where("user_name LIKE ?","%" + name + "%").Find(&users).Count(&count)

新增语句

db.Create(data)  // data := &model.User{}

修改语句

db.Model(data).Where("id=?",id).Update(data)  // 根据id修改数据

删除语句

db.Where("id=?",id).Delete(model.User{})
better2021 commented 5 years ago

SQL

primary key 主键约束 unique 唯一约束 not null 非空约束 auto_increment 自动增长

删除表 :drop table 表名 修改:

查询表结构:

表中的数据操作 插入 : insert into 表名(列名,列名) values(值1,值2) 删除 :delete from 表名 where 条件 修改 : update 表名 set 列名=“值”,列名=“值” where 条件 查询 :select [distinct] * [列名] from 表名 where 条件

聚合函数:sum(),avg(),count(),max(),min() 排序:order by (asc升序 ,desc 降序)

better2021 commented 4 years ago

使用database/sql接口对数据库表进行增删改查操作

package main

import (
    "database/sql"
    "fmt"
    //"time"

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

func main() {
    db, err := sql.Open("mysql", "astaxie:astaxie@/test?charset=utf8")
    checkErr(err)

    //插入数据
    stmt, err := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?")
    checkErr(err)

    res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
    checkErr(err)

    id, err := res.LastInsertId()
    checkErr(err)

    fmt.Println(id)
    //更新数据
    stmt, err = db.Prepare("update userinfo set username=? where uid=?")
    checkErr(err)

    res, err = stmt.Exec("astaxieupdate", id)
    checkErr(err)

    affect, err := res.RowsAffected()
    checkErr(err)

    fmt.Println(affect)

    //查询数据
    rows, err := db.Query("SELECT * FROM userinfo")
    checkErr(err)

    for rows.Next() {
        var uid int
        var username string
        var department string
        var created string
        err = rows.Scan(&uid, &username, &department, &created)
        checkErr(err)
        fmt.Println(uid)
        fmt.Println(username)
        fmt.Println(department)
        fmt.Println(created)
    }

    //删除数据
    stmt, err = db.Prepare("delete from userinfo where uid=?")
    checkErr(err)

    res, err = stmt.Exec(id)
    checkErr(err)

    affect, err = res.RowsAffected()
    checkErr(err)

    fmt.Println(affect)

    db.Close()

}

func checkErr(err error) {
    if err != nil {
        panic(err)
    }
}

sql.Open()函数用来打开一个注册过的数据库驱动,go-sql-driver中注册了mysql这个数据库驱动,第二个参数是DSN(Data Source Name),它是go-sql-driver定义的一些数据库链接和配置信息。它支持如下格式:

user@unix(/path/to/socket)/dbname?charset=utf8
user:password@tcp(localhost:5555)/dbname?charset=utf8
user:password@/dbname
user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname

我们可以看到我们传入的参数都是=?对应的数据,这样做的方式可以一定程度上防止SQL注入。

better2021 commented 4 years ago

go语言的微服务架构

go语言的微服务

better2021 commented 4 years ago

读文件

        fileURL,_ := os.Getwd()  // 获取到文件的相对路劲
    path := strings.Replace(fileURL, "\\", "/", -1) // 替换\\为/
    fmt.Println(path,"--")
    d1 := []byte("hello\ngo\n")
    errs := ioutil.WriteFile(path + "/lesson/file/aa.txt",d1,0644) // 0644 为读写权限
    check(errs)

    f,err:=os.Create(path + "/lesson/file/bb.txt")
    check(err)

    defer f.Close()
better2021 commented 4 years ago

goroutine的WaitGroup等待组

var wg sync.WaitGroup // 创建一个同步等待组的对象

func main(){
        wg.Add(2) // 2个goroutine
        go printNum()
        go printStr()

    fmt.Println("进入阻塞状态")
    wg.Wait() // 表示goroutine进入等待,意味着阻塞
    fmt.Println("解除阻塞")
}

func printNum()  {
    for i:=1;i<=1000;i++{
        fmt.Println("打印数字",i)
    }

     wg.Done() // 给wg等待组中的counter数值减1,同 wg.Add(-1)
}

func printStr(){
    defer wg.Done()  // 使用defer写法更优雅
    for i:=1;i<=1000;i++{
        fmt.Println("字母",i)
    }
}
better2021 commented 4 years ago

golang语言中xxx{变量} 中的{}里面可以写变量,跟js的es6的模板字符串有点类似

var orderField = "created_at"
    var orderASC = "DESC"
    if c.Query("asc") == "1" {
        orderASC = "ASC"
    } else {
        orderASC = "DESC"
    }

    cateIDStr := c.Query("cateId")
    if cateIDStr == "" {
        categoryID = 0
    } else if categoryID, err = strconv.Atoi(cateIDStr); err != nil {
        fmt.Println(err.Error())
        SendErrJSON("分类ID不正确", c)
        return
    }

var sql = `SELECT distinct(articles.id), articles.name, articles.browse_count, articles.comment_count, articles.collect_count,  
                    articles.status, articles.created_at, articles.updated_at, articles.user_id, articles.last_user_id  
                FROM articles, article_category  
                WHERE articles.id = article_category.article_id   
                {statusSQL}       
                AND article_category.category_id = {categoryID} 
                AND articles.deleted_at IS NULL 
                AND articles.id NOT IN ({topIDs})   
                {timeSQL} 
                ORDER BY {orderField} {orderASC}
                LIMIT {offset}, {pageSize}`
better2021 commented 4 years ago

查看go版本

go version

查看go环境配置

go env

better2021 commented 4 years ago

len()函数与字符串遍历

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {

    str1 := "hello world"
    str2 := "你好,"

    fmt.Println(len(str1))                          // 11
    fmt.Println(len(str2))                          // 9
    fmt.Println(utf8.RuneCountInString(str2))       // 3
}