dccmmtop / notebook

个人博客记录
0 stars 0 forks source link

Go与SQL #27

Open dccmmtop opened 2 years ago

dccmmtop commented 2 years ago

连接数据库

sq1.DB结构是一个数据库句柄(handle),它代表的是一个包含了零个或任意多个数据库连接的连接池(pool),这个连接池由sql包管理。程序可以通过调用Open函数,并将相应的数据库驱动名字(driver name)以及数据源名字(data source name)传递给该函数来建立与数据库的连接。

比如,在下面展示的例子中,程序使用的是mysql驱动。数据源名字是一个特定于数据库驱动的字符串,它会告诉驱动应该如何与数据库进行连接。

Open函数在执行之后会返回一个指向sq1.DB结构的指针作为结果。Open函数在执行时,不会真正的与数据库连接,甚至不会检查参数.

Open函数真正的作用是设置好连接数据库所需要的结构,并以惰性的方式,等真正需要的时候才建立与数据库连接

var Db *sql.DB

func init() {
    var err error
    Db, err = sql.Open("mysql", "esns:dccmmtop@tcp(192.168.32.128:3306)/chitchat")
    if err != nil {
        log.Fatal(err)
    }
    return
}

创建用户

type User struct {
    Id int64
    Uuid string
    Name string
    Email string
    Password string
    CreatedAt time.Time
}

func (u *User) Create() (err error) {
    statement := "insert into users(uuid,name,email,password, created_at) value(?,?,?,?,?)"
    // 预编译
    stmt, err := Db.Prepare(statement)
    if err != nil {
        return  err
    }
    defer stmt.Close()
    // 加密密码
    u.Password = Encrypt(u.Password)
    // 生成UUID
    u.Uuid = CreateUUID()
    u.CreatedAt = time.Now()
    // 执行
    result, err := stmt.Exec(u.Uuid,u.Name,u.Email,u.Password,u.CreatedAt)
    if err != nil {
        return err
    }
    // 返回插入后的自增ID
    u.Id, err = result.LastInsertId()
    if err != nil {
        util.Danger.Println("创建用户返回Id错误: ",err)
        return err
    }
    util.Info.Println("新增用户: ", fmt.Sprintf("%v",*u))
    userJson, err := json.Marshal(*u)
    if err != nil {
        return err
    }
    util.Info.Println("新增用户: ", string(userJson))
    return
}

查询用户

// 根据ID查询用户
func FindUserById(id int64)(u User, err error) {
    sql := "select id, uuid, `name`, email, password, created_at from users where id = ?"
    u = User{}
  // scan 将查询出来的每一列赋值给对应的属性
    err = Db.QueryRow(sql, id).Scan(&u.Id, &u.Uuid, &u.Name, &u.Email, &u.Password, &u.CreatedAt)
    if err != nil {
        util.Danger.Println("查询用户错误: ", err)
        return
    }
    return
}

获取多个对象

type Thread struct {
    Id int64
    Uuid   string
    UserId int64
    Topic string
    CreatedAt time.Time
}

// 获取用户发布多个帖子
func ThreadsList(userId int64)(threads []Thread){
    sql := "select id, uuid, user_id, topic,created_at from threads where user_id = ? order by created_at desc"
    rows, err := Db.Query(sql,userId)
    if err != nil {
        util.Danger.Println("查询 threads 错误, 返回空数据,err:", err)
        return
    }
    defer rows.Close()
    for rows.Next() {
        thread := Thread{}
        err := rows.Scan(&thread.Id,&thread.Uuid,&thread.UserId,&thread.Topic,&thread.CreatedAt)
        if err != nil {
            util.Danger.Println(err)
            continue
        }
        threads = append(threads,thread)
    }

    return
}