基于iris-xorm-casbin-jwt 的权限管理项目1

GO 的权限管理项目

  • 项目介绍
    • 采用框架
    • 相关文档
    • 编写项目
      • orm工具类编写
        • 1. 配置文件编写-.env格式
        • 2. models 的结构体编写
        • 3. UserDao 类
        • 4.最后测试文件编写--测试dao里面的方法
      • 具体的项目代码后面博客会贴出
    • 下个博客记录iris 的学习

项目介绍

采用框架

  1. web框架-iris
  2. orm框架-xorm
  3. 权限管理框架-casbin
  4. 用户验证-jwt

相关文档

iris中文文档
casbin文档
xorm文档
jwt 文档在 iris中文文档中所介绍,这里不再给出

编写项目

orm工具类编写

1. 配置文件编写-.env格式

突然在GoLang软件中,发现这个插件试了下,感觉这个自动读取配置文件很舒服,所以在这就采用下

  1. 新建一个**.env 的文件,里面格式为key-value的格式
DBName=mysql
CONNECT_URL=root:123456@(localhost:3306)/atcrowdfunding-v1?charset=utf8
  1. 引用的import 的包
	"RBAC_GO/src/models"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/go-xorm/xorm"
	"github.com/joho/godotenv"
	_ "github.com/joho/godotenv/autoload"
  1. utils 文件的代码

func MysqlEngine() {
	// 读取配置文件
	myEnv := loadEnvText()
	var err error

	Engine, err = xorm.NewEngine(myEnv["DBName"], myEnv["CONNECT_URL"])
	if err != nil {
		fmt.Printf("错误信息:%e", err)
	}
	Engine.ShowSQL(true)
	Engine.Logger()
	err = Engine.Sync2(new(models.User), new(models.Role), new(models.Permission), new(models.OauthToken))
	if err != nil {
		fmt.Printf("同步结构错误:%v", err)
	}
}
// 项目从main方法启动,需要在db上面改动
func loadEnv() map[string]string {
	var myEnv map[string]string

	myEnv, err := godotenv.Read("test_db.env")
	if err != nil{
		fmt.Println(err)
	}
	return myEnv
}
// 后台的方法测试,使用 的绝对路径方法
func loadEnvText() map[string]string {
	var myEnv map[string]string

	myEnv, err := godotenv.Read("E:\\GO\\RBAC_GO\\test_db.env")
	if err != nil{
		fmt.Println(err)
	}

	return myEnv
}

重点说明下,sync2 是很方便的,但是这个是同步struct 到mysql中,但是并不能相互同步,只能够提供警告显示你的两种结构中存在的差别
如果是,先创建数据表,那么采用reverse 的工具进行生成结构,我没有试过,就不在这多说

2. models 的结构体编写

通过casbin的学习,往常的五个基本表的权限管理,这里可以简约成4个,只存在user,role,permission,rule表。
先贴出 user表代码

type User struct {
	Id         int    `xorm:" pk  int notnull autoincr unique"`
	Username   string `xorm:"varchar(255) "`
	LoginAcct  string `xorm:"varchar(255)  "`
	UserPsWd   string `xorm:"varchar(255)  "`
	Email      string `xorm:"varchar(255)  "`
	CreateTime int64 `xorm:"timestamp "`
}

如果想要同步结构体,必须在每个变量中声明在数据库中想要约定的信息,例如 主键,格式,长度,是否自增,是否为空等,xorm 是非常的强大。
建议指定,默认的格式,会有点麻烦

3. UserDao 类

package dao

import (
	"RBAC_GO/configs"
	"RBAC_GO/src/models"
	"bytes"
	"fmt"
)

// 查询所有user 信息
func QueryAll() (map[int64]models.User, error) {
	users := make(map[int64]models.User, 0)
	err := configs.Engine.Find(users)
	if err != nil {
		return nil, err
	}
	return users, nil
}

// 用户名loginacct 和密码判断用户名可以登录
func QueryLogin(user *models.User) (models.User, error) {
	//sqlStr := "select * from user where loginacct = ? and usepswd = ?"
	resultUser := models.User{}
	_, err := configs.Engine.Table("user").Where("login_acct = ? and user_ps_wd = ?",user.LoginAcct,user.UserPsWd).Get(&resultUser)

	if err != nil {
		fmt.Println("出现错误:", err)
		return resultUser, err
	}

	return resultUser, nil
}

// 更新用户信息
func UpdateUser(user *models.User) int64 {
	//sqlStr := "update t_user set loginacct = ?,?,?,? where id = ?"
	update, err := configs.Engine.ID(user.Id).Update(user)
	if err != nil {
		fmt.Printf("UpdateUser 出现异常:%e", err)
	}
	return update
}

//根据id 查找用户user
func QueryById(id int) (models.User, error) {
	resultUser := models.User{}
	err := configs.Engine.ID(id).Find(resultUser)
	if err != nil {
		return models.User{}, err
	}
	return resultUser, nil
}

// 通过user 的id 删除用户
func DeleteUserById(id int) int64 {

	//sqlStr := "delete from t_user where id = ?"

	results, err := configs.Engine.ID(id).Delete(models.User{})
	if err != nil {
		fmt.Printf("DeleteUserById 出现异常:%e", err)
	}
	return results
}

// 批量删除用户
func DeleteUsers(users map[string][]string) int64 {

	sqlstr := "delete from user where id in ("
	//定义Buffer类型
	var bt bytes.Buffer
	//向bt中写入字符串
	bt.WriteString(sqlstr)
	for n, i := range users["usersid"] {
		bt.WriteString(i)
		if n != len(users["usersid"])-1 {
			bt.WriteString(",")
		}
	}
	bt.WriteString(")")
	//获得拼接后的字符串
	sql1 := bt.String()
	fmt.Println(sql1)
	exec, err := configs.Engine.Exec(sqlstr)
	if err != nil {
		fmt.Println(err)
	}
	affected, _ := exec.RowsAffected()
	return affected
}

// 添加新用户
func InsertUser(user *models.User) (int64, error) {
	//sqlstr = "insert into user login_acct ,username,user_ps_wd,email,create_time values (?,?,?,?,?)"
	result, err := configs.Engine.InsertOne(user)
	if err != nil {
		return -1, err
	}
	return result, nil
}

// 分页查找user的数据
func PageQueryUserData(maps map[string]interface{}) ([]models.User, error) {

	users := make([]models.User, 0)
	if _, ok := maps["queryText"]; ok {
		sqlStr1 := "select * from user where login_acct like concat('%', ?, '%')  order by create_time desc limit ?,?"

		start := maps["start"].(int64)
		size := maps["size"].(int64)
		rows, err := configs.Engine.SQL(sqlStr1, maps["queryText"].(string), start, size).Rows(new(models.Role))
		if err != nil {
			return nil, err
		}
		defer rows.Close()
		for rows.Next() {
			user := models.User{}
			err = rows.Scan(&user)
			users = append(users, user)
			//...
		}
		return users, nil
	} else {
		sqlStr2 := "select * from role  limit ?,?"
		start := maps["start"].(int64)
		size := maps["size"].(int64)
		rows, err := configs.Engine.SQL(sqlStr2, start, size).Rows(new(models.Role))
		if err != nil {
			return nil, err
		}
		defer rows.Close()
		for rows.Next() {
			user := models.User{}
			err = rows.Scan(&user)
			users = append(users, user)
			//...
		}
		return users, nil
	}
}

// 分页查找user 的count
func PageQueryUserCount(maps map[string]interface{}) (int64, error) {
	if _, ok := maps["queryText"]; ok {
		sqlStr1 := "select count(*) from user  where name like concat('%', ?, '%')"

		count, err := configs.Engine.SQL(sqlStr1, maps["queryText"]).Count(new(map[string]models.User))
		if err != nil {
			return -1, err
		}
		return count, nil
	} else {
		sqlStr2 := "select count(*) from user"
		count, err := configs.Engine.SQL(sqlStr2).Count(new(map[string]models.User))
		if err != nil {
			return -1, err
		}

		return count, nil
	}
}

在xorm 中,有三种方法去查询数据,
一种是直接通过mysql语句执行——Exec 方法
一种是方法例如 Where,ID,Limit,Goup by等方法,组成一个完整的语句,并且在最后,可以将获取到的数据,直接映射到结构体中,方便读取。
最后一种是调用sql语句,但是还是可以将数据映射到结构体中。
这三种方法,各有各的优势。

4.最后测试文件编写–测试dao里面的方法

package dao

import (
	"RBAC_GO/configs"
	"RBAC_GO/src/models"
	"fmt"
	"testing"
	"time"
)


func TestMain(m *testing.M) {
	fmt.Println("write setup code here...") // 测试之前的做一些设置
	// 如果 TestMain 使用了 flags,这里应该加上flag.Parse()
	configs.MysqlEngine()
	m.Run()
	// 执行测试
	fmt.Println("write teardown code here...") // 测试之后做一些拆卸工作

}

func TestQueryAll(t *testing.T) {
	results, _ := QueryAll()

	fmt.Println(results)


}


func TestUpdateUser(t *testing.T) {
	user := models.User{
		Id:       1,
		UserPsWd: "admin",
		LoginAcct: "admin",
		Username: "lizi",
		Email: "[email protected]",
	}
   results := UpdateUser(&user)
   fmt.Println(results)
}

func TestDeleteUsers(t *testing.T) {
	users := make(map[string][]string,0)
	users["usersid"] = []string{"1","2"}
	deleteUsers := DeleteUsers(users)
	fmt.Println(deleteUsers)
}

func TestInsertUser(t *testing.T) {
	user  := models.User{
		Username:   "lll",
		LoginAcct:  "admin",
		UserPsWd:   "admin",
		Email:      "[email protected]",
		CreateTime: time.Now().Unix(),

	}

	fmt.Println(user)
	insertUser, err := InsertUser(&user)
	fmt.Println(user)
	if err != nil{
		fmt.Println("cuwou :",err)
	}
	fmt.Println(insertUser)
}

func TestQueryLogin(t *testing.T) {
	user  := models.User{
		LoginAcct:  "root",
		UserPsWd:   "admin",
	}
	login, _ := QueryLogin(&user)
	fmt.Println(login)
}

注意: 因为是采用xorm 框架,所以在测试方法前面要添加TestMain方法,在所有测试方法调用前,去启动xorm,连接mysql数据

具体的项目代码后面博客会贴出

下个博客记录iris 的学习

你可能感兴趣的:(GO)