osm
osm(Object Sql Mapping And Template)是用go编写的ORM工具,目前已在生产环境中使用,只支持mysql和postgresql(其他数据库没有测试过)。
以前是使用MyBatis开发java服务端,它的sql mapping很灵活,把sql独立出来,程序通过输入与输出来完成所有的数据库操作。
osm就是对MyBatis的简单模仿。当然动态sql的生成是使用go和template包,所以sql mapping的格式与MyBatis的不同。sql xml 格式如下:
SELECT id,email
FROM user
{{if ne .Email ""}} where email=#{Email} {{end}}
order by id
osm获取
go get github.com/yinshuwei/osm
api doc
Quickstart
创建数据库
create database test;
use test;
创建user表
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(255) DEFAULT NULL,
`nickname` varchar(45) DEFAULT NULL,
`create_time` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='user table';
sql template文件test.xml
INSERT INTO user (email,nickname,create_time) VALUES (#{Email},#{Nickname},#{CreateTime});
]]>
SELECT id,email,nickname,create_time FROM user
WHERE
{{if ne .Email ""}}email=#{Email} and{{end}}
{{if ne .Nickname ""}}nickname=#{Nickname} and{{end}}
1=1;
]]>
DELETE FROM user WHERE email=#{Email}
]]>
example.go
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/yinshuwei/osm"
"time"
)
type User struct {
Id int64
Email string
Nickname string
CreateTime time.Time
}
func main() {
o, err := osm.New("mysql", "root:root@/test?charset=utf8", []string{"test.xml"})
if err != nil {
fmt.Println(err.Error())
}
//添加
user := User{
Email: "test@foxmail.com",
Nickname: "haha",
CreateTime: time.Now(),
}
fmt.Println(o.Insert("insertUser", user))
//动态查询
user = User{
Email: "test@foxmail.com",
}
var results []User
o.Select("selectUser", user)(&results)
for _, u := range results {
fmt.Println(u)
}
//删除
fmt.Println(o.Delete("deleteUser", user))
err = o.Close()
if err != nil {
fmt.Println(err.Error())
}
}
查询结果类型
value 查出的结果为单行,并存入不定长的变量上(...)
xml
SELECT id, email, head_image_url FROM res_user WHERE email=#{Email};
go
user := ResUser{Email: "test@foxmail.com"}
var id int64
var email, headImageURL string
o.Select("selectResUserValue", user)(&id, &email, &headImageURL)
log.Println(id, email, headImageURL)
values 查出的结果为多行,并存入不定长的变量上(...,每个都为array,每个array长度都与结果集行数相同)
xml
SELECT id,email,head_image_url FROM res_user WHERE city=#{City} order by id;
go
user := ResUser{City: "上海"}
var ids []int64
var emails, headImageUrls []string
o.Select("selectResUserValues", user)(&ids, &emails, &headImageUrls)
log.Println(ids, emails, headImageUrls)
struct 查出的结果为单行,并存入struct
xml
SELECT id, email, head_image_url FROM res_user WHERE email=#{Email};
go
user := ResUser{Email: "test@foxmail.com"}
var result ResUser
o.Select("selectResUser", user)(&result)
log.Printf("%#v", result)
structs 查出的结果为多行,并存入struct array
xml
SELECT id,email,head_image_url FROM res_user WHERE city=#{City} order by id;
go
user := ResUser{City: "上海"}
var results []*ResUser // 或var results []ResUser
o.Select("selectResUsers", user)(&results)
log.Printf("%#v", results)
kvs 查出的结果为多行,每行有两个字段,前者为key,后者为value,存入map (双列)
xml
SELECT id,email FROM res_user WHERE city=#{City} order by id;
go
user := ResUser{City: "上海"}
var idEmailMap map[int64]string
o.Select("selectResUserKvs", user)(&idEmailMap)
log.Println(idEmailMap)
struct与SQL列对应关系
正常的转换过程
用"_"分隔 (例:XXX_YYY -> XXX,YYY)
每个部分全部转为首字大写其余字符小写 (例:XXX,YYY -> Xxx,Yyy)
拼接(例:Xxx,Yyy -> XxxYyy)
常见缩写单词,下面这些单词两种形式都可以,struct上可以任选其一。
比如"UserId"和"UserID"可以正常对应到"user_id"列上。但是同一个struct中不可以既有"UserId"成员又有"UserID"成员,如查同时存在只会有一个成员会被赋值。
Acl 或 ACL
Api 或 API
Ascii 或 ASCII
Cpu 或 CPU
Css 或 CSS
Dns 或 DNS
Eof 或 EOF
Guid 或 GUID
Html 或 HTML
Http 或 HTTP
Https 或 HTTPS
Id 或 ID
Ip 或 IP
Json 或 JSON
Lhs 或 LHS
Qps 或 QPS
Ram 或 RAM
Rhs 或 RHS
Rpc 或 RPC
Sla 或 SLA
Smtp 或 SMTP
Sql 或 SQL
Ssh 或 SSH
Tcp 或 TCP
Tls 或 TLS
Ttl 或 TTL
Udp 或 UDP
Ui 或 UI
Uid 或 UID
Uuid 或 UUID
Uri 或 URI
Url 或 URL
Utf8 或 UTF8
Vm 或 VM
Xml 或 XML
Xmpp 或 XMPP
Xsrf 或 XSRF
Xss 或 XSS