gobatis

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 6, 2019 License: Apache-2.0 Imports: 11 Imported by: 0

README

gobatis

Appveyor Build status

介绍

gobatis是一个golang的ORM框架,类似Java的Mybatis。支持直接执行sql语句以及动态sql。

建议配合gobatis-cmd自动代码、sql生成工具使用。

支持的动态sql标签:

标签 说明
if 动态 SQL 通常要做的事情是根据条件包含 where 子句的一部分。
where where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除。
set set 元素会动态前置 SET 关键字,同时也会删掉无关的逗号。
include 使用sql标签定义的语句替换。
choose
when
otherwise
有时我们不想应用到所有的条件语句,而只想从中择其一项。针对这种情况,gobatis 提供了 choose 元素,它有点像switch 语句。
foreach foreach 允许指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。

待完成项

  • 继续完善动态sql支持(trim)
  • 性能优化:增加动态sql缓存 (已经实现,但测试发现性能提升很小,目前该功能被关闭)

使用

1、配置数据库,获得SessionManager
func InitDB() *gobatis.SessionManager {
    fac := factory.DefaultFactory{
        Host:     "localhost",
        Port:     3306,
        DBName:   "test",
        Username: "root",
        Password: "123",
        Charset:  "utf8",

        MaxConn:     1000,
        MaxIdleConn: 500,

        Log: logging.DefaultLogf,
    }
    fac.Init()
    return gobatis.NewSessionManager(&fac)
}
2、定义Model

使用tag("xfield")定义struct,tag指定数据库表中的column name。

type TestTable struct {
    //指定table name
    TestTable gobatis.ModelName "test_table"
    //指定表字段id
    Id        int64             `xfield:"id"`
    //指定表字段username
    Username  string            `xfield:"username"`
    //指定表字段password
    Password  string            `xfield:"password"`
}
3、注册Model

作用是提高执行速度,已变为非必要步骤,现在gobatis会自动缓存。

func init() {
    var model TestTable
    gobatis.RegisterModel(&model)
}
4、调用
func Run() {
    //初始化db并获得Session Manager
    mgr := InitDB()
    
    //获得session
    session := mgr.NewSession()
    
    ret := TestTable{}
    
    //使用session查询
    session.Select("select * from test_table where id = ${0}").Param(100).Result(&ret)
    
    fmt.printf("%v\n", ret)
}
5、说明
  1. ${}表示直接替换,#{}防止sql注入
  2. 与Mybatis类似,语句中${0}、${1}、${2}...${n} 对应的是Param方法中对应的不定参数,最终替换和调用底层Driver
  3. Param方法接受简单类型的不定参数(string、int、time、float等)、struct、map,底层自动解析获得参数,用法为:
param := TestTable{Username:"test_user"}
ret := TestTable{}
session.Select("select * from test_table where username = #{TestTable.username}").Param(param).Result(&ret)
  1. Param解析的参数规则(请务必按此规则对应SQL语句的占位参数):
  • 简单类型

    对应sql参数中的#{0}、#{1}...

  • map类型

    对应sql参数中的#{key1}、#{key2}...

  • struct类型

    对应sql参数中的#{StructName.Field1}、#{StructName.Field2}...

6、事务

使用

    mgr.NewSession().Tx(func(session *gobatis.Session) bool {
        ret := 0
        session.Insert("insert_id").Param(testV).Result(&ret)
        
        t.Logf("ret %d\n", ret)
        
        session.Select("select_id").Param().Result(&testList)
        
        for _, v := range  testList {
            t.Logf("data: %v", v)
        }
        //commit
        return true
    })
  1. 当参数的func返回true,则提交
  2. 当参数的func返回false,则回滚
  3. 当参数的func内抛出panic,则回滚
7、xml

gobatis支持xml的sql解析及动态sql

  1. 注册xml
gobatis.RegisterMapperData([]byte(main_xml))

gobatis.RegisterMapperFile(filePath)
  1. xml示例
<mapper namespace="test_package.TestTable">
    <sql id="columns_id">id,username,password,update_time</sql>

    <select id="selectTestTable">
        SELECT <include refid="columns_id"> </include> FROM test_table
        <where>
            <if test="{TestTable.id} != nil and {TestTable.id} != 0">AND id = #{TestTable.id} </if>
            <if test="{TestTable.username} != nil">AND username = #{TestTable.username} </if>
            <if test="{TestTable.password} != nil">AND password = #{TestTable.password} </if>
            <if test="{TestTable.update_time} != nil">AND update_time = #{TestTable.update_time} </if>
        </where>
    </select>

    <select id="selectTestTableCount">
        SELECT COUNT(*) FROM test_table
        <where>
            <if test="{TestTable.id} != nil and {TestTable.id} != 0">AND id = #{TestTable.id} </if>
            <if test="{TestTable.username} != nil">AND username = #{TestTable.username} </if>
            <if test="{TestTable.password} != nil">AND password = #{TestTable.password} </if>
            <if test="{TestTable.update_time} != nil">AND update_time = #{TestTable.update_time} </if>
        </where>
    </select>

    <insert id="insertTestTable">
        INSERT INTO test_table (id,username,password,update_time)
        VALUES(
        #{TestTable.id},
        #{TestTable.username},
        #{TestTable.password},
        #{TestTable.update_time}
        )
    </insert>

    <update id="updateTestTable">
        UPDATE test_table
        <set>
            <if test="{TestTable.username} != nil"> username = #{TestTable.username} </if>
            <if test="{TestTable.password} != nil"> password = #{TestTable.password} </if>
            <if test="{TestTable.update_time} != nil"> update_time = #{TestTable.update_time} </if>
        </set>
        WHERE id = #{TestTable.id}
    </update>

    <delete id="deleteTestTable">
        DELETE FROM test_table
        <where>
            <if test="{TestTable.id} != nil and {TestTable.id} != 0">AND id = #{TestTable.id} </if>
            <if test="{TestTable.username} != nil">AND username = #{TestTable.username} </if>
            <if test="{TestTable.password} != nil">AND password = #{TestTable.password} </if>
            <if test="{TestTable.update_time} != nil">AND update_time = #{TestTable.update_time} </if>
        </where>
    </delete>
</mapper>
8、gobatis-cmd生成文件使用示例

参考cmd_test

9、 SQL语句构建器

gobatis xml特性有非常强大的动态SQL生成方案,当需要在代码中嵌入SQL语句时,也可使用SQL语句构建器:

import "github.com/xfali/gobatis/builder"
    str := builder.Select("A.test1", "B.test2").
            Select("B.test3").
            From("test_a AS A").
            From("test_b AS B").
            Where("id = 1").
            And().
            Where("name=2").
            GroupBy("name").
            OrderBy("name").
            Desc().
            Offset(5).
            Limit(10).
            String()
    t.Log(str)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FindSql

func FindSql(sqlId string) *parsing.DynamicData

func ParseObject

func ParseObject(bean interface{}) (reflection.Object, error)

func RegisterMapperData

func RegisterMapperData(data []byte) error

func RegisterMapperFile

func RegisterMapperFile(file string) error

func RegisterModel

func RegisterModel(model interface{})

注册struct模型,模型描述了column和field之间的关联关系; 目前已非必要条件

func RegisterModelWithName

func RegisterModelWithName(name string, model interface{}) error

func RegisterSql

func RegisterSql(sqlId string, sql string) error

func UnregisterSql

func UnregisterSql(sqlId string)

Types

type BaseRunner

type BaseRunner struct {
	// contains filtered or unexported fields
}

func (*BaseRunner) Context

func (this *BaseRunner) Context(ctx context.Context) Runner

Context 设置执行的context

func (*BaseRunner) LastInsertId

func (this *BaseRunner) LastInsertId() int64

func (*BaseRunner) Param

func (this *BaseRunner) Param(params ...interface{}) Runner

func (*BaseRunner) Result

func (this *BaseRunner) Result(bean interface{}) error

type DeleteRunner

type DeleteRunner struct {
	BaseRunner
}

func (*DeleteRunner) Result

func (this *DeleteRunner) Result(bean interface{}) error

type InsertRunner

type InsertRunner struct {
	BaseRunner
	// contains filtered or unexported fields
}

func (*InsertRunner) LastInsertId

func (this *InsertRunner) LastInsertId() int64

func (*InsertRunner) Result

func (this *InsertRunner) Result(bean interface{}) error

type ModelName

type ModelName string

type ObjectCache

type ObjectCache struct {
	// contains filtered or unexported fields
}

type Runner

type Runner interface {
	//参数
	//注意:如果没有参数也必须调用
	//如果参数个数为1并且为struct,将解析struct获得参数
	//如果参数个数大于1并且全部为简单类型,或则个数为1且为简单类型,则使用这些参数
	Param(params ...interface{}) Runner
	//获得结果
	Result(bean interface{}) error
	//最后插入的自增id
	LastInsertId() int64
	//设置Context
	Context(ctx context.Context) Runner
}

type SelectRunner

type SelectRunner struct {
	BaseRunner
	// contains filtered or unexported fields
}

func (*SelectRunner) Result

func (this *SelectRunner) Result(bean interface{}) error

type Session

type Session struct {
	// contains filtered or unexported fields
}

func (*Session) Delete

func (this *Session) Delete(sql string) Runner

func (*Session) GetContext

func (this *Session) GetContext() context.Context

func (*Session) Insert

func (this *Session) Insert(sql string) Runner

func (*Session) Select

func (this *Session) Select(sql string) Runner

func (*Session) SetContext

func (this *Session) SetContext(ctx context.Context) *Session

func (*Session) Tx

func (this *Session) Tx(txFunc func(session *Session) bool)

开启事务执行语句 返回true则提交,返回false回滚 抛出异常错误触发回滚

func (*Session) Update

func (this *Session) Update(sql string) Runner

type SessionManager

type SessionManager struct {
	// contains filtered or unexported fields
}

func NewSessionManager

func NewSessionManager(factory factory.Factory) *SessionManager

func (*SessionManager) NewSession

func (this *SessionManager) NewSession() *Session

使用一个session操作数据库

type SqlManager

type SqlManager struct {
	// contains filtered or unexported fields
}

type UpdateRunner

type UpdateRunner struct {
	BaseRunner
}

func (*UpdateRunner) Result

func (this *UpdateRunner) Result(bean interface{}) error

Source Files

  • init.go
  • objectmanager.go
  • sqlmanager.go
  • sqlrunner.go

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL