使用go进行项目开发,大多数人会使用gorm,但是gorm有一些缺点,我无法接受。于是开发出了aorm,目前能有满足日常开发需求,并且完善了使用文档,希望能够帮助到大家。
Aorm
Golang操作数据库如此简单
给个 吧,如果这个项目帮助到你
特性
代码简洁,高性能
支持 MySQL 数据库
支持 空值查询
支持 自动迁移
支持 SQL 拼接
支持 其他数据库, 例如 MSSQL
如何使用
导入
定义数据结构
连接数据库
自动迁移
基本的增删改查
增加一条记录
获取一条记录
获取多条记录
更新记录
删除记录
高级查询
查询指定表
查询指定字段
查询条件
查询条件相关操作
联合查询
分组查询
筛选
排序
分页查询
悲观锁
自增操作
自减操作
查询某字段的值(字符串)
查询某字段的值(Int64)
查询某字段的值(Float32)
查询某字段的值(Float64)
聚合查询
Count
Sum
AVG
Min
Max
通用操作
Query
Exec
事务操作
清空表数据
工具类
导入
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"github.com/tangpanqing/aorm"
)
database/sql
是golang的标准库,提供了操作数据库的接口
github.com/go-sql-driver/mysql
操作mysql数据库的驱动
github.com/tangpanqing/aorm
对sql的操作进行包装,使用起来更方便
你可以使用如下命令下载和使用他们
go get -u github.com/go-sql-driver/mysql
go get -u github.com/tangpanqing/aorm
定义数据结构
type Person struct {
Id aorm.Int `aorm:"primary;auto_increment" json:"id"`
Name aorm.String `aorm:"size:100;not null;comment:名字" json:"name"`
Sex aorm.Bool `aorm:"index;comment:性别" json:"sex"`
Age aorm.Int `aorm:"index;comment:年龄" json:"age"`
Type aorm.Int `aorm:"index;comment:类型" json:"type"`
CreateTime aorm.Time `aorm:"comment:创建时间" json:"createTime"`
Money aorm.Float `aorm:"comment:金额" json:"money"`
Test aorm.Float `aorm:"type:double;comment:测试" json:"test"`
}
连接数据库
//connect
db, err := sql.Open("mysql", "root:root@tcp(localhost:3306)/database_name?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
//ping test
err1 := db.Ping()
if err1 != nil {
panic(err1)
}
自动迁移
使用 AutoMigrate
方法, 表名将是结构体名字的下划线形式,如person
aorm.Use(db).Opinion("ENGINE", "InnoDB").Opinion("COMMENT", "用户表").AutoMigrate(&Person{})
使用 Migrate
方法, 你可以使用其他的表名
aorm.Use(db).Opinion("ENGINE", "InnoDB").Opinion("COMMENT", "用户表").Migrate("person_1", &Person{})
使用 ShowCreateTable
方法, 你可以获得创建表的sql语句
showCreate := aorm.Use(db).ShowCreateTable("person")
fmt.Println(showCreate)
如下
CREATE TABLE `person` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '名字',
`sex` tinyint DEFAULT NULL COMMENT '性别',
`age` int DEFAULT NULL COMMENT '年龄',
`type` int DEFAULT NULL COMMENT '类型',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`money` float DEFAULT NULL COMMENT '金额',
`article_body` text COLLATE utf8mb4_general_ci COMMENT '文章内容',
`test` double DEFAULT NULL COMMENT '测试',
PRIMARY KEY (`id`),
KEY `idx_person_sex` (`sex`),
KEY `idx_person_age` (`age`),
KEY `idx_person_type` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='人员表'
基本的增删改查
增加一条记录
id, errInsert := aorm.Use(db).Debug(true).Insert(&Person{
Name: aorm.StringFrom("Alice"),
Sex: aorm.BoolFrom(false),
Age: aorm.IntFrom(18),
Type: aorm.IntFrom(0),
CreateTime: aorm.TimeFrom(time.Now()),
Money: aorm.FloatFrom(100.15987654321),
Test: aorm.FloatFrom(200.15987654321987654321),
})
if errInsert != nil {
fmt.Println(errInsert)
}
fmt.Println(id)
上述代码运行后得到的SQL预处理语句以及相关参数如下
INSERT INTO person (name,sex,age,type,create_time,money,test) VALUES (?,?,?,?,?,?,?)
Alice false 18 0 2022-12-07 10:10:26.1450773 +0800 CST m=+0.031808801 100.15987654321 200.15987654321987
获取一条记录
var person Person
errFind := aorm.Use(db).Debug(true).Where(&Person{Id: aorm.IntFrom(id)}).GetOne(&person)
if errFind != nil {
fmt.Println(errFind)
}
fmt.Println(person)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT * FROM person WHERE id = ? Limit ?,?
1 0 1
获取多条记录
var list []Person
errSelect := aorm.Use(db).Debug(true).Where(&Person{Type: aorm.IntFrom(0)}).GetMany(&list)
if errSelect != nil {
fmt.Println(errSelect)
}
for i := 0; i < len(list); i++ {
fmt.Println(list[i])
}
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT * FROM person WHERE type = ?
0
更新记录
countUpdate, errUpdate := aorm.Use(db).Debug(true).Where(&Person{Id: aorm.IntFrom(id)}).Update(&Person{Name: aorm.StringFrom("Bob")})
if errUpdate != nil {
fmt.Println(errUpdate)
}
fmt.Println(countUpdate)
上述代码运行后得到的SQL预处理语句以及相关参数如下
UPDATE person SET name=? WHERE id = ?
Bob 1
删除记录
countDelete, errDelete := aorm.Use(db).Debug(true).Where(&Person{Id: aorm.IntFrom(id)}).Delete()
if errDelete != nil {
fmt.Println(errDelete)
}
fmt.Println(countDelete)
上述代码运行后得到的SQL预处理语句以及相关参数如下
DELETE FROM person WHERE id = ?
1
高级查询
查询指定表
使用 Table
方法, 你可以在查询时指定表名
aorm.Use(db).Debug(true).Table("person_1").Insert(&Person{Name: aorm.StringFrom("Cherry")})
上述代码运行后得到的SQL预处理语句以及相关参数如下
INSERT INTO person_1 (name) VALUES (?)
Cherry
查询指定字段
使用 Select
方法, 你可以在查询时指定字段
var listByFiled []Person
aorm.Use(db).Debug(true).Select("name,age").Where(&Person{Age: aorm.IntFrom(18)}).GetMany(&listByFiled)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT name,age FROM person WHERE age = ?
18
查询条件
使用 WhereArr
方法, 你可以在查询时添加更多查询条件
var listByWhere []Person
var where1 []aorm.WhereItem
where1 = append(where1, aorm.WhereItem{Field: "type", Opt: aorm.Eq, Val: 0})
where1 = append(where1, aorm.WhereItem{Field: "age", Opt: aorm.In, Val: []int{18, 20}})
where1 = append(where1, aorm.WhereItem{Field: "money", Opt: aorm.Between, Val: []float64{100.1, 200.9}})
where1 = append(where1, aorm.WhereItem{Field: "money", Opt: aorm.Eq, Val: 100.15})
where1 = append(where1, aorm.WhereItem{Field: "name", Opt: aorm.Like, Val: []string{"%", "li", "%"}})
aorm.Use(db).Debug(true).Table("person").WhereArr(where1).GetMany(&listByWhere)
for i := 0; i < len(listByWhere); i++ {
fmt.Println(listByWhere[i])
}
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT * FROM person WHERE type = ? AND age IN (?,?) AND money BETWEEN (?) AND (?) AND CONCAT(money,'') = ? AND name LIKE concat('%',?,'%')
0 18 20 100.1 200.9 100.15 li
查询条件相关操作
aorm.Eq
等同于 =
aorm.Ne
等同于 !=
aorm.Gt
等同于 >
aorm.Ge
等同于 >=
aorm.Lt
等同于 <
aorm.Le
等同于 <=
aorm.In
等同于 IN
aorm.NotIn
等同于 NOT IN
aorm.Like
等同于 LIKE
aorm.NotLike
等同于 NOT LIKE
aorm.Between
等同于 BETWEEN
aorm.NotBetween
等同于 NOT BETWEEN
联合查询
使用 LeftJoin
方法, 你可以使用联合查询
var list2 []ArticleVO
var where2 []aorm.WhereItem
where2 = append(where2, aorm.WhereItem{Field: "o.type", Opt: aorm.Eq, Val: 0})
where2 = append(where2, aorm.WhereItem{Field: "p.age", Opt: aorm.In, Val: []int{18, 20}})
aorm.Use(db).Debug(true).
Table("article o").
LeftJoin("person p", "p.id=o.person_id").
Select("o.*").
Select("p.name as person_name").
WhereArr(where2).
GetMany(&list2)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT o.*,p.name as person_name FROM article o LEFT JOIN person p ON p.id=o.person_id WHERE o.type = ? AND p.age IN (?,?)
0 18 20
其他的联合查询方法还有 RightJoin
, Join
分组查询
使用 GroupBy
方法, 你可以进行分组查询
type PersonAge struct {
Age aorm.Int
AgeCount aorm.Int
}
var personAge PersonAge
var where []aorm.WhereItem
where = append(where, aorm.WhereItem{Field: "type", Opt: aorm.Eq, Val: 0})
err := aorm.Use(db).Debug(true).
Table("person").
Select("age").
Select("count(age) as age_count").
GroupBy("age").
WhereArr(where).
GetOne(&personAge)
if err != nil {
panic(err)
}
fmt.Println(personAge)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT age,count(age) as age_count FROM person WHERE type = ? GROUP BY age Limit ?,?
0 0 1
筛选
使用 HavingArr
以及 Having
方法, 你可以对分组查询的结果进行筛选
var listByHaving []PersonAge
var where3 []aorm.WhereItem
where3 = append(where3, aorm.WhereItem{Field: "type", Opt: aorm.Eq, Val: 0})
var having []aorm.WhereItem
having = append(having, aorm.WhereItem{Field: "age_count", Opt: aorm.Gt, Val: 4})
err := aorm.Use(db).Debug(true).
Table("person").
Select("age").
Select("count(age) as age_count").
GroupBy("age").
WhereArr(where3).
HavingArr(having).
GetMany(&listByHaving)
if err != nil {
panic(err)
}
fmt.Println(listByHaving)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT age,count(age) as age_count FROM person WHERE type = ? GROUP BY age Having age_count > ?
0 4
排序
使用 OrderBy
方法, 你可以对查询结果进行排序
var listByOrder []Person
var where []aorm.WhereItem
where = append(where, aorm.WhereItem{Field: "type", Opt: aorm.Eq, Val: 0})
err := aorm.Use(db).Debug(true).
Table("person").
WhereArr(where).
OrderBy("age", aorm.Desc).
GetMany(&listByOrder)
if err != nil {
panic(err)
}
fmt.Println(listByOrder)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT * FROM person WHERE type = ? Order BY age DESC
0
分页查询
使用 Limit
或者 Page
方法, 你可以进行分页查询
var list3 []Person
var where1 []aorm.WhereItem
where1 = append(where1, aorm.WhereItem{Field: "type", Opt: aorm.Eq, Val: 0})
err1 := aorm.Use(db).Debug(true).
Table("person").
WhereArr(where1).
Limit(50, 10).
GetMany(&list3)
if err1 != nil {
panic(err1)
}
fmt.Println(list3)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT * FROM person WHERE type = ? Limit ?,?
0 50 10
var list4 []Person
var where2 []aorm.WhereItem
where2 = append(where2, aorm.WhereItem{Field: "type", Opt: aorm.Eq, Val: 0})
err := aorm.Use(db).Debug(true).
Table("person").
WhereArr(where2).
Page(3, 10).
GetMany(&list4)
if err != nil {
panic(err)
}
fmt.Println(list4)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT * FROM person WHERE type = ? Limit ?,?
0 20 10
悲观锁
使用 LockForUpdate
方法, 你可以在查询时候锁住某些记录,禁止他们被修改
var itemByLock Person
err := aorm.Use(db).Debug(true).LockForUpdate(true).Where(&Person{Id: aorm.IntFrom(id)}).GetOne(&itemByLock)
if err != nil {
panic(err)
}
fmt.Println(itemByLock)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT * FROM person WHERE id = ? Limit ?,? FOR UPDATE
2 0 1
自增操作
使用 Increment
方法, 你可以直接操作某字段增加数值
count, err := aorm.Use(db).Debug(true).Where(&Person{Id: aorm.IntFrom(id)}).Increment("age", 1)
if err != nil {
panic(err)
}
fmt.Println(count)
上述代码运行后得到的SQL预处理语句以及相关参数如下
UPDATE person SET age=age+? WHERE id = ?
1 2
自减操作
使用 Decrement
方法, 你可以直接操作某字段减少数值
count, err := aorm.Use(db).Debug(true).Where(&Person{Id: aorm.IntFrom(id)}).Decrement("age", 2)
if err != nil {
panic(err)
}
fmt.Println(count)
上述代码运行后得到的SQL预处理语句以及相关参数如下
UPDATE person SET age=age-? WHERE id = ?
2 2
查询某字段的值(字符串)
使用 Value
方法, 你可以直接获取到某字段的值。
注意,返回值是字符串
name, err := aorm.Use(db).Debug(true).Where(&Person{Id: aorm.IntFrom(id)}).Value("name")
if err != nil {
panic(err)
}
fmt.Println(name)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT name FROM person WHERE id = ? Limit ?,?
2 0 1
打印结果为 Alice
查询某字段的值(Int64)
使用 ValueInt64
方法, 你可以直接获取到某字段的值。
注意,返回值是Int64
age, err := aorm.Use(db).Debug(true).Where(&Person{Id: aorm.IntFrom(id)}).ValueInt64("age")
if err != nil {
panic(err)
}
fmt.Println(age)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT age FROM person WHERE id = ? Limit ?,?
2 0 1
打印结果为 17
查询某字段的值(Float32)
使用 ValueFloat32
方法, 你可以直接获取到某字段的值。
注意,返回值是Float32
money, err := aorm.Use(db).Debug(true).Where(&Person{Id: aorm.IntFrom(id)}).ValueFloat32("money")
if err != nil {
panic(err)
}
fmt.Println(money)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT money FROM person WHERE id = ? Limit ?,?
2 0 1
打印结果为 100.159874
查询某字段的值(Float64)
使用 ValueFloat64
方法, 你可以直接获取到某字段的值。
注意,返回值是Float64
test, err := aorm.Use(db).Debug(true).Where(&Person{Id: aorm.IntFrom(id)}).ValueFloat64("test")
if err != nil {
panic(err)
}
fmt.Println(test)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT test FROM person WHERE id = ? Limit ?,?
2 0 1
打印结果为 200.15987654321987
聚合查询
Count
使用 Count
方法, 你可以查询出记录总数量
count, err := aorm.Use(db).Debug(true).Where(&Person{Age: aorm.IntFrom(18)}).Count("*")
if err != nil {
panic(err)
}
fmt.Println(count)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT count(*) as c FROM person WHERE age = ?
18
Sum
使用 Sum
方法, 你可以查询出符合条件的某字段之和
sum, err := aorm.Use(db).Debug(true).Where(&Person{Age: aorm.IntFrom(18)}).Sum("age")
if err != nil {
panic(err)
}
fmt.Println(sum)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT sum(age) as c FROM person WHERE age = ?
18
Avg
使用 Avg
方法, 你可以查询出符合条件的某字段平均值
avg, err := aorm.Use(db).Debug(true).Where(&Person{Age: aorm.IntFrom(18)}).Avg("age")
if err != nil {
panic(err)
}
fmt.Println(avg)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT avg(age) as c FROM person WHERE age = ?
18
Min
使用 Min
方法, 你可以查询出符合条件的某字段最小值
min, err := aorm.Use(db).Debug(true).Where(&Person{Age: aorm.IntFrom(18)}).Min("age")
if err != nil {
panic(err)
}
fmt.Println(min)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT min(age) as c FROM person WHERE age = ?
18
Max
使用 Max
方法, 你可以查询出符合条件的某字段最大值
max, err := aorm.Use(db).Debug(true).Where(&Person{Age: aorm.IntFrom(18)}).Max("age")
if err != nil {
panic(err)
}
fmt.Println(max)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT max(age) as c FROM person WHERE age = ?
18
通用操作
使用 Query
方法, 你可以执行自定义的查询
Query
resQuery, err := aorm.Use(db).Debug(true).Query("SELECT * FROM person WHERE id=? AND type=?", 1, 3)
if err != nil {
panic(err)
}
fmt.Println(resQuery)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT * FROM person WHERE id=? AND type=?
1 3
Exec
使用 Exec
方法, 你可以执行自定义的修改操作
resExec, err := aorm.Use(db).Debug(true).Exec("UPDATE person SET name = ? WHERE id=?", "Bob", 3)
if err != nil {
panic(err)
}
fmt.Println(resExec.RowsAffected())
上述代码运行后得到的SQL预处理语句以及相关参数如下
UPDATE person SET name = ? WHERE id=?
Bob 3
事务操作
使用 db
的 Begin
方法, 开始一个事务
然后使用 Commit
方法提交事务,Rollback
方法回滚事务
tx, _ := db.Begin()
id, errInsert := aorm.Use(tx).Insert(&Person{
Name: aorm.StringFrom("Alice"),
})
if errInsert != nil {
fmt.Println(errInsert)
tx.Rollback()
return
}
countUpdate, errUpdate := aorm.Use(tx).Where(&Person{
Id: aorm.IntFrom(id),
}).Update(&Person{
Name: aorm.StringFrom("Bob"),
})
if errUpdate != nil {
fmt.Println(errUpdate)
tx.Rollback()
return
}
fmt.Println(countUpdate)
tx.Commit()
上述代码运行后得到的SQL预处理语句以及相关参数如下
INSERT INTO person (name) VALUES (?)
Alice
UPDATE person SET name=? WHERE id = ?
Bob 3
清空表数据
使用 Truncate
方法, 你可以很方便的清空一个表
count, err := aorm.Use(db).Table("person").Truncate()
if err != nil {
panic(err)
}
fmt.Println(count)
上述代码运行后得到的SQL预处理语句以及相关参数如下
TRUNCATE TABLE person
工具类
使用 Ul
或者 UnderLine
方法, 你可以将一个字符串从驼峰写法转换成下划线写法
例如, 转换 personId
成 person_id
var list2 []ArticleVO
var where2 []aorm.WhereItem
where2 = append(where2, aorm.WhereItem{Field: "o.type", Opt: aorm.Eq, Val: 0})
where2 = append(where2, aorm.WhereItem{Field: "p.age", Opt: aorm.In, Val: []int{18, 20}})
aorm.Use(db).Debug(true).
Table("article o").
LeftJoin("person p", aorm.Ul("p.id=o.personId")).
Select("o.*").
Select(aorm.Ul("p.name as personName")).
WhereArr(where2).
GetMany(&list2)
上述代码运行后得到的SQL预处理语句以及相关参数如下
SELECT o.*,p.name as person_name FROM article o LEFT JOIN person p ON p.id=o.person_id WHERE o.type = ? AND p.age IN (?,?)
0 18 20
作者
tangpanqing
Twitter: @tangpanqing
Github: @tangpanqing
希望能得到你的支持
给个 吧,如果这个项目帮助到你