- 文檔
前言
學習過原生的Go鏈接Mysql的方法,使用Go自帶的“database/sql”數據庫鏈接api。
“github.com/go-sql-driver/mysql”mysql驅動,通過比較原生的方法去寫sql和處理事務。
目前開源界也有好多封裝好的Orm操作框架:
Java系(Mybatis,MybatisPlus,hibernate ...)
Go系 (xorm,gorm,gomybatis ...)
總所周知,在java/go系orm框架中,國外互聯網公司程序員喜歡用hibernate/gorm(這是因為國外產品穩定,需求 清晰,代碼素質普遍高),反觀國內java系互聯網公司則喜歡mybatis之流(需求頻繁變動,水平參差不齊,sql優化方便) - 我的觀點
JPA/Hibernate.Gorm之流都比較復雜,團隊中要有人Hold住它,否則后期及其容易踩坑;
Mybatis框架直觀,但是基本crud功能應該簡化一下,畢竟重復度極高(重點:而且簡化的同時可以擴展邏輯)
GoMybatis 框架介紹:
GoMybatis是一款總結了以上許多框架的優缺點的ORM框架,並且極力希望在 維護性/可讀性/性能/易用性/之上做到均衡(正如go的思想一樣,大道至簡)
項目地址 https://github.com/zhuxiujia/GoMybatis
GoMybatis並不是一夜之間想出來的,之前閱讀過Hibernate、MybatisPlus ,xorm,gorm,gobatis(需要go generate生成中間代碼)還有go標准庫(database/sql)的部分源碼,總結經驗而來。
-
GoMybatis 特性介紹: 整體基於標准庫“database/sql”開發而來,干凈無依賴,結構體+閉包+反射+代理實現 而不是使用go generate生成*.go等中間代碼(利用反射函數閉包解決了gobatis框架免去生成代碼的缺陷)
吸收mybatis plus框架樂觀鎖,邏輯刪除功能(當然你也可以手動在sql中加入,就是比較繁瑣 好處是可讀性高)
實現了AST抽象語法樹,能在#{}表達式中靈活使用公式
增加了模板標簽,減少普通CRUD操作的重復度(mybatis框架是沒有的,意味着普通增刪改查也得寫sql) -
gomybatis+mysql數據庫使用教程:
使用教程
教程源碼 https://github.com/zhuxiujia/GoMybatis/tree/master/example
設置好GoPath,用go get 命令下載GoMybatis和對應的數據庫驅動
go get github.com/zhuxiujia/GoMybatis go get github.com/go-sql-driver/mysql
實際使用mapper 定義xml內容,建議以*Mapper.xml文件存於項目目錄中,在編輯xml時就可享受GoLand等IDE渲染和智能提示。生產環境可以使用statikFS把xml文件打包進程序里
var xmlBytes = []byte(`
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://raw.githubusercontent.com/zhuxiujia/GoMybatis/master/mybatis-3-mapper.dtd"> <mapper> <select id="SelectAll"> select * from biz_activity where delete_flag=1 order by create_time desc </select> </mapper> `)
import ( "fmt" _ "github.com/go-sql-driver/mysql" //選擇需要的數據庫驅動導入 "github.com/zhuxiujia/GoMybatis" ) type ExampleActivityMapperImpl struct { SelectAll func() ([]Activity, error) } func main() { var engine = GoMybatis.GoMybatisEngine{}.New() //Mysql鏈接格式 用戶名:密碼@(數據庫鏈接地址:端口)/數據庫名稱,如root:123456@(***.com:3306)/test err := engine.Open("mysql", "*?charset=utf8&parseTime=True&loc=Local") if err != nil { panic(err) } var exampleActivityMapperImpl ExampleActivityMapperImpl //加載xml實現邏輯到ExampleActivityMapperImpl engine.WriteMapperPtr(&exampleActivityMapperImpl, xmlBytes) //使用mapper result, err := exampleActivityMapperImpl.SelectAll(&result) if err != nil { panic(err) } fmt.Println(result) }
功能:模板標簽CRUD 簡化(必須依賴一個resultMap 標簽)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://raw.githubusercontent.com/zhuxiujia/GoMybatis/master/mybatis-3-mapper.dtd"> <mapper> <!--logic_enable 邏輯刪除字段--> <!--logic_deleted 邏輯刪除已刪除字段--> <!--logic_undelete 邏輯刪除 未刪除字段--> <!--version_enable 樂觀鎖版本字段,支持int,int8,int16,int32,int64--> <resultMap id="BaseResultMap" tables="biz_activity"> <id column="id" property="id"/> <result column="name" property="name" langType="string"/> <result column="pc_link" property="pcLink" langType="string"/> <result column="h5_link" property="h5Link" langType="string"/> <result column="remark" property="remark" langType="string"/> <result column="version" property="version" langType="int" version_enable="true"/> <result column="create_time" property="createTime" langType="time.Time"/> <result column="delete_flag" property="deleteFlag" langType="int" logic_enable="true" logic_undelete="1" logic_deleted="0"/> </resultMap> <!--模板標簽: columns wheres sets 支持逗號,分隔表達式,*?* 為判空表達式--> <!--插入模板:默認id="insertTemplete,test="field != null",where自動設置邏輯刪除字段,支持批量插入" --> <insertTemplete/> <!--查詢模板:默認id="selectTemplete,where自動設置邏輯刪除字段--> <selectTemplete wheres="name?name = #{name}"/> <!--更新模板:默認id="updateTemplete,set自動設置樂觀鎖版本號--> <updateTemplete sets="name?name = #{name},remark?remark=#{remark}" wheres="id?id = #{id}"/> <!--刪除模板:默認id="deleteTemplete,where自動設置邏輯刪除字段--> <deleteTemplete wheres="name?name = #{name}"/> </mapper>
xml對應以下定義的Mapper結構體方法
type Activity struct { Id string `json:"id"` Uuid string `json:"uuid"` Name string `json:"name"` PcLink string `json:"pcLink"` H5Link string `json:"h5Link"` Remark string `json:"remark"` Version int `json:"version"` CreateTime time.Time `json:"createTime"` DeleteFlag int `json:"deleteFlag"` } type ExampleActivityMapper struct { SelectTemplete func(name string) ([]Activity, error) `mapperParams:"name"` InsertTemplete func(arg Activity) (int64, error) InsertTempleteBatch func(args []Activity) (int64, error) `mapperParams:"args"` UpdateTemplete func(arg Activity) (int64, error) `mapperParams:"name"` DeleteTemplete func(name string) (int64, error) `mapperParams:"name"` }
功能:動態數據源
//添加第二個mysql數據庫,請把MysqlUri改成你的第二個數據源鏈接 GoMybatis.Open("mysql", MysqlUri) //動態數據源路由 var router = GoMybatis.GoMybatisDataSourceRouter{}.New(func(mapperName string) *string { //根據包名路由指向數據源 if strings.Contains(mapperName, "example.") { var url = MysqlUri//第二個mysql數據庫,請把MysqlUri改成你的第二個數據源鏈接 fmt.Println(url) return &url } return nil })
功能:自定義日志輸出
engine.SetLogEnable(true) engine.SetLog(&GoMybatis.LogStandard{ PrintlnFunc: func(messages []byte) { //do someting save messages }, })
功能:異步日志-基於消息隊列日志
功能:嵌套事務-事務傳播行為
事務類型 | 說明 |
---|---|
PROPAGATION_REQUIRED | 表示如果當前事務存在,則支持當前事務。否則,會啟動一個新的事務。默認事務類型。 |
PROPAGATION_SUPPORTS | 表示如果當前事務存在,則支持當前事務,如果當前沒有事務,就以非事務方式執行。 |
PROPAGATION_MANDATORY | 表示如果當前事務存在,則支持當前事務,如果當前沒有事務,則返回事務嵌套錯誤。 |
PROPAGATION_REQUIRES_NEW | 表示新建一個全新Session開啟一個全新事務,如果當前存在事務,則把當前事務掛起。 |
PROPAGATION_NOT_SUPPORTED | 表示以非事務方式執行操作,如果當前存在事務,則新建一個Session以非事務方式執行操作,把當前事務掛起。 |
PROPAGATION_NEVER | 表示以非事務方式執行操作,如果當前存在事務,則返回事務嵌套錯誤。 |
PROPAGATION_NESTED | 表示如果當前事務存在,則在嵌套事務內執行,如嵌套事務回滾,則只會在嵌套事務內回滾,不會影響當前事務。如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的操作。 |
PROPAGATION_NOT_REQUIRED | 表示如果當前沒有事務,就新建一個事務,否則返回錯誤。 |
//嵌套事務的服務 type TestService struct { exampleActivityMapper *ExampleActivityMapper //服務包含一個mapper操作數據庫,類似java spring mvc UpdateName func(id string, name string) error `tx:"" rollback:"error"` UpdateRemark func(id string, remark string) error `tx:"" rollback:"error"` } func main() { var testService TestService testService = TestService{ exampleActivityMapper: &exampleActivityMapper, UpdateRemark: func(id string, remark string) error { testService.exampleActivityMapper.SelectByIds([]string{id}) panic(errors.New("業務異常")) // panic 觸發事務回滾策略 return nil // rollback:"error"指定了返回error類型 且不為nil 就會觸發事務回滾策略 }, UpdateName: func(id string, name string) error { testService.exampleActivityMapper.SelectByIds([]string{id}) return nil }, } GoMybatis.AopProxyService(&testService, &engine)//必須使用AOP代理服務的func testService.UpdateRemark("1","remark") }
功能:內置xml生成工具- 根據用戶定義的struct結構體生成對應的 mapper.xml
//step1 定義你的數據庫模型,必須包含 json注解(默認為數據庫字段), gm:""注解指定 值是否為 id,version樂觀鎖,logic邏輯軟刪除 type UserAddress struct { Id string `json:"id" gm:"id"` UserId string `json:"user_id"` RealName string `json:"real_name"` Phone string `json:"phone"` AddressDetail string `json:"address_detail"` Version int `json:"version" gm:"version"` CreateTime time.Time `json:"create_time"` DeleteFlag int `json:"delete_flag" gm:"logic"` }
- 第二步,在你項目main 目錄下建立一個 XmlCreateTool.go 內容如下
func main() { var bean = UserAddress{} //此處只是舉例,應該替換為你自己的數據庫模型 GoMybatis.OutPutXml(reflect.TypeOf(bean).Name()+"Mapper.xml", GoMybatis.CreateXml("biz_"+GoMybatis.StructToSnakeString(bean), bean)) }
- 第三步,執行命令,在當前目錄下得到 UserAddressMapper.xml文件
go run XmlCreateTool.go
- 以下是自動生成的xml文件內容
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://raw.githubusercontent.com/zhuxiujia/GoMybatis/master/mybatis-3-mapper.dtd"> <mapper> <!--logic_enable 邏輯刪除字段--> <!--logic_deleted 邏輯刪除已刪除字段--> <!--logic_undelete 邏輯刪除 未刪除字段--> <!--version_enable 樂觀鎖版本字段,支持int,int8,int16,int32,int64--> <resultMap id="BaseResultMap" tables="biz_user_address"> <id column="id" property="id"/> <result column="id" property="id" langType="string" /> <result column="user_id" property="user_id" langType="string" /> <result column="real_name" property="real_name" langType="string" /> <result column="phone" property="phone" langType="string" /> <result column="address_detail" property="address_detail" langType="string" /> <result column="version" property="version" langType="int" version_enable="true" /> <result column="create_time" property="create_time" langType="Time" /> <result column="delete_flag" property="delete_flag" langType="int" logic_enable="true" logic_undelete="1" logic_deleted="0" /> </resultMap> </mapper>
配套生態(RPC,JSONRPC,Consul)-搭配GoMybatis
- https://github.com/zhuxiujia/easy_mvc //mvc,極大簡化開發流程
- https://github.com/zhuxiujia/easyrpc //easyrpc(基於標准庫的RPC)吸收GoMybatis的概念,類似標准庫的api,定義服務沒有標准庫的要求那么嚴格(可選不傳參數,或者只有一個參數,只有一個返回值)
- https://github.com/zhuxiujia/easyrpc_discovery //基於easyrpc定制微服務發現,支持動態代理,支持GoMybatis事務,AOP代理,事務嵌套,tag定義事務,自帶負載均衡算法(隨機,加權輪詢,源地址哈希法)
配套生態(RPC,JSONRPC,Consul)-搭配GoMybatis
- https://github.com/zhuxiujia/easy_mvc //mvc,極大簡化開發流程
- https://github.com/zhuxiujia/easyrpc //easyrpc(基於標准庫的RPC)吸收GoMybatis的概念,類似標准庫的api,定義服務沒有標准庫的要求那么嚴格(可選不傳參數,或者只有一個參數,只有一個返回值)
- https://github.com/zhuxiujia/easyrpc_discovery //基於easyrpc定制微服務發現,支持動態代理,支持GoMybatis事務,AOP代理,事務嵌套,tag定義事務,自帶負載均衡算法(隨機,加權輪詢,源地址哈希法)
- 授權協議:
- Apache
- 開發語言:
- go 查看源碼»
- 操作系統:
- windows,linux