代码拉取完成,页面将自动刷新
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)
}
// 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)
}
// 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)
}
// 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日志重写
}
// 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 = Convert(table,&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 = Convert(table,&test1)
fmt.Println(err, test1)
}
// 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)
}
// 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. 开源生态
2. 协作、人、软件
3. 评估模型