golang sql mapper

eatmoreapple · · 1460 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

## Juice SQL Mapper Framework For Golang ![Go Doc](https://pkg.go.dev/badge/github.com/eatmoreapple/juice) ![Go Report Card](https://goreportcard.com/badge/github.com/eatmoreapple/juice) ![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg) This is a SQL mapper framework for Golang. It is inspired by MyBatis. Juice is a simple and lightweight framework. It is easy to use and easy to extend. ### Features * Simple and lightweight * Easy to use * Easy to extend * Support for multiple databases * Dynamic SQL * Result to entity mapping * Generic type support * Middleware support * Todo support more ### support xml tags * select * insert * update * delete * sql * if * where * trim * set * foreach * choose * when * otherwise * include ### Condition Method The condition method can be used with `if` or `when` tags. For example: ```xml <!--ids = []int{1,2,3}--> <if test='len(ids) > 0 && substr("eatmoreapple", 0, 3) == "eat"'> your sql node here </if> ``` It can register to the framework with your own condition method. Here are some default condition methods. * len: return the length of the given parameter * strsub: return the substring of the given parameter * join: join the given parameters with the given separator * contains: return true if the given parameter contains the given element * slice: return the slice of the given parameter ### Quick Start #### Install ```bash go get github.com/eatmoreapple/juice ``` #### Example ```shell touch config.xml ``` and write the following content into config.xml ```xml <?xml version="1.0" encoding="UTF-8"?> <configuration> <environments default="prod"> <environment id="prod"> <dataSource>root:qwe123@tcp(localhost:3306)/database</dataSource> <driver>mysql</driver> </environment> </environments> <mappers> <mapper namespace="main.UserRepository" table="user"> <sql id="columns"> `id`, `name`, `age` </sql> <sql id="selectAll"> select <include refid="columns"/> from ${table} </sql> <select id="GetUserByID" debug="true"> <include refid="selectAll"/> where id = #{param} </select> <insert id="CreateUser" debug="true"> insert into ${table} <trim prefix="(" suffixOverrides="," suffix=")"> <if test='name != ""'> name, </if> <if test="age > 0"> age, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test='name != ""'> #{name}, </if> <if test="age > 0"> #{age}, </if> </trim> </insert> <update id="UpdateUser" debug="true"> update ${table} <set> <if test='name != ""'> `name` = #{name}, </if> <if test="age > 0"> `age` = #{age}, </if> </set> where id = #{id} </update> <delete id="DeleteUserByID" debug="true" table="user"> delete from ${table} where id = #{param} </delete> </mapper> </mappers> </configuration> ``` ```go package main import ( "context" "fmt" "github.com/eatmoreapple/juice" "reflect" _ "github.com/go-sql-driver/mysql" ) var schema = ` CREATE TABLE IF NOT EXISTS user ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(255) COLLATE utf8mb4_bin NOT NULL, age int(11) NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; ` type User struct { Id int64 `column:"id" param:"id"` Name string `column:"name" param:"name"` Age int `column:"age" param:"age"` } type UserRepository interface { GetUserByID(id int64) CreateUser(user *User) UpdateUser(user *User) DeleteUserByID(id int64) } type UserRepositoryImpl struct{} func (u UserRepositoryImpl) UpdateUser(user *User) { //TODO implement me panic("implement me") } func (u UserRepositoryImpl) DeleteUserByID(id int64) { //TODO implement me panic("implement me") } func (u UserRepositoryImpl) CreateUser(user *User) { //TODO implement me panic("implement me") } func (u UserRepositoryImpl) GetUserByID(id int64) { //TODO implement me panic("implement me") } func main() { cfg, err := juice.NewXMLConfiguration("config.xml") if err != nil { fmt.Println(err) return } engine, err := juice.DefaultEngine(cfg) if err != nil { fmt.Println(err) return } // create table first if _, err = engine.DB.Exec(schema); err != nil { fmt.Println(err) return } var repo UserRepository = UserRepositoryImpl{} // create user first user := &User{ Name: "eatmoreapple", Age: 18, } result, err := engine.Object(repo.CreateUser).ExecContext(context.Background(), user) if err != nil { fmt.Println(err) return } user.Id, err = result.LastInsertId() if err != nil { fmt.Println(err) return } // query user rows, err := engine.Object(repo.GetUserByID).Query(user.Id) if err != nil { fmt.Println(err) return } defer rows.Close() // todo: iterate rows with your own way // query user with auto mapping user2, err := juice.NewGenericManager[*User](engine).Object(repo.GetUserByID).Query(user.Id).One() if err != nil { fmt.Println(err) return } if reflect.DeepEqual(user, user2) { fmt.Println("user and user2 are equal") } else { fmt.Println("user and user2 are not equal") return } // with transaction // begin transaction // begin tx := engine.Tx() // update user with tx user.Name = "eatmoreapple2" user.Age = 20 result, err = tx.Object(repo.UpdateUser).ExecContext(context.Background(), user) if err != nil { fmt.Println(err) tx.Rollback() return } affected, err := result.RowsAffected() if err != nil { fmt.Println(err) tx.Rollback() return } fmt.Printf("update affected rows: %d\n", affected) // delete user with tx result, err = tx.Object(repo.DeleteUserByID).ExecContext(context.Background(), user.Id) if err != nil { fmt.Println(err) tx.Rollback() return } affected, err = result.RowsAffected() if err != nil { fmt.Println(err) tx.Rollback() return } fmt.Printf("delete affected rows: %d\n", affected) // commit if err = tx.Commit(); err != nil { fmt.Println(err) return } } ``` ### License Juice is licensed under the Apache License, Version 2.0. See LICENSE for the full license text. ### Contact If you like this project, please give me a star. Thank you. And If you have any questions, please contact me by WeChat: eatmoreapple or scan the following QR code. <img width="210px" src="https://github.com/eatmoreapple/eatMoreApple/blob/main/img/wechat.jpg" align="left">

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1460 次点击  ∙  1 赞  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传