0 Star 0 Fork 0

asktop_golib / dbr

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

mysql数据库操作工具包

1. 使用说明

使用方法详见 example/dbr_test.go 测试用例

2. 使用测试用例

package example

import (
	"fmt"
	"gitee.com/asktop_golib/dbr"
)

func Session() *dbr.Session {
	config := new(dbr.MysqlConfig)
	config.Host = "127.0.0.1"
	config.Port = 3306
	config.Username = "root"
	config.Password = "kf123456"
	config.Database = "dbr_test"
	conn, err := dbr.NewConnWithMyqsl(config)
	if err != nil {
		fmt.Println("连接数据库失败")
		panic(err)
	}
	return conn.NewSession(nil)
}
package example

import (
	"fmt"
	"gitee.com/asktop_golib/dbr"
	"gitee.com/asktop_golib/dbr/dialect"
	"testing"
	"time"
)

//对象定义规范
type Demo struct {
	Id         int64
	User_id    int64  //数据库字段名:user_id		下划线法,首字母大写
	UserName   string //数据库字段名:user_name	驼峰法,首字母和下划线后首字母大写
	CreateTime int64  `db:"w_time"` //数据库字段名:w_time		标签法,自由指定,标签为 db ;而不是 dbr
}

type DemoConfig struct {
	Id     int64  `json:"id" db:"id"`
	Module string `json:"module" db:"module"` //模块名
	Name   string `json:"name" db:"name"`     //参数名
	Value  string `json:"value" db:"value"`   //参数值
	Remark string `json:"remark" db:"remark"` //备注
	Status int64  `json:"status" db:"status"` //状态[0:禁用,1:启用]
	//CreateTime *decimal.Big    `json:"create_time" db:"create_time"` //创建时间
}

func TestGetSql(t *testing.T) {
	where := dbr.And(
		dbr.Eq("a.id", 1),
		dbr.Gte("time", 2),
	)
	sql, err := dbr.GetSQL(where, dialect.MySQL)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(sql)
}

//普通查询
// 拼接where条件: in 的值可以是一个数组
func TestDbrSelect1(t *testing.T) {
	sess := Session()

	ids := []int{7, 8, 9}

	stmt := sess.Select("id", "name", "value").From("config").Where("id >= ? AND id < ? OR id in ?", 1, 5, ids)

	//可以单独获取sql语句(必须在 Rows 执行之前执行,否则无法获取)
	sql, _ := stmt.GetSQL()
	fmt.Println(sql)

	rows, err := stmt.Rows()
	if err != nil {
		fmt.Println(err)
	} else {
		defer rows.Close()
		for rows.Next() {
			var id int64
			var key, value string
			rows.Scan(&id, &key, &value)
			fmt.Println(id, key, value)
		}
	}
}

//普通查询
// dbr组装where条件:eq 的值可以是一个数组
func TestDbrSelect2(t *testing.T) {
	sess := Session()

	ids := []int{7, 8, 9}
	var configs []DemoConfig
	where := dbr.And(dbr.Gte("id", 1), dbr.Lt("id", 5))
	where = dbr.Or(where, dbr.Eq("id", ids))

	stmt := sess.Select("id", "name", "value", "create_time", "update_time").From("config").Where(where)

	//可以单独获取sql语句(必须在 Load 执行之前执行,否则无法获取)
	sql, _ := stmt.GetSQL()
	fmt.Println(sql)

	count, err := stmt.Load(&configs) //若只查一条数据,使用 LoadOne
	if err != nil {
		fmt.Println(err)
	} else {
		for _, config := range configs {
			fmt.Println(config)
		}
		fmt.Println(count)
	}
}

//查询结果加载到map数组中
// 每一条数据库记录在一个map中
// map值的类型必须指定,不能是interface
func TestDbrSelectMaps(t *testing.T) {
	sess := Session()

	var maps []map[string]string
	_, err := sess.Select("id", "name", "value").From("config").Where("id >= ? AND id < ?", 1, 5).Load(&maps)
	if err != nil {
		fmt.Println(err)
	} else {
		for _, row := range maps {
			fmt.Println(row["id"], ":", row["name"], ":", row["value"])
		}
	}
}

//查询2个字段,将结果加载到map中
// map值的类型必须指定,不能是interface
func TestDbrSelectMap(t *testing.T) {
	sess := Session()

	var maps map[string]string
	_, err := sess.Select("name", "value").From("config").Where("id >= ? AND id < ?", 1, 5).Load(&maps)
	if err != nil {
		fmt.Println(err)
	} else {
		for key, value := range maps {
			fmt.Println(key, ":", value)
		}
	}
}

//子查询
// Expr 自定义表达式
func TestDbrSelectExpr(t *testing.T) {
	sess := Session()

	var maps []map[string]string
	count, err := sess.Select("name", "start_time", "msg").From("task_log").
		Where("name in (select name from task where id in ?)", []int64{2}). //非表达式方式
		//Where(Expr("name in (select name from task where id in ?)", []int64{2})). //表达式方式
		Load(&maps)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(count)
		for _, data := range maps {
			fmt.Println(data)
		}
	}
}

//联表查询
func TestDbrSelectJoin(t *testing.T) {
	sess := Session()

	var maps []map[string]string
	count, err := sess.Select("tl.name", "tl.start_time", "tl.msg").From("task_log tl").
		LeftJoin("task t", "tl.name = t.name").
		Where(dbr.Eq("t.id", []int64{2})).
		Load(&maps)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(count)
		for _, data := range maps {
			fmt.Println(data)
		}
	}
}

//Between查询
func TestDbrSelectBetween(t *testing.T) {
	sess := Session()

	ids := []int{7, 8, 9}
	rows, err := sess.Select("id", "name", "value").From("config").
		Where(dbr.Or(dbr.Between("id", 1, 5), dbr.Eq("id", ids))).Rows()
	if err != nil {
		fmt.Println(err)
	} else {
		defer rows.Close()
		for rows.Next() {
			var id int64
			var key, value string
			rows.Scan(&id, &key, &value)
			fmt.Println(id, key, value)
		}
	}
}

//插入|批量插入
// 直接插入值
// 插入对象值
func TestDbrInsert(t *testing.T) {
	sess := Session()

	config3 := DemoConfig{
		Name:  "key3",
		Value: "value3",
	}
	config4 := DemoConfig{
		Name:  "key4",
		Value: "value4",
	}
	stmt := sess.InsertInto("config").
		Columns("name", "value").
		Values("key1", "value1"). //直接插入值
		Values("key2", "value2"). //直接插入值
		Record(&config3). //插入对象值
		Record(&config4) //插入对象值

	//可以单独获取sql语句(必须在Exec执行之前执行,否则无法获取)
	sql, _ := stmt.GetSQL()
	fmt.Println(sql)

	stmt.SetRunLen(3) //设置批量一次执行条数,可以不设,默认1000

	rs, err := stmt.Exec()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(rs.LastInsertId()) //批量插入第一条的id
		fmt.Println(rs.RowsAffected())
	}
}

//插入|批量插入
// 插入map
func TestDbrInsertMap(t *testing.T) {
	sess := Session()

	kv := map[string]interface{}{
		"name":  "key5",
		"value": "value5",
	}
	rs, err := sess.InsertInto("config").Map(kv).Exec()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(rs.LastInsertId())
	}
}

//更新
// 直接更新
func TestDbrUpdate(t *testing.T) {
	sess := Session()

	stmt := sess.Update("config").
		Set("value", "value1 u").
		Set("status", dbr.Expr("status - ?", "1")). //值为表达式
		Set("update_time", time.Now().Unix()).
		Where("name = 'key1'")

	//可以单独获取sql语句(必须在Exec执行之前执行,否则无法获取)
	sql, _ := stmt.GetSQL()
	fmt.Println(sql)

	rs, err := stmt.Exec()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(rs.RowsAffected())
	}
}

//更新
// map方式更新
func TestDbrUpdateMap(t *testing.T) {
	sess := Session()

	setMap := map[string]interface{}{
		"value":       "value2 u",
		"status":      dbr.Expr("status + ?", "1"), //值为表达式
		"update_time": time.Now().Unix(),
	}
	rs, err := sess.Update("config").
		SetMap(setMap).
		Where("name = 'key2'").Exec()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(rs.RowsAffected())
	}
}

//批量更新
func TestDbrCaseUpdate(t *testing.T) {
	sess := Session()

	stmt := sess.CaseUpdate("user").
		// 主键字段 更新字段...
		Columns("name", "age", "info").
		// 主键值	对应更新字段值...
		Values("a", dbr.Expr("age + ?", 10), "aaa").
		Values("b", dbr.Expr("age - ?", 1), "bbb").
		Values("c", 31, "ccc").
		Values("d", 41, "ddd")

	//可以单独获取sql语句(必须在Exec执行之前执行,否则无法获取)
	sql, _ := stmt.GetSQL()
	fmt.Println(sql)

	stmt.SetRunLen(3) //设置批量一次执行条数,可以不设,默认1000

	err := stmt.Exec()
	fmt.Println(err)

	//sql语句为:
	/*
	   UPDATE `user`
	   SET `age` =
	       CASE `name`
	   WHEN 'a' THEN
	   age + 10
	   WHEN 'b' THEN
	   age - 1
	   WHEN 'c' THEN
	   31
	   WHEN 'd' THEN
	   41
	   END,
	   `info` =
	   CASE `name`
	   WHEN 'a' THEN
	   'aaa'
	   WHEN 'b' THEN
	       'bbb'
	   WHEN 'c' THEN
	       'ccc'
	   WHEN 'd' THEN
	       'ddd'
	   END
	   WHERE
	   `name` IN ('a', 'b', 'c', 'd')
	*/
}

//删除
func TestDbrDelete(t *testing.T) {
	sess := Session()

	names := []string{
		"key1",
		"key2",
		"key3",
		"key4",
		"key5",
	}
	rs, err := sess.DeleteFrom("config").Where("name in ?", names).Exec()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(rs.RowsAffected())
	}
}

type DemoUser struct {
	UserId   int64
	Mobile   string
	Username string
}

//缓存到redis
func TestDbrCache(t *testing.T) {
	//sess := Session()

	//此处循环调用,不能再此处测试
	//err := cache.StartRedis(cache.Config{Host: "127.0.0.1", Password: "kf123456", Select: 0})
	//if err != nil {
	//    panic(err)
	//}
	//redisconn := cache.NewRedis(true)
	//defer redisconn.Close()
	//
	//stmt := sess.Select("user_id", "mobile", "username").From("user").Where(Eq("user_id", []int64{1, 2, 3}))
	//
	//stmt.Cache(redisconn, "test", 60) //缓存到redis
	//
	//sql, err := stmt.GetSQL()
	//if err != nil {
	//    fmt.Println("GetSQL:", err)
	//} else {
	//    fmt.Println("GetSQL:", sql)
	//}
	//count, err := stmt.Count()
	//if err != nil {
	//    fmt.Println("Count:", err)
	//} else {
	//    fmt.Println("Count:", count)
	//}
	//users := []DemoUser{}
	//count, err = stmt.Load(&users)
	//if err != nil {
	//    fmt.Println("Return:", err)
	//} else {
	//    fmt.Println("Return:", count)
	//    fmt.Println("Return:", users)
	//}
}

3. dbr对数据加密解密实现的原理

测试用例:https://gitee.com/asktop_golib/dbr/blob/master/example/encrypt_test.go

1)配置上:将数据加密解密函数等注入dbr

//设置dbr数据加密解密方法
dbr.EncryptData = encrypt.EncryptData

//设置dbr数据加密解密方法
dbr.DecryptData = encrypt.DecryptData

2)查询时,若想对查询结果的某些字段进行数据解密,仅需调 func (b *SelectStmt) Encrypt(columns ...string) *SelectStmt

//测试解密数据
func TestDecrypt(t *testing.T) {
	dbr.SetDataEncryptDecryptFunc(EncryptData, DecryptData)

	sess := Session()
	table := "user"

	users := []*User{}
	_, err := sess.Select("*").From(table).
		Encrypt("phone").
		Load(&users)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("ok")
	fmt.Println(len(users))
	for _, user := range users {
		fmt.Println(user)
	}
}

3)插入或修改时,若想对赋值的某些字段进行数据加密,仅需调 func (b *InsertStmt) Encrypt(columns ...string) *InsertStmt

//测试加密数据
func TestEncrypt(t *testing.T) {
	dbr.SetDataEncryptDecryptFunc(EncryptData, DecryptData)

	sess := Session()
	table := "user"

	_, err := sess.InsertInto(table).Columns("name", "phone").
		Values("张A", "18769910003").
		Values("张B", 123).
		Encrypt("phone").
		Exec()
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("ok")
}

4)注意!!!where条件不支持字段自动加解密,需要调加解密函数!

1.所有表数据操作的 Where 条件的数据需要手动加密!!!
2.数据加密函数: dbr.EncryptData()
3.数据解密函数: dbr.DecryptData()
例如:要查手机号是 18769910001 的用户:

// where条件中的手机号需要手动解密 dbr.EncryptData("187699910001")
// 查询结果 user 中的手机号,是models自动解密过的明文数据
func TestDecrypt(t *testing.T) {
	dbr.SetDataEncryptDecryptFunc(EncryptData, DecryptData)

	sess := Session()
	table := "user"

	users := []*User{}
	_, err := sess.Select("*").From(table).
		Encrypt("phone").
		Where(dbr.Eq("phone", dbr.EncryptData("187699910001")).
		Load(&users)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("ok")
	fmt.Println(len(users))
	for _, user := range users {
		fmt.Println(user)
	}
}

5)数据加密解密sql

-- 数据加密
select phone, CONCAT('MMM_', HEX(AES_ENCRYPT(phone, 'ABCQRFGHAXVDEFGH'))) as phone2 from pp_user
where phone != '' and phone not like 'MMM_%' and phone not like '%*%';
-- 数据解密
select phone, AES_DECRYPT(UNHEX(SUBSTR(phone, 5)), 'ABCQRFGHAXVDEFGH') as phone2 from pp_user
where phone != '' and phone like 'MMM_%';


-- 数据加密
SELECT CONCAT('MMM_', HEX(AES_ENCRYPT('18769910001', 'ABCQRFGHAXVDEFGH'))) as phone; -- MMM_5C44B25562B0EB3282CD15E12E542DC1
-- 数据解密
SELECT AES_DECRYPT(UNHEX(SUBSTR('MMM_5C44B25562B0EB3282CD15E12E542DC1', 5)), 'ABCQRFGHAXVDEFGH') as phone; -- 18769910001

空文件

简介

mysql数据库操作工具包 展开 收起
Go
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Go
1
https://gitee.com/asktop_golib/dbr.git
git@gitee.com:asktop_golib/dbr.git
asktop_golib
dbr
dbr
master

搜索帮助