高性能數據庫ORM框架 GoMybatis


  • 文檔

    前言

    學習過原生的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 }, }) 

功能:異步日志-基於消息隊列日志

Image text

功能:嵌套事務-事務傳播行為

事務類型 說明
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

配套生態(RPC,JSONRPC,Consul)-搭配GoMybatis

Go ORM Library.Have Powerful Features like transaction nesting, Optimistic Lock,Logical deletion and more. like mybatis for go golang — Read More

Latest commit to the  master branch on 6-6-2021
Download as zip
授權協議:
Apache
開發語言:
go  查看源碼»
操作系統:
windows,linux


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM