想早点下班?试试Aorm库吧,更方便的进行Go数据库操作

2023-02-12,,,,

使用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

事务操作

使用 dbBegin 方法, 开始一个事务

然后使用 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 方法, 你可以将一个字符串从驼峰写法转换成下划线写法

例如, 转换 personIdperson_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

希望能得到你的支持

给个 吧,如果这个项目帮助到你

早点下班试试Aorm库吧,更方便的进行Go数据库操作的相关教程结束。

《想早点下班?试试Aorm库吧,更方便的进行Go数据库操作.doc》

下载本文的Word格式文档,以方便收藏与打印。