使用sql操作数据库
安装mysql驱动:go get github.com/go-sql-driver/mysql
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func checkErr(errMasg error) {
if errMasg != nil {
panic(errMasg)
}
}
func printResult(query *sql.Rows) {
column, _ := query.Columns() //读出查询出的列字段名
values := make([][]byte, len(column)) //values是每个列的值,这里获取到byte里
scans := make([]interface{}, len(column)) //因为每次查询出来的列是不定长的,用len(column)定住当次查询的长度
for i := range values { //让每一行数据都填充到[][]byte里面
scans[i] = &values[i]
}
results := make(map[int]map[string]string) //最后得到的map
i := 0
for query.Next() { //循环,让游标往下移动
if err := query.Scan(scans...); err != nil {
//query.Scan查询出来的不定长值放到scans[i] = &values[i],也就是每行都放在values里
fmt.Println(err)
return
}
row := make(map[string]string) //每行数据
for k, v := range values { //每行数据是放在values里面,现在把它挪到row里
key := column[k]
row[key] = string(v)
}
results[i] = row //装入结果集中
i++
}
for k, v := range results { //查询出来的数组
fmt.Println(k, v)
}
}
func main() {
db, err := sql.Open("mysql", "yuanye:yuanye@tcp(127.0.0.1:3306)/test?charset=utf8")
checkErr(err)
//使用sql语句创建一个user表
db.Query("create table user(id int primary key , username varchar(20), password varchar(20))")
//向user表中插入数据
db.Query("insert into user(username,password) values('yy', '123456')")
//查询数据库插入的数据
v, err := db.Query("select * from user")
checkErr(err)
//打印查询结果
printResult(v)
db.Query("update user set username = 'tt'")
//查询数据库插入的数据
v, err = db.Query("select * from user")
checkErr(err)
//打印查询结果
printResult(v)
db.Query("delete from user where id = 1")
}
使用xorm基本操作
安装xorm框架 go get github.com/go-xorm/cmd/xorm
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/go-xorm/xorm"
)
type Person struct {
Id int64 `xorm:"pk autoincr"`
Name string `xorm:"varchar(25) notnull unique"`
}
var engine *xorm.Engine
func checkErr(errMasg error) {
if errMasg != nil {
panic(errMasg)
}
}
func main() {
var err error
//与数据库建立链接
engine, err = xorm.NewEngine("mysql", "yuanye:yuanye@tcp(127.0.0.1:3306)/test?charset=utf8")
checkErr(err)
//在控制台打印sql语句,默认为false
engine.ShowSQL(true)
//同步数据库结构
err = engine.Sync2(new(Person))
p := Person{
Name: "yuanye",
}
//插入数据
engine.Insert(&p)
//查询id为1的数据
p1 := Person{}
engine.Id(1).Get(&p1)
fmt.Println(p1)
//查询name为yuanye的数据
p2 := Person{}
engine.Where("name = ?", "yuanye").Get(&p2)
fmt.Println(p2)
//根据user结构体中已有的非空数据来查看数据是否存在
p3 := &Person{Name: "yuanye"}
has, _ := engine.Get(p3)
fmt.Println(has)
//根据条件统计数量
p4 := new(Person)
total, _ := engine.Where("name = ?", "yuanye").Count(p4)
fmt.Println(total)
//修改name为“yy”
p5 := Person{Name: "yy"}
engine.Id(1).Update(&p5)
//find用于查询多条数据,可以传入切片、map地址,也可以使用where添加条件
p6 := make([]Person, 0)
engine.Find(&p6)
fmt.Println(p6)
//删除id=1的记录
p7 := Person{}
engine.Id(1).Delete(&p7)
has, _ = engine.Id(1).Get(&p7)
fmt.Println(has)
}
数据库列属性定义:
具体的Tag规则如下,另Tag中的关键字均不区分大小写,但字段名根据不同的数据库是区分大小写
name | 当前field对应的字段的名称,可选,如不写,则自动根据field名字和转换规则命名,如与其它关键字冲突,请使用单引号括起来。 |
---|---|
pk | 是否是Primary Key,如果在一个struct中有多个字段都使用了此标记,则这多个字段构成了复合主键,单主键当前支持int32,int,int64,uint32,uint,uint64,string这7种Go的数据类型,复合主键支持这7种Go的数据类型的组合。 |
当前支持30多种字段类型,详情参见本文最后一个表格 | 字段类型 |
autoincr | 是否是自增 |
[not ]null 或 notnull | 是否可以为空 |
unique或unique(uniquename) | 是否是唯一,如不加括号则该字段不允许重复;如加上括号,则括号中为联合唯一索引的名字,此时如果有另外一个或多个字段和本unique的uniquename相同,则这些uniquename相同的字段组成联合唯一索引 |
index或index(indexname) | 是否是索引,如不加括号则该字段自身为索引,如加上括号,则括号中为联合索引的名字,此时如果有另外一个或多个字段和本index的indexname相同,则这些indexname相同的字段组成联合索引 |
extends | 应用于一个匿名成员结构体或者非匿名成员结构体之上,表示此结构体的所有成员也映射到数据库中,不过extends只加载一级深度 |
- | 这个Field将不进行字段映射 |
-> | 这个Field将只写入到数据库而不从数据库读取 |
<- | 这个Field将只从数据库读取,而不写入到数据库 |
created | 这个Field将在Insert时自动赋值为当前时间 |
updated | 这个Field将在Insert或Update时自动赋值为当前时间 |
deleted | 这个Field将在Delete时设置为当前时间,并且当前记录不删除 |
version | 这个Field将会在insert时默认为1,每次更新自动加1 |
default 0 | 设置默认值,紧跟的内容如果是Varchar等需要加上单引号 |