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

news2024/11/16 10:22:53

【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 {
	//创建结构体CRUD4Oracle
	return &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 {
	//创建结构体CRUD4Dm
	return &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 dothing

import (
	"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,DELETE
	SQL    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 SQL
	switch 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
		}
		//执行SQL
		doSQL(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 string
	switch 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 DELETE
		result = "\"只能执行 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.coloradmin.cn/o/1376777.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

黑群晖6.x 7.x ABB Active Backup for Business 套件激活方法

注意事项: 要先下载安装好Active Backup for Business套件再操作。SN码在【控制面板】 - 【信息中心】 -【产品序列号】。建议复制到记事本内修改内容。群晖的https是默认的5001端口,如果你的https端口号换过请自行修改:5001 为当前的端口号…

应用在热能表领域中的数字温度传感芯片

热能表,是适用于测量在热交换环路中,被称作载热液体的液体所吸收或转换热能的仪器,它由流量传感器、温度传感器和热能积算仪三部分组成。热量表(热表)又称热能表、热能积算仪,既能测量供热系统的供热量又能…

Zabbix6.0全套落地方案-基于RHEL9系列源码编译安装-Linux+Nginx+Mysql+Redis生产级模板Agent2客户端一键部署

实践说明:基于RHEL9系列(CentOS9,AlmaLinux9,RockyLinux9等),但适用场景不限于此,客户端一键部署安装包基于RHEL8和RHEL9。 文档形成时期:2023年 因系统或软件版本不同,构建部署可能略有差异,但本文未做细分…

便携式灯具的UL测试标准UL153介绍

UL153标准:UL153标准主要是描述有关使用电源线及插头作为连接工具,使用120伏电压,15或20安培的电源,并符合美国国家电器规范的便携灯.此标准也适用于那些不用插头,而用一些兼容的接线端作为连接工具的便携灯,同时对于使用非120伏电压,15or20安…

Google I/O大会:Android 13

3个体验升级的方向 以智能手机为场景核心、 扩大智能终端的应用边界以及实现多设备间更好地协同。具体到系统体验层,安卓13将支持图标颜色随主题更换、为不同应用设定使用的语言、新的媒体中心界面等等,同时谷歌也推出了自家的钱包应用(Goog…

C++程序员必备的面试技巧

“程序员必备的面试技巧,就像是编写一段完美的代码一样重要。在面试战场上,我们需要像忍者一样灵活,像侦探一样聪明,还要像无敌铁金刚一样坚定。只有掌握了这些技巧,我们才能在面试的舞台上闪耀光芒,成为那…

雪花代码-html版

雪花代码 动画效果 代码 <!DOCTYPE html><html><head><style>body {background-color: #000000;}.snowflake {position: absolute;font-size: 10px;color: #FFFFFF;text-shadow: 1px 1px 1px #000000;user-select: none;}</style></head>…

java基于ssm框架的少儿编程在线培训系统论文

目 录 目 录 I 1 课题背景及研究内容 4 1.1 课题背景 4 1.2 开发目的和意义 4 2 相关技术和应用 4 2.1 VUE技术 4 2.2 Mysql数据库简介 5 2.3 SSM框架简介 6 2.4 Eclipse简介 6 2.5 B/S系统架构 6 3 系统分析 8 3.1可行性分析 8 3.1.1技术可行性 8 3.1.2经济可行性 8 3.1.3操作…

【会议征稿通知】第二届数字化经济与管理科学国际学术会议(CDEMS 2024)

第二届数字化经济与管理科学国际学术会议&#xff08;CDEMS 2024&#xff09; 2024 2nd International Conference on Digital Economy and Management Science&#xff08;CDEMS 2024&#xff09; 2024年第二届数字经济与管理科学国际会议(CDEMS 2024) 定于2023年4月26-28日…

怎么做微信秒杀链接_开启用户的购物新体验

微信秒杀&#xff1a;开启你的购物新体验 在繁忙的生活节奏中&#xff0c;你是否厌倦了长时间排队等待购物&#xff0c;或者在电商平台上漫长而复杂的购物流程&#xff1f;今天&#xff0c;我要向你介绍一种全新的购物方式——微信秒杀。这不仅是一种全新的购物体验&#xff0…

基于SpringBoot的婚恋交友网站 JAVA简易版

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 会员管理模块2.3 新闻管理模块2.4 相亲大会管理模块2.5 留言管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 会员信息表3.2.2 新闻表3.2.3 相亲大会表3.2.4 留言表 四、系统展示五、核心代码5.…

git: Updates were rejected because the tip of your current branch is behind

一、报错含义 由于本地分支的tip落后远程分支&#xff0c;push操作被拒绝。 二、产生原因 我再本地拉去了新的分支并未同步到远程仓库&#xff0c;在新分支进行开发&#xff0c;由于前几天同步也创建了该分支并同步到了远程仓库&#xff0c;导致我本次push失败 三、解决方…

使用proteus进行主从JK触发器仿真失败原因的分析

在进行JK触发器的原理分析的时候&#xff0c;我首先在proteus根据主从JK触发器的原理进行了实验根据原理图&#xff0c;如下图&#xff1a; 我进行仿真&#xff0c;在仿真的过程中&#xff0c;我向电路图中添加了外部的置0/1端口&#xff0c;由此在proteus中得到下面的电路图 …

数据库课设--家电销售订单管理系统

1.1课程设计选题 《家电销售订单管理系统》 1.2课程设计的目的 学生在充分理解《数据库应用》课程知识点的基础上&#xff0c;初步掌握将数据库应用于具体的管理信息系统中。把数据库原理、数据库应用有机的结合在一起&#xff0c;以数据库原理的理论为指导设计数据库&#xff…

Vue3 父事件覆盖子事件,Vue2 的 v-on=“$listeners“ 的替代方案

在 Vue3 中&#xff0c;$listeners 被删除 子组件代码&#xff0c;需要特别注意的是事件名为 on 开头&#xff0c;例如 onBack。不确定的可以通过给父组件传递 事件或属性&#xff0c;再打印子组件的 attrs useAttrs()&#xff0c;来确定传值 // template v-bind"newA…

shp文件与数据库(创建shp文件)

前言 前面把shp文件中的内容读取到数据库&#xff0c;接下来就把数据库中的表变成shp文件。 正文 简单的创建一个shp文件 暂时不读取数据库的表&#xff0c;先随机创建一个shp文件。既然是随机的&#xff0c;这就需要使用到faker这个第三方库&#xff0c;代码如下。 impor…

【python,机器学习,nlp】RNN循环神经网络

RNN(Recurrent Neural Network)&#xff0c;中文称作循环神经网络&#xff0c;它一般以序列数据为输入&#xff0c;通过网络内部的结构设计有效捕捉序列之间的关系特征&#xff0c;一般也是以序列形式进行输出。 因为RNN结构能够很好利用序列之间的关系&#xff0c;因此针对自…

Web实战丨基于Django与HTML的新闻发布系统

文章目录 写在前面项目简介项目框架实验内容安装依赖库1.创建项目2.系统配置3.配置视图文件4.配置模型文件5.配置管理员文件6.配置模板文件7.创建数据库8.启动项目 运行结果写在后面 写在前面 本期内容&#xff1a;基于Django与HTML的简单新闻发布系统。 项目需求&#xff1a…

linux高级篇基础理论十一(GlusterFS)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️不能因为人生的道路坎坷,就使自己的身躯变得弯曲;不能因为生活的历程漫长,就使求索的 脚步迟缓。 ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xff1a;云计算技…

以用户为导向,可定制化高精度直线模组降本增效正当时

近年来&#xff0c;随着工业自动化转型升级不断提速&#xff0c;市场对优质直线模组的需求量直线上升&#xff0c;而直线模组拥有单体运动速度快、重复定位精度高、本体质量轻、占设备空间小、寿命长等优势&#xff0c;在机械设备领域备受青睐。作为深耕工业自动化产品市场多年…