3 Star 8 Fork 0

yanshikun/tcode

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

tcode

介绍

Go语言轻量ORM,极简封装,尽可能少使用反射进行封装,支持多库,支持基本类型,结构体,切片,分页结果映射,原始表数据映射(行,列),批量新增,事务

新增,更新数据表时采用go语言类型默认值进行补充,不允许数据表中包含null列,

代码生成器,使用函数WriteStruct进行结构体的输出,生成出的结构体不建议手动修改,如需修改,可以copy至其他目录进行修改

安装教程

go get gitee.com/yan-shi-kun/tcode

支持数据库

目前仅支持Mysql,后续新增支持(PostgreSQL,SQLite,Oracle,DB2...等)

使用说明

初始化代码生成器和数据库链接

// 初始化代码生成器和数据库链接
var (
    conf = &Config{
        Dsn:                   "root:root@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=true&loc=Local",
        DriverName:            "mysql",
        Dialect:               "mysql",
        MaxOpenConns:          50,
        MaxIdleConns:          50,
        ConnMaxLifetimeSecond: 600,
    }
    _, codeConstructor, _ = New(conf)
    ctx                   = context.Background()
)

生成当前库所有表

// TestGenAll 生成当前库所有表
func TestGenAll(t *testing.T) {
	info, err := codeConstructor.ToAllStructInfo(ctx)
	if err != nil {
		panic(err)
	}
	for i := range info {
		err = WriteStruct(ctx, info[i])
		if err != nil {
			panic(err)
		}
	}
	time.Sleep(time.Second)
}

新增,未设置的值将使用类型默认值补充

// TestInsert 新增,未设置的值将使用类型默认值补充
func TestInsert(t *testing.T) {
	var tb tables.TbTest
	tb.UserId = 199999
	tb.CategoryId = 123
	tb.ArticleCover = "Ar't''icl\\'\\\\'\\'eCover"
	tb.ArticleTitle = "ArticleTitle"
	tb.ArticleContent = "ArticleContent"
	tb.Type = 4
	tb.OriginalUrl = "OriginalUrl"
	tb.IsTop = 1
	tb.IsDelete = 0
	tb.Status = 1
	tb.Sortno = 99
	tb.UpdateTime = time.Now()
	insert, pkid, err := tcode.Insert(ctx, &tb)
	fmt.Println(insert, pkid, err)
	fmt.Println(tb)
}

批量新增

// TestInsertBatch 批量新增
func TestInsertBatch(t *testing.T) {
	var tbs []tcode.Table
	for i := 0; i < 1000; i++ {
		var tb tables.TbTest
		tb.UserId = int32(i)
		tb.UpdateTime = time.Now()
		tb.ArticleTitle = "测试批量新增123"
		tbs = append(tbs, &tb)
	}
	insert, pkid, err := tcode.InsertBatch(ctx, &tbs)
	fmt.Println(insert, pkid, err)
}

更新;忽略每一个空列(类型默认值进行忽略)

// TestUpdate 更新;忽略每一个空列(类型默认值进行忽略)
func TestUpdate(t *testing.T) {
	var tb tables.TbTest
	tb.Id = 201434
	tb.ArticleTitle = "测试\\'1234"
	update, id, err := tcode.UpdateByPk(ctx, &tb)
	fmt.Println(update, id, err)
}

更新:不忽略任何一列

// TestUpdateNotIgnoredEveryColumn 更新:不忽略任何一列
func TestUpdateNotIgnoredEveryColumn(t *testing.T) {
	var tb tables.TbTest
	tb.Id = pkid
	tb.ArticleTitle = "测试1234"
	update, id, err := tcode.UpdateNotIgnoredEveryColumnByPk(ctx, &tb)
	fmt.Println(update, id, err)
}

删除

// TestDelete 删除
func TestDelete(t *testing.T) {
	var tb tables.TbTest
	tb.Id = pkid
	affected, id, err := tcode.DeleteByPk(ctx, &tb)
	if err != nil {
		panic(err)
	}
	fmt.Println(affected, id, err)
}

查询结果映射变量

// TestSelectToVar 查询结果映射变量
func TestSelectToVar(t *testing.T) {
	var id int
	err := tcode.NewSqlInfo(ctx, "SELECT id FROM tb_test WHERE id=?", pkid).ToVar(&id)
	if err != nil {
		panic(err)
	}
	fmt.Println(id)
}

查询结果映射结构体ToStruct

// TestSelect 查询结果映射结构体ToStruct
func TestSelect(t *testing.T) {
	toStruct, err := tcode.Select[*tables.TbTest](ctx).AppendSQL(" WHERE id=?", pkid).ToStruct()
	if err != nil {
		panic(err)
	}
	fmt.Println(toStruct, err)
}

查询结果映射为切片

// TestSelect1 查询结果映射为切片
func TestSelect1(t *testing.T) {
	//PossibleQueryEmptyColumn 查询的列可能有空数据(nil)
	//toSlice, err := tcode.Select[*tables.TbTest](ctx).PossibleQueryEmptyColumn().ToSlice(nil)
	toSlice, err := tcode.Select[*tables.TbTest](ctx).ToSlice(nil)
	if err != nil {
		panic(err)
	}
	slice := *toSlice
	for i := range slice {
		fmt.Println(slice[i])
	}
}

没有结构体的情况下,将查询结果映射为原始表

// TestSelectToRawTable 没有结构体的情况下,将查询结果映射为原始表
func TestSelectToRawTable(t *testing.T) {
	table, err := tcode.NewSqlInfo(ctx, "select * FROM tb_test").ToRawTable(nil)
	if err != nil {
		panic(err)
	}
	//获取行
	row := table.GetRow(1)
	fmt.Println(row["id"])

	//获取列
	col := table.GetColumnByIndex(2)
	//col := table.GetColumnByName("列明")
	for i := range col {
		fmt.Println(col[i])
	}
}

分页查询

// TestPage 分页查询
func TestPage(t *testing.T) {
	newPage := tcode.NewPage()
	newPage.PageSize = 2
	newPage.NextPage = 1
	page, err := tcode.Select[*tables.TbTest](ctx, "id,article_title").PossibleQueryEmptyColumn().ToPage(newPage)
	if err != nil {
		panic(err)
	}
	p := *page
	for i := range p {
		fmt.Println(p[i].Id)
		fmt.Println(p[i].ArticleTitle)
	}
	fmt.Println(newPage)
}

自定义分页查询总记录数函数

// TestPage2 分页查询;自定义查询总记录数函数
func TestPage2(t *testing.T) {
	newPage := tcode.NewPage()
	newPage.PageSize = 2
	newPage.NextPage = 1
	newPage.FuncCustomTotal = func(total *int) error {
		err := tcode.NewSqlInfo(ctx, "SELECT COUNT(*) FROM tb_test").ToVar(total)
		if err != nil {
			return err
		}
		return nil
	}
	page, err := tcode.Select[*tables.TbTest](ctx, "id,article_title").PossibleQueryEmptyColumn().ToSlice(newPage)
	if err != nil {
		panic(err)
	}
	p := *page
	for i := range p {
		fmt.Println(p[i].Id)
		fmt.Println(p[i].ArticleTitle)
	}
	fmt.Println(newPage)
}

查询条件,in,like

// TestSelect4 查询条件,in,like
func TestSelect4(t *testing.T) {
	ids := []int32{pkid}
	cids := []int{186}
	slice, err := tcode.Select[*tables.TbTest](ctx).AppendSQL("WHERE id in (?) AND category_id IN (?) and  article_title like ?", ids, cids, "%测试%").ToSlice(nil)
	if err != nil {
		panic(err)
	}
	s := *slice
	for i := range s {
		fmt.Println(s[i])
	}
}

使用事务

// TestTransaction 使用事务
func TestTransaction(t *testing.T) {
	err := tcode.Transaction(ctx, func(ctx context.Context) error {
		var tb tables.TbTest
		tb.UserId = 199999
		tb.CategoryId = 123
		tb.ArticleCover = "rollback"
		tb.ArticleTitle = "ArticleTitle"
		tb.ArticleContent = "ArticleContent"
		tb.Type = 4
		tb.OriginalUrl = "OriginalUrl"
		tb.IsTop = 1
		tb.IsDelete = 0
		tb.Status = 1
		tb.Sortno = 99
		tb.UpdateTime = time.Now()
		insert, id, err := tcode.Insert(ctx, &tb)
		fmt.Println(insert, id, err)

		err2 := tcode.Transaction(ctx, func(ctx context.Context) error {
			var tb tables.TbTest
			tb.UserId = 199999
			tb.CategoryId = 123
			tb.ArticleCover = "commit"
			tb.ArticleTitle = "ArticleTitle"
			tb.ArticleContent = "ArticleContent"
			tb.Type = 4
			tb.OriginalUrl = "OriginalUrl"
			tb.IsTop = 1
			tb.IsDelete = 0
			tb.Status = 1
			tb.Sortno = 99
			tb.UpdateTime = time.Now()
			insert, id, err := tcode.Insert(ctx, &tb)
			fmt.Println(insert, id, err)
			return nil
		})
		fmt.Println(err2)

		insert, id, err = tcode.Insert(ctx, &tb)
		fmt.Println(insert, id, err)

		return errors.New("rollback")
	})
	fmt.Println(err)
}

开启调试sql

// TestDebugSQL 开启调试sql,会将参数值拼接好的完整sql打印至控制台,用户开发阶段调试复杂sql,可直接在sql控制台执行的sql
func TestDebugSQL(t *testing.T) {
    conf = &tcode.Config{
        Dsn:                   "root:root@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=true&loc=Local",
        DriverName:            "mysql",
        Dialect:               "mysql",
        MaxOpenConns:          50,
        MaxIdleConns:          50,
        ConnMaxLifetimeSecond: 600,
        PrimaryKeyColumnName:  "id",
        DebugSQL:              true,
    }
    _, _, _ = tcode.New(conf)
    ids := []int32{pkid}
    cids := []int{186}
    slice, err := tcode.Select[*tables.TbTest](context.Background()).AppendSQL("WHERE id in (?) AND category_id IN (?) and  article_title like ?", ids, cids, "%测试%").ToSlice(nil)
    if err != nil {
        panic(err)
    }
    s := *slice
    for i := range s {
        fmt.Println(s[i])
    }
}

日志重写

tcode.FuncLog = func(arbitrarily ...interface{}) {
    // 日志重写
}
tcode.FuncSQLLog = func(ms float64, sql string, params []any) {
    // sql日志重写
}

不实现Table接口进行表和结构体进行转换

// Test_rawTable_ConvertStruct 转换结构体
func Test_rawTable_ConvertStruct(t *testing.T) {
	test1 := struct {
		Id           int32
		ArticleTitle string
		CreateTime   time.Time
		UpdateTime   time.Time
		Sortno       int32
	}{}
	table, err := NewSqlInfo(ctx, "select * FROM tb_test where id=?", 1014).ToRawTable(nil)
	if err != nil {
		fmt.Println(err)
	}
	err = table.Convert(&test1)
	fmt.Println(err, test1)
}

// Test_rawTable_Convert_Slice 转换结构体切片
func Test_rawTable_Convert_Slice(t *testing.T) {
	var test1 []struct {
		Id           int32
		ArticleTitle string
		CreateTime   time.Time
		UpdateTime   time.Time
		Sortno       int32
	}
	table, err := NewSqlInfo(ctx, "select * FROM tb_test where id=?", 1014).ToRawTable(nil)
	if err != nil {
		fmt.Println(err)
	}
	err = table.Convert(&test1)
	fmt.Println(err, test1)
}

rawTable 转换基本类型切片

// Test_rawTable_ConvertColIndex_Var_Slice 转换基本类型切片
func Test_rawTable_ConvertColIndex_Var_Slice(t *testing.T) {
	var test1 []int
	table, err := NewSqlInfo(ctx, "select id,user_id FROM tb_test where id=?", 1014).ToRawTable(nil)
	if err != nil {
		fmt.Println(err)
	}
	err = ConvertColIndex(table, 1, &test1)
	fmt.Println(err, test1)
}

rawTable分页查询

// Test_rawTable_Convert_Slice rawTable分页查询
func Test_rawTable_Convert_Slice_QueryPage(t *testing.T) {
	var test1 []struct {
		Id           int32
		ArticleTitle string
		CreateTime   time.Time
		UpdateTime   time.Time
		Sortno       int32
	}
	newPage := NewPage()
	table, err := NewSqlInfo(ctx, "select * FROM tb_test").ToRawTable(newPage)
	if err != nil {
		fmt.Println(err)
	}
	err = Convert(table, &test1)
	fmt.Println(newPage, err, test1)
}

参与贡献

  1. Fork 本仓库
  2. 新建 Feat_master 分支
  3. 提交代码
  4. 新建 Pull Request

空文件

简介

Go语言轻量ORM,极简封装,支持基本类型,结构体,切片,分页结果映射,原始表数据映射(行,列) 展开 收起
README
Apache-2.0
取消

发行版

暂无发行版

贡献者

全部

语言

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/yan-shi-kun/tcode.git
git@gitee.com:yan-shi-kun/tcode.git
yan-shi-kun
tcode
tcode
v0.0.6

搜索帮助