Giter VIP home page Giter VIP logo

gobatis's Introduction

gobatis

CodeQL

目前代码都是基于类mysql数据库编写测试的,其他数据库暂时还未做兼容处理

  • 支持数据库
    • mysql
    • tidb
    • mariadb
    • postgres
    • sqlite
  • 基础操作
    • query
    • insert
    • update
    • delete

ToDo

  • 增加更多易用表达式指令,目前已有$blank指令用于判别字符串是否为空的指令,比如判断name为空串: test="$blank(name)"

模板代码生成

提供了简单的增删改查代码自动生成

具体操作看仓库: https://github.com/wenj91/mctl.git

gobatis接口

type GoBatis interface {
	// Select 查询数据
	Select(stmt string, param interface{}, rowBound ...*rowBounds) func(res interface{}) (int64, error)
	// SelectContext 查询数据with context
	SelectContext(ctx context.Context, stmt string, param interface{}, rowBound ...*rowBounds) func(res interface{}) (int64, error)
	// Insert 插入数据
	Insert(stmt string, param interface{}) (lastInsertId int64, affected int64, err error)
	// InsertContext 插入数据with context
	InsertContext(ctx context.Context, stmt string, param interface{}) (lastInsertId int64, affected int64, err error)
	// Update 更新数据
	Update(stmt string, param interface{}) (affected int64, err error)
	// UpdateContext 更新数据with context
	UpdateContext(ctx context.Context, stmt string, param interface{}) (affected int64, err error)
	// Delete 刪除数据
	Delete(stmt string, param interface{}) (affected int64, err error)
	// DeleteContext 刪除数据with context
	DeleteContext(ctx context.Context, stmt string, param interface{}) (affected int64, err error)
}

db数据源配置

  • 支持多数据源配置
  • db子级配置为一个map,map的key即为数据源名称标识
  • map的value为数据源具体配置,具体配置项如下表
配置 是否必填配置 默认值 说明
driverName 数据源驱动名,必填配置项
dataSourceName 数据源名称,必填配置项,例如: root:123456@tcp(127.0.0.1:3306)/test?charset=utf8
maxLifeTime 120(单位: s) 连接最大存活时间,默认值为: 120 单位为: s
maxOpenConns 10 最大打开连接数,默认值为: 10
maxIdleConns 5 最大挂起连接数,默认值为: 5

示例

  • db配置示例(配置较之前的有所调整)
    以下为多数据源配置示例: db.yml
# 数据库配置
db:
  # 数据源名称1
  - datasource: ds1
    # 驱动名
    driverName: mysql
    # 数据源
    dataSourceName: root:123456@tcp(127.0.0.1:3306)/test?charset=utf8
    # 连接最大存活时间(单位: s)
    maxLifeTime: 120
    # 最大open连接数
    maxOpenConns: 10
    # 最大挂起连接数
    maxIdleConns: 5
  # 数据源名称2
  - datasource: ds2
    # 驱动名
    driverName: mysql
    # 数据源
    dataSourceName: root:123456@tcp(127.0.0.1:3306)/test?charset=utf8
    # 连接最大存活时间(单位: s)
    maxLifeTime: 120
    # 最大open连接数
    maxOpenConns: 10
    # 最大挂起连接数
    maxIdleConns: 5
# 是否显示SQL语句
showSql: true
# 数据表映射文件路径配置
mappers:
  # 映射文件路径, 可以为绝对路径,如: /usr/local/mapper/userMapper.xml
  - mapper/userMapper.xml
  • mapper配置
  1. mapper可以配置namespace属性
  2. mapper可以包含: select, insert, update, delete标签
  3. mapper子标签id属性则为标签唯一标识, 必须配置属性
  4. 其中select标签必须包含resultType属性,resultType可以是: map, maps, array, arrays, struct, structs, value
  • 标签说明
    select: 用于查询操作
    insert: 用于插入sql操作
    update: 用于更新sql操作
    delete: 用于删除sql操作

  • resultType说明
    map: 则数据库查询结果为map
    maps: 则数据库查询结果为map数组
    array: 则数据库查询结果为值数组
    arrays: 则数据库查询结果为多个值数组
    struct: 则数据库查询结果为单个结构体
    structs: 则数据库查询结果为结构体数组
    value: 则数据库查询结果为单个数值

以下是mapper配置示例: mapper/userMapper.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mapper PUBLIC "gobatis"
        "https://raw.githubusercontent.com/wenj91/gobatis/master/gobatis.dtd">
<mapper namespace="userMapper">
    <sql id="Base_Column_List">
        id, name, crtTm, pwd, email
    </sql>
    <select id="findIncludeMaps" resultType="maps">
        SELECT
        	<include refid="Base_Column_List" />
        FROM user
        limit 10
    </select>
    <select id="findMapById" resultType="map">
        SELECT id, name FROM user where id=#{id} order by id
    </select>
    <select id="findMapByValue" resultType="map">
            SELECT id, name FROM user where id=#{0} order by id
    </select>
    <select id="findStructByStruct" resultType="struct">
        SELECT id, name, crtTm FROM user where id=#{Id} order by id
    </select>
    <select id="queryStructs" resultType="structs">
        SELECT id, name, crtTm FROM user order by id
    </select>
    <select id="queryStructsByOrder" resultType="structs">
        SELECT id, name, crtTm FROM user order by ${id} desc
    </select>
    <insert id="insertStruct">
        insert into user (name, email, crtTm)
        values (#{Name}, #{Email}, #{CrtTm})
    </insert>
    <delete id="deleteById">
        delete from user where id=#{id}
    </delete>
    <select id="queryStructsByCond" resultType="structs">
         SELECT id, name, crtTm, pwd, email FROM user
         <where>
             <if test="!$blank(Name)">and name = #{Name}</if>
         </where>
         order by id
    </select>
     <select id="queryStructsByCond2" resultType="structs">
         SELECT id, name, crtTm, pwd, email FROM user
         <trim prefixOverrides="and" prefix="where" suffixOverrides="," suffix="and 1=1">
              <if test="!$blank(Name)">and name = #{Name}</if>
         </trim>
         order by id
    </select>
    <update id="updateByCond">
        update user
        <set>
            <if test="!$blank(Name) and !$blank(Name2)">name = #{Name},</if>
        </set>
        where id = #{Id}
    </update>
</mapper>

使用方法

使用配置文件配置

example1.go

package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql" // 引入驱动
	"github.com/wenj91/gobatis"        // 引入gobatis
)

// 实体结构示例, tag:field为数据库对应字段名称
type User struct {
	Id    gobatis.NullInt64  `field:"id"`
	Name  gobatis.NullString `field:"name"`
	Email gobatis.NullString `field:"email"`
	CrtTm gobatis.NullTime   `field:"crtTm"`
}


// User to string
func (u *User) String() string {
	bs, _ := json.Marshal(u)
	return string(bs)
}

func main() {
	// 初始化db,参数为db.yml路径,如:db.yml	
	gobatis.Init(gobatis.NewFileOption("db.yml"))

	// 获取数据源,参数为数据源名称,如:datasource1
	gb := gobatis.Get("ds1")

	//传入id查询Map
	mapRes := make(map[string]interface{})
	// stmt标识为:namespace + '.' + id, 如:userMapper.findMapById
	// 查询参数可以是map,也可以是数组,也可以是实体结构
	_, err := gb.Select("userMapper.findMapById", map[string]interface{}{"id": 1})(mapRes)
	fmt.Println("userMapper.findMapById-->", mapRes, err)

	// 根据传入实体查询对象
	param := User{Id: gobatis.NullInt64{Int64: 1, Valid: true}}
	var structRes *User
	_, err = gb.Select("userMapper.findStructByStruct", param)(&structRes)
	fmt.Println("userMapper.findStructByStruct-->", structRes, err)

	// 查询实体列表
	structsRes := make([]*User, 0)
	_, err = gb.Select("userMapper.queryStructs", map[string]interface{}{})(&structsRes)
	fmt.Println("userMapper.queryStructs-->", structsRes, err)

	param = User{
		Id:   gobatis.NullInt64{Int64: 1, Valid: true},
		Name: gobatis.NullString{String: "wenj1993", Valid: true},
	}

	// set tag
	affected, err := gb.Update("userMapper.updateByCond", param)
	fmt.Println("updateByCond:", affected, err)

	param = User{Name: gobatis.NullString{String: "wenj1993", Valid: true}}
	// where tag
	res := make([]*User, 0)
	_, err = gb.Select("userMapper.queryStructsByCond", param)(&res)
	fmt.Println("queryStructsByCond", res, err)

	// trim tag
	res = make([]*User, 0)
	_, err = gb.Select("userMapper.queryStructsByCond2", param)(&res)
	fmt.Println("queryStructsByCond2", res, err)

	// include tag
	ms := make([]map[string]interface{}, 0)
	_, err = gb.Select("userMapper.findIncludeMaps", nil)(&ms)
	fmt.Println("userMapper.findIncludeMaps-->", ms, err)
	
	// ${id}
	res = make([]*User, 0)
	_, err = gb.Select("userMapper.queryStructsByOrder", map[string]interface{}{
		"id":"id",
	})(&res)
	fmt.Println("queryStructsByCond", res, err)

	// ${id} with count, 传入RowBounds(0, 100)即可返回count总数
	res = make([]*User, 0)
	cnt, err = gb.Select("userMapper.queryStructsByOrder", map[string]interface{}{
		"id":"id",
	}, RowBounds(0, 100))(&res)
	fmt.Println("queryStructsByCond", cnt, res, err)


	// 开启事务示例
	tx, _ := gb.Begin()
	defer tx.Rollback()
	_, tx.Select("userMapper.findMapById", map[string]interface{}{"id": 1,})(mapRes)
	fmt.Println("tx userMapper.findMapById-->", mapRes, err)
	tx.Commit()
}

代码配置方式

example2.go

package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql" // 引入驱动
	"github.com/wenj91/gobatis"        // 引入gobatis
)

// 实体结构示例, tag:field为数据库对应字段名称
type User struct {
	Id    gobatis.NullInt64  `field:"id"`
	Name  gobatis.NullString `field:"name"`
	Email gobatis.NullString `field:"email"`
	CrtTm gobatis.NullTime   `field:"crtTm"`
}

func main() {
	// 初始化db
	ds1 := gobatis.NewDataSourceBuilder().
		DataSource("ds1").
		DriverName("mysql").
		DataSourceName("root:123456@tcp(127.0.0.1:3306)/test?charset=utf8").
		MaxLifeTime(120).
		MaxOpenConns(10).
		MaxIdleConns(5).
		Build()

	option := gobatis.NewDSOption().
		DS([]*gobatis.DataSource{ds1}).
		Mappers([]string{"examples/mapper/userMapper.xml"}).
		ShowSQL(true)

	gobatis.Init(option)

	// 获取数据源,参数为数据源名称,如:ds1
	gb := gobatis.Get("ds1")

	//传入id查询Map
	mapRes := make(map[string]interface{})
	// stmt标识为:namespace + '.' + id, 如:userMapper.findMapById
	// 查询参数可以是map,也可以是数组,也可以是实体结构
	_, err := gb.Select("userMapper.findMapById", map[string]interface{}{"id": 1})(mapRes)
	fmt.Println("userMapper.findMapById-->", mapRes, err)
}

example3.go

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql" // 引入驱动
	"github.com/wenj91/gobatis"        // 引入gobatis
)

// 实体结构示例, tag:field为数据库对应字段名称
type User struct {
	Id    gobatis.NullInt64  `field:"id"`
	Name  gobatis.NullString `field:"name"`
	Email gobatis.NullString `field:"email"`
	CrtTm gobatis.NullTime   `field:"crtTm"`
}

func main() {
	// 初始化db
	db, _ := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8")
	dbs := make(map[string]*gobatis.GoBatisDB)
	dbs["ds1"] = gobatis.NewGoBatisDB(gobatis.DBTypeMySQL, db)

	option := gobatis.NewDBOption().
		DB(dbs).
		ShowSQL(true).
		Mappers([]string{"examples/mapper/userMapper.xml"})

	gobatis.Init(option)

	// 获取数据源,参数为数据源名称,如:ds1
	gb := gobatis.Get("ds1")

	//传入id查询Map
	mapRes := make(map[string]interface{})
	// stmt标识为:namespace + '.' + id, 如:userMapper.findMapById
	// 查询参数可以是map,也可以是数组,也可以是实体结构
	_, err := gb.Select("userMapper.findMapById", map[string]interface{}{"id": 1})(mapRes)
	fmt.Println("userMapper.findMapById-->", mapRes, err)
}

致谢

感谢jetbrains提供的goland!

gobatis's People

Contributors

wenj91 avatar youkale avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

gobatis's Issues

关于配置

大致看了下代码,感觉简洁明了
有几个地方感觉需要改进:
1.数据库连接(池)的初始化,觉得不应该耦合在代码里面,是通过外部传入。
2.同时读取yaml相关的代码也不应该在里面,而是通过外部传入

打包问题

我想问下,你的那些xml文件是打不进二进制包的,你是怎么解决的,用go-bindata一个一个转成go文件吗

返回值自动映射

目前返回值都是通过field的tag映射的,我在想是否考虑将 CamelCase 自动转换为 snake_case

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.