(Translated by https://www.hiragana.jp/)
GitHub - mei-rune/GoBatis: An easy ORM tool for Golang, support MyBatis-Like XML template SQL
Skip to content

An easy ORM tool for Golang, support MyBatis-Like XML template SQL

Notifications You must be signed in to change notification settings

mei-rune/GoBatis

Repository files navigation

GoBatis

GoDoc Travis Build Status GitHub Actions GitHub tag (latest SemVer) Coverage Status Appveyor Build status

Introduction

An easy ORM tool for Golang, support MyBatis-Like XML template SQL

まち完成かんせいてきにん

  1. 对象继承てき实现

  2. のべ迟加载或みつだん(ある特殊とくしゅ处理)てき实现 ゆう泛型りょう以尝试下

    type Lazy[T any] struct {
       value T
       session SqlSession
       sqlstr string
    }
    func (l *Lazy[T]) Read() T {
        session.Query()
    }
    
    // みつだん(ある特殊とくしゅ处理)
    type Passworder struct {
       value string
    }
    func (p *Passworder) Scan(interface{}) error {
        xxxxx
    }
    func (p *Passworder) Value() driver.Value {
        xxxxx
    }
    
    
    type Record struct {
    TableName struct{}    `db:records`
    Blob   Lazy[[]byte]   `db:"blob"`
    Password Passworder   `db:"password"`
    }
  3. かえしかい大量たいりょうすうすえ记录时用泛型らいあらため

    type Results[T any] struct  {}
    func (rs *Results) Next() bool {}
    func (rs *Results) Read(value *T) error {}

やめ bug

  1. とう sql ちゅう含有がんゆう xml 标签时 < ごう需要じゅよう转义为 &lt; ,而不含 xml 标签时&lt; また转义为 < , 这很不一致ふいっち最近さいきんわがあらため进了いち个像 mybatis いち样用 gt, gte,lt lte 代替だいたい >,>=, < <=, 如

    a > 8 うつしなり a gt 8

    a >= 8 うつしなり a gte 8

    a < 8 うつしなり a lt 8

    a <= 8 うつしなり a lte 8

  2. 达梦すうすえ库实现 upsert 时无ほうかえしかい insert id (达梦すうすえ库的问题)。

かず MyBatis てき

GoBatis 就是对 MyBatis てき简单仿。 ただしゆうれつ不同ふどう

1. 动态 sql 语句てき格式かくしき

 わが实现いち个和  mybatis 类似てき if, chose, foreach, trim, set  where 类的 xml 基本きほん实现,どう时也支持しじ go template らい生成せいせい sql。

1.1 另外わが们不支持しじ ${xxx}, ただしわが提供ていきょうりょういち个更安全あんぜんてき らいがえ换它

 とう  inStr="true" 时我かい检查 value てき值中ゆう 引号类的防止ぼうし sql 注入ちゅうにゅう
 
 とう    inStr="false" 时我かい检查 value てき值中ゆう and ある  or 类的逻辑ひょう达式,防止ぼうし sql 注入ちゅうにゅう

1.2 わが为 if 标签 增加ぞうかりょう else 支持しじ用法ようほう为 xx xxx

2. 生成せいせい sql 语句

MyBatis かい生成せいせい sql 语句てきわが觉得のうぞう大部たいぶ份的 orm いち样能生成せいせい sql てき话,以省很多工作こうさく 请见 SQL 生成せいせい

基本きほんおもえ

  1. よう户定义结构和せっこう
  2. ざいせっこうてき方法ほうほうじょうてい义 sql (以在 xml ちゅうある方法ほうほうてきちゅう释中)
  3. よう工具こうぐ生成せいせいせっこうてき实现
  4. 创建せっこうてき实例并使用しよう

Roadmap

  1. ます级 go1.14 きさき goparser とく别慢,じゅん备用 goparser2 がえ
  2. はた xml しょう关代码移いた xml
  3. はた sql 生成せいせい工具こうぐ builder しょう关代码移いた sql

Usage

注意ちゅうい, gobatis 也支持しじ xml, 请见 example_xml

  1. install gobatis tools.

    go get -u -v github.com/runner-mei/GoBatis/cmd/gobatis

  2. Define a struct, interface and comment methods with SQLs and Variables, then write a directive //go:generate gobatis user.go.

//go:generate gobatis user.go
package example

import (
  "time"
)

type AuthUser struct {
  ID        int64      `json:"id"`
  Username  string     `json:"username"`
  Phone     string     `json:"phone"`
  Address   *string    `json:"address"`
  Status    uint8      `json:"status"`
  BirthDay  *time.Time `json:"birth_day"`
  CreatedAt time.Time  `json:"created_at"`
  UpdatedAt time.Time  `json:"updated_at"`
}

type UserDao interface {
  // @postgres insert into auth_users(username, phone, address, status, birth_day, created_at, updated_at)
  // values (#{username},#{phone},#{address},#{status},#{birth_day},CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) returning id
  //
  // @default insert into auth_users(username, phone, address, status, birth_day, created_at, updated_at)
  // values (#{username},#{phone},#{address},#{status},#{birth_day},CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
  Insert(u *AuthUser) (int64, error)
}
  1. After that, run go generate ./... , user.gobatis.go is generated
// Please don't edit this file!
package example

import (
  "errors"

  gobatis "github.com/runner-mei/GoBatis"
)

func init() {
  gobatis.Init(func(ctx *gobatis.InitContext) error {
    { //// UserDao.Insert
      if _, exists := ctx.Statements["UserDao.Insert"]; !exists {
        sqlStr := "insert into auth_users(username, phone, address, status, birth_day, created_at, updated_at)\r\n values (#{username},#{phone},#{address},#{status},#{birth_day},CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)"
        switch ctx.Dialect {
        case gobatis.NewDialect("mssql"):
          sqlStr = "insert into auth_users(username, phone, address, status, birth_day, created_at, updated_at)\r\n output inserted.id\r\n values (#{username},#{phone},#{address},#{status},#{birth_day},CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)"
        case gobatis.NewDialect("postgres"):
          sqlStr = "insert into auth_users(username, phone, address, status, birth_day, created_at, updated_at)\r\n values (#{username},#{phone},#{address},#{status},#{birth_day},CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) returning id"
        }
        stmt, err := gobatis.NewMapppedStatement(ctx, "UserDao.Insert",
          gobatis.StatementTypeInsert,
          gobatis.ResultStruct,
          sqlStr)
        if err != nil {
          return err
        }
        ctx.Statements["UserDao.Insert"] = stmt
      }
    }
  })
}

func NewUserDao(session gobatis.SqlSession) UserDao {
  return &UserDaoImpl{session: session}
}

type UserDaoImpl struct {
  session gobatis.SqlSession
}

func (impl *UserDaoImpl) Insert(u *AuthUser) (int64, error) {
  return impl.session.Insert("UserDao.Insert",
    []string{
      "u",
    },
    []interface{}{
      u,
    })
}

...
  1. use UserDao
  factory, err := gobatis.New(&gobatis.Config{DriverName: tests.TestDrv,
    DataSource: tests.GetTestConnURL(),
    // XMLPaths: []string{"example/test.xml"},
    })
    
  userDao := NewUserDao(factory.SessionReference())
  id, err := userDao.Insert(&insertUser)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println("insert success!")

  u, err := userDao.Get(id)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println("fetch user from database!")

  _, err = userDao.Delete(id)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println("delete success!")

注意ちゅうい

GoBatis もとosm てきもと础上おさむあらためらいてき,goparser 则是ざい light てきもと础上おさむあらためらいてき, reflectx 则从 sqlx 拷贝过来てき