timandy / GoMybatis

Mybatis for golang.
Apache License 2.0
9 stars 1 forks source link
go golang gomybatis mybatis

SQL mapper ORM framework for Golang

Go Report Card Build Status GoDoc Coverage Status codecov

Image text

Please read the documentation website carefully when using the tutorial. DOC

Powerful Features

Database Driver support(support all database of database/sql)

 //Traditional database
 Mysql:                             github.com/go-sql-driver/mysql
 MyMysql:                           github.com/ziutek/mymysql/godrv
 Postgres:                          github.com/lib/pq
 SQLite:                            github.com/mattn/go-sqlite3
 MsSql:                             github.com/denisenkom/go-mssqldb
 Oracle:                            github.com/mattn/go-oci8
 //Distributed NewSql database
 Tidb:                              github.com/go-sql-driver/mysql
 CockroachDB:                       github.com/lib/pq

Use tutorials

Tutorial source code https://github.com/timandy/GoMybatis/tree/master/example

go get github.com/timandy/GoMybatis
go get github.com/go-sql-driver/mysql
//go.mod加入依赖
require (
    github.com/go-sql-driver/mysql v1.5.0
    github.com/timandy/GoMybatis v6.5.6+incompatible
)

In practice, we use mapper to define the content of xml. It is suggested that the * Mapper. XML file be stored in the project directory. When editing xml, we can enjoy IDE rendering and intelligent prompts such as GoLand. Production environments can use statikFS to package XML files in the process

var xmlBytes = []byte(`
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://raw.githubusercontent.com/timandy/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" //Select the required database-driven imports
    "github.com/timandy/GoMybatis"
)
type ExampleActivityMapperImpl struct {
     SelectAll  func() ([]Activity, error)
}

func main() {
    var engine = GoMybatis.GoMybatisEngine{}.New()
    //Mysql link format user name: password @ (database link address: port)/database name, such as root: 123456 @(***.com: 3306)/test
    err := engine.Open("mysql", "*?charset=utf8&parseTime=True&loc=Local")
    if err != nil {
       panic(err)
    }
    var exampleActivityMapperImpl ExampleActivityMapperImpl

    //Loading XML implementation logic to ExampleActivity Mapper Impl
    engine.WriteMapperPtr(&exampleActivityMapperImpl, xmlBytes)

    //use mapper
    result, err := exampleActivityMapperImpl.SelectAll(&result)
        if err != nil {
       panic(err)
    }
    fmt.Println(result)
}

Features: Template tag CRUD simplification (must rely on a resultMap tag)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://raw.githubusercontent.com/timandy/GoMybatis/master/mybatis-3-mapper.dtd">
<mapper>
    <!--logic_enable -->
    <!--logic_deleted -->
    <!--logic_undelete  -->
    <!--version_enable support int,int8,int16,int32,int64-->
    <resultMap id="BaseResultMap" tables="biz_activity">
        <id column="id" langType="string"/>
        <result column="name" langType="string"/>
        <result column="pc_link" langType="string"/>
        <result column="h5_link" langType="string"/>
        <result column="remark" langType="string"/>
        <result column="sort" langType="int"/>
        <result column="status" langType="status"/>
        <result column="version" langType="int"
                version_enable="true"/>
        <result column="create_time" langType="time.Time"/>
        <result column="delete_flag" langType="int"
                logic_enable="true"
                logic_undelete="1"
                logic_deleted="0"/>
    </resultMap>

    <!--模板标签: columns wheres sets 支持逗号,分隔表达式,*?* 为判空表达式-->

    <!--插入模板:默认id="insertTemplate,test="field != null",where自动设置逻辑删除字段,支持批量插入" -->
    <insertTemplate/>
    <!--查询模板:默认id="selectTemplate,where自动设置逻辑删除字段-->
    <selectTemplate wheres="name?name = #{name}"/>
    <!--更新模板:默认id="updateTemplate,set自动设置乐观锁版本号-->
    <updateTemplate sets="name?name = #{name},remark?remark=#{remark}" wheres="id?id = #{id}"/>
    <!--删除模板:默认id="deleteTemplate,where自动设置逻辑删除字段-->
    <deleteTemplate wheres="name?name = #{name}"/>
</mapper>    

XML corresponds to the Mapper structure method defined below

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 {
    SelectTemplate      func(name string) ([]Activity, error) `args:"name"`
    InsertTemplate      func(arg Activity) (int64, error)
    InsertTemplateBatch func(args []Activity) (int64, error) `args:"args"`
    UpdateTemplate      func(arg Activity) (int64, error)    `args:"name"`
    DeleteTemplate      func(name string) (int64, error)     `args:"name"`
}

Features:Dynamic Data Source

        //To add a second MySQL database, change Mysql Uri to your second data source link
    var engine = GoMybatis.GoMybatisEngine{}.New()
    engine.Open("mysql", MysqlUri)//添加第二个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.SetDataSourceRouter(&router)

Features:Custom log output

    engine.SetLogEnable(true)
    engine.SetLog(&GoMybatis.LogStandard{
        PrintlnFunc: func(messages []byte) {
          //do someting save messages
        },
    })

Features:Asynchronous log interface (customizable log output)

Image text

Features:Transaction Propagation Processor (Nested Transactions)

Transaction type Explain
PROPAGATION_REQUIREDRepresents that if the current transaction exists, the current transaction is supported. Otherwise, a new transaction will be started. Default transaction type.
PROPAGATION_SUPPORTSRepresents that if the current transaction exists, the current transaction is supported, and if there is no transaction at present, it is executed in a non-transactional manner.
PROPAGATION_MANDATORYRepresents that if the current transaction exists, the current transaction is supported, and if no transaction exists, the transaction nesting error is returned.
PROPAGATION_REQUIRES_NEWRepresents that a new Session opens a new transaction and suspends the current transaction if it currently exists.
PROPAGATION_NOT_SUPPORTEDRepresents that an operation is performed in a non-transactional manner. If a transaction exists, a new Session is created to perform the operation in a non-transactional manner, suspending the current transaction.
PROPAGATION_NEVERRepresents that an operation is executed in a non-transactional manner and returns a transaction nesting error if a transaction currently exists.
PROPAGATION_NESTEDRepresents that if the current transaction exists, it will be executed within the nested transaction. If the nested transaction rolls back, it will only roll back within the nested transaction and will not affect the current transaction. If there is no transaction at the moment, do something similar to PROPAGATION_REQUIRED.
PROPAGATION_NOT_REQUIREDRepresents that if there is currently no transaction, a new transaction will be created, otherwise an error will be returned.
 //Nested transaction services
type TestService struct {
    exampleActivityMapper *ExampleActivityMapper //The service contains a mapper operation database similar to 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("Business exceptions")) // panic Triggered transaction rollback strategy
            return nil                   // rollback:"error" A transaction rollback policy is triggered if the error type is returned and is not nil
        },
        UpdateName: func(id string, name string) error {
            testService.exampleActivityMapper.SelectByIds([]string{id})
            return nil
        },
    }
    GoMybatis.AopProxyService(&testService, &engine)//Func must use AOP proxy service
    testService.UpdateRemark("1","remark")
}

Features:XML/Mapper Generator - Generate * mapper. XML from struct structure

  //step1 To define your database model, you must include JSON annotations (default database fields), gm:"" annotations specifying whether the value is id, version optimistic locks, and logic logic soft deletion.
  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"`
}
func main() {
    var bean = UserAddress{} //Here's just an example, which should be replaced by your own database model
    GoMybatis.OutPutXml(reflect.TypeOf(bean).Name()+"Mapper.xml", GoMybatis.CreateXml("biz_"+GoMybatis.StructToSnakeString(bean), bean))
}
go run XmlCreateTool.go
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://raw.githubusercontent.com/timandy/GoMybatis/master/mybatis-3-mapper.dtd">
<mapper>
    <!--logic_enable Logical Delete Fields-->
    <!--logic_deleted Logically delete deleted fields-->
    <!--logic_undelete Logically Delete Undeleted Fields-->
    <!--version_enable Optimistic lock version field, support 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>

Components (RPC, JSONRPC, Consul) - With GoMybatis

Please pay attention to the version in time, upgrade the version in time (new features, bug fix). For projects using GoMybatis, please leave your project name + contact information in Issues.

Welcome to Star or Wechat Payment Sponsorship at the top right corner~

Image text