ggm
golang generic orm, base on sqlx
install
go get github.com/daodao97/ggm
usage
Below is an example which shows some common use cases for ggm. Check model_test.go for more usage.
init db
We can initialize some db resources commonly used by programs, like this
// map[conn_name]db_config
ggm.Init(map[string]*ggm.Config{
"default": {
DSN: "root@tcp(127.0.0.1:3306)/ggm_test?&parseTime=true",
},
})
Of course, we can also instantiate some temporary DB resources, like this
m := ggm.NewConn(&ggm.Config{
DSN: "root@tcp(127.0.0.1:3306)/ggm_test?&parseTime=true"
})
data model
For example, we have a table with the following structure
CREATE TABLE `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`status` tinyint(4) NOT NULL DEFAULT '0',
`profile` varchar(200) NOT NULL,
`is_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0',
`ctime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`mtime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
struct define
The structure model for this table is
type User struct {
Id int `db:"id,pk" json:"id"`
Name string `db:"name" json:"name"`
Profile string `db:"profile" json:"profile"`
CTime time.Time `db:"ctime" json:"ctime"`
}
func (u User) Table() string {
return "user"
}
interface: Table() string
the struct must implement.
struct field must have db
tag, value is db field name.
set conn
If you are using a db resource that is not the default
func (u User) Conn() string {
return "conn_name"
}
fake delete
If you have a field to mark fake delete
func (u User) FakeDeleteKey() string {
return "is_deleted"
}
then, the delete sql
will converted to update ${fakeDeleteKey} = 1
when we delete data
select sql
will auto add ${fackDeleteKey} = 0
, to filter deleted data.
select
m := ggm.New[*User]() // or ggm.New[User]()
m.Select(ggm.WhereEq("id", 1))
detail of where condition
see where condition
insert
user := &User{Name: "Seiya"}
// single insert
m.Insert(user)
// batch insert
m.Insert(user, user2, ...)
update
use primary key update
user := &User{Id: 1, Name: "Seiya!!!"}
m.Update(user)
with where condition
user := &User{Name: "Seiya!!!"}
m.Update(user, ggm.WhereEq("id", 1))
delete
m.Delete(ggm.WhereEq("id", 1))
where condition
m.Select(
WhereEq("id", 1),
WhereGt("age", 20),
WhereLike("name", "dd"),
WhereGroup(
WhereEq("sex", 1),
WhereOrEq("class", 2),
WhereGroup(
WhereEq("sex1", 1),
WhereEq("class2", 2),
),
),
OrderBy("id", DESC),
)
more example, checkout sql_test.go
data type
Json
If the value of field user.profile
is json_string
like {"skill":"Pegasus Ryuseiken"}
type User struct {
Id int `db:"id,pk" json:"id"`
Name string `db:"name" json:"name"`
Profile *ggm.Json[*Profile] `db:"profile" json:"profile"`
CTime time.Time `db:"ctime" json:"ctime"`
}
type Profile struct {
Skill string `json:"skill"`
}
Profile{Skill: "xxx"}
<==> '{"skill":"xxx"}'
Data can be automatically converted into struct for use by programs.
Time
type User struct {
Id int `db:"id,pk" json:"id"`
Name string `db:"name" json:"name"`
Profile *ggm.Json[*Profile] `db:"profile" json:"profile"`
CTime ggm.Time `db:"ctime" json:"ctime"`
}
when api response or json.Marshal
ctime : 2022-03-19T11:52:19Z
=> 2022-03-19 11:52:19
define yourself data type
Implement the following interfaces
type DataType[T any] interface {
Value() (driver.Value, error)
Scan(value any) error
MarshalJSON() ([]byte, error)
UnmarshalJSON(b []byte) error
Get() T
}
Linked data
hasOne
one to one
type User struct {
Id int `db:"id,pk" json:"id"`
Name string `db:"name" json:"name"`
Profile *Json[*Profile] `db:"profile" json:"profile"`
Score int `db:"score" json:"score" hasOne:"user_score:uid"`
Score2 int `db:"score2" json:"score2" hasOne:"user_score:uid"`
}
hasMany
one to N
type User struct {
Id int `db:"id,pk" json:"id"`
Name string `db:"name" json:"name"`
Profile *Json[*Profile] `db:"profile" json:"profile"`
Logs []*Log `json:"logs" hasMany:"user_log:uid"`
}
type Log struct {
Message string `db:"message" json:"message"`
}
hasOne or hasMany tag token:
[conn.][database.]table:[local_key->]foreign_key
m.Select()
will auto query the linked data into the struct.
Check model_test.go for detail.
Top comments (0)