当前位置: 首页 > news >正文

【REST2SQL】06 GO 跨包接口重构代码

【REST2SQL】01RDB关系型数据库REST初设计
【REST2SQL】02 GO连接Oracle数据库
【REST2SQL】03 GO读取JSON文件
【REST2SQL】04 REST2SQL第一版Oracle版实现
【REST2SQL】05 GO 操作 达梦 数据库

对所有关系数据的操作都只有CRUD,采用Go 的接口interface{}重构代码,代码更简洁、易维护。

1 创建接口声明包

在 REST2sql目录下创建一个dbif的子目录,在此子目录下创建dbif.go包,文件组织结构如下图:
在这里插入图片描述
接口包代码如下:

// 数据库接口定义
package dbif// 数据库操作接口
type CRUD interface {InsertData(string) string //插入,返回影响行数json字符串SelectData(string) string //查询, 返回查询结果json字符串UpdateData(string) string //更新,返回影响行数json字符串DeleteData(string) string //删除,返回影响行数json字符串IsResource(string) bool   //在系统对象表总查找资源是否有效,用户表或视图
}

2 dboracle包重构

2.1 引入接口包dbif

import ("database/sql/driver""encoding/json""io""log""rest2sql/config"db "rest2sql/dbif" //数据库接口包"strings"go_ora "github.com/sijms/go-ora/v2" // 1 go get github.com/sijms/go-ora/v2
)

2.2 声明CRUD4Oracle结构体

作为接口函数的接收者,或者说接口绑定对象。

type CRUD4Oracle struct {//Oracle的CRUD操作,结构体
}

2.3 创建New()构造函数

直接返回,结构体指针。

func New() db.CRUD {//创建结构体CRUD4Oraclereturn &CRUD4Oracle{}
}

2.4 实现接口的全部函数或方法

原来的CRUD函数加上接受者即可,或者说绑定结构体

// delete
func (crud *CRUD4Oracle) DeleteData(deleteSql string) string {}
// update
func (crud *CRUD4Oracle) UpdateData(updateSql string) string {}
// insert
func (crud *CRUD4Oracle) InsertData(insertSql string) string {}
// select查询,结果为json
func (crud *CRUD4Oracle) SelectData(sqls string) string {}

原来dothing包的资源检查函数 isRes( resName string) bool ,用接口重构,不同数据库实现稍微不同。

// REST请求时检查资源是否有效
func (crud *CRUD4Oracle) IsResource(resName string) bool {icurd := New()resname := strings.ToUpper(resName)resSQL := "select object_name from user_objects where object_type in ('TABLE','VIEW') and object_name = '" + resname + "'"//执行数据库查询result := icurd.SelectData(resSQL)//检查数据库是否有此表if strings.Contains(result, resname) {return true} else {return false}
}

3 dbdm包重构

和oracle重构类似,只有结构体和New() 不同

3.1 引入dbif包

import db "rest2sql/dbif"

3.2 声明CRUD4Dm结构体

type CRUD4Dm struct {//Dm的CRUD操作,结构体
}

3.3 创建New()构造函数

func New() db.CRUD {//创建结构体CRUD4Dmreturn &CRUD4Dm{}
}

3.4 实现接口的全部函数或方法

原来的CRUD函数加上接受者即可,或者说绑定结构体

/* 往表插入数据 */
func (crud *CRUD4Dm) InsertData(insertSql string) string {}
/* 删除表数据 */
func (crud *CRUD4Dm) DeleteData(deleteSql string) string {}
/* 修改表数据 */
func (crud *CRUD4Dm) UpdateData(updateSql string) string {}
/* 查询表数据 */
func (crud *CRUD4Dm) SelectData(sqlSelect string) string {}// REST请求时检查资源是否有效
func (crud *CRUD4Dm) IsResource(resName string) bool {icurd := New()resname := strings.ToUpper(resName)resSQL := "select object_name from user_objects where object_type in ('TABLE','VIEW') and object_name = '" + resname + "'"//执行数据库查询result := icurd.SelectData(resSQL)//检查数据库是否有此表if strings.Contains(result, resname) {return true} else {return false}
}

4 Dothing包的重构

4.1 引入接口和数据库包

// dothing project dothing.go
package dothingimport ("encoding/json""fmt""net/http""rest2sql/config"dm "rest2sql/dbdm"db "rest2sql/dbif"ora "rest2sql/dboracle""strings"
)

4.2 声明接口全局变量

// 当前连接的数据库类型oracle
var (DBType string = config.Conf.DBType //数据库类型REST   string = config.Conf.REST   //支持的REST:GET,POST,PUT,DELETESQL    string = config.Conf.SQL    //支持的SQL:SELECT,INSERT,UPDATE,DELETE
)
// 声明CRUD操作的全局接口变量
var Icrud db.CRUD

4.3 创建全局变量构造函数createDBType

// 根据数据库类型,创建crud对象
func createDBType() {switch DBType {case "oracle":Icrud = ora.New()case "dm":// 达梦Icrud = dm.New()default:// 不支持的数据库}
}// 调用接口函数
// 根据请求类型参数执行不同的操作 
func DoThing(w http.ResponseWriter, req map[string]interface{}) {//创建数据库接口createDBType()w.Write([]byte("\n"))//请求类型 REST or SQLswitch req["RESTorSQL"] {case "REST"://REST请求方法过滤sMethod := strings.ToUpper(req["Method"].(string))if !strings.Contains(REST, sMethod) {w.Write([]byte("!!!不准许的REST请求,检查配置文件config.json的REST项。"))return}//执行REST请求doREST(w, req)case "SQL"://SQL过滤resSQL := req["ResName"].(string)sqlToUpper := strings.ToUpper(resSQL)sql6 := sqlToUpper[:6]if !strings.Contains(SQL, sql6) {w.Write([]byte("!!!不准许的SQL请求,检查配置文件config.json的SQL项。"))return}//执行SQLdoSQL(w, req)}
}

4.4 检查资源是否有效的调用

//资源名resName := req["ResName"].(string)// 检查是否有效资源if !Icrud.IsResource(resName) {//if !isRes(resName) {w.Write([]byte("\nerror:无效资源" + resName))return} else {//w.Write([]byte("\nresName:" + resName))}

4.5 doSQL重构

重构了switch case

// 根据请求参数执行不同的操作 
func doSQL(w http.ResponseWriter, req map[string]interface{}) {//w.Write([]byte("\ndoSQL()\n"))w.Write([]byte("\"Response\":"))//资源名sql语句resSQL := req["ResName"].(string)fmt.Println("SQL://", resSQL)sqlToUpper := strings.ToUpper(resSQL)sql6 := sqlToUpper[:6]var result stringswitch sql6 {case "SELECT":result = Icrud.SelectData(resSQL)case "INSERT":result = Icrud.InsertData(resSQL)case "UPDATE":result = Icrud.UpdateData(resSQL)case "DELETE":result = Icrud.DeleteData(resSQL)default:// 过滤sql ,只能执行 SELECT INSERT UPDATE DELETEresult = "\"只能执行 SELECT INSERT UPDATE DELETE\""}fmt.Println("SQL://", resSQL)w.Write([]byte(result))w.Write([]byte("}"))
}

4.6 REST4种请求的重构

// get
//执行 sql并返回 json 结果fmt.Println("REST://", selectSQL)result := Icrud.SelectData(selectSQL)
// post
//执行 insertSQL 并返回 json 结果fmt.Println("REST://:", insertSQL)result := Icrud.InsertData(insertSQL)
// put 
//执行 insertSQL 并返回 json 结果fmt.Println("REST://", updateSQL)result := Icrud.UpdateData(updateSQL)
// delete
//执行 sql并返回 json 结果fmt.Println("REST://", deleteSQL)result := Icrud.DeleteData(deleteSQL)

5 测试结果

总体代码组织
在这里插入图片描述

Oracle OK
达梦dm OK

控制台执行日志:
在这里插入图片描述

浏览器请求及返回:

在这里插入图片描述

《06 完》

http://www.lryc.cn/news/278995.html

相关文章:

  • 《NLP入门到精通》栏目导读
  • C++学习笔记——类继承
  • ARCGIS PRO SDK 使用条件管理 Pro UI
  • Halcon经典的边缘检测算子Sobel/Laplace/Canny
  • 用单片机设计PLC电路图
  • 【设计模式-6】建造者模式的实现与框架中的应用
  • PositiveSSL和Sectigo的多域名证书
  • Docker:docker exec命令简介
  • 【大数据进阶第三阶段之Hive学习笔记】Hive的数据类型与数据操作
  • GPT2:Language Models are Unsupervised Multitask Learners
  • 微创新与稳定性的权衡
  • 对回调函数的各种讲解说明
  • Java多线程:创建多线程的三种方式
  • Unity中打印信息的两种方式
  • 给定n个字符串s[1...n], 求有多少个数对(i, j), 满足i < j 且 s[i] + s[j] == s[j] + s[i]?
  • Linux磁盘空间与文件大小查看命令详解
  • 网络通信过程的一些基础问题
  • STL——stack容器和queue容器详解
  • django websocket实现聊天室功能
  • 软件测评中心▏性能测试之压力测试、负载测试的区别和联系简析
  • Go 语言 panic 和 recover 详解
  • NAND Separate Command Address (SCA) 接口数据传输解读
  • 彻底认识Unity ui设计中Space - Overlay、Screen Space - Camera和World Space三种模式
  • 档案数字化怎样快速整理资料
  • 面试算法100:三角形中最小路径之和
  • androj studio安装及运行源码
  • 【Web】token机制
  • JVM 11 调优指南:如何进行JVM调优,JVM调优参数
  • 横版动作闯关游戏:幽灵之歌 GHOST SONG 中文版
  • 【C++】:C++中的STL序列式容器vector源码剖析