当前位置: 首页 > 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 完》

相关文章:

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

【REST2SQL】01RDB关系型数据库REST初设计 【REST2SQL】02 GO连接Oracle数据库 【REST2SQL】03 GO读取JSON文件 【REST2SQL】04 REST2SQL第一版Oracle版实现 【REST2SQL】05 GO 操作 达梦 数据库 对所有关系数据的操作都只有CRUD,采用Go 的接口interface{}重构代码…...

《NLP入门到精通》栏目导读

一、说明 栏目《NLP入门到精通》本着从简到难得台阶式学习过度。将自然语言处理得知识贯穿过来。本栏目得前导栏目是《深度学习》、《pytorch实践》,因此,读者需要一定得深度学习基础,才能过度到此栏目内容。 二、博客建设理念 本博客基地&am…...

C++学习笔记——类继承

目录 一、一个简单的基类 1.1封装性 1.2继承性 1.3虚函数 1.4多态性 二、基类 2.1一个简单的C基类的示例 2.2 Animal是一个基类。 三、继承 3.1概念 3.2is-a关系 3.3多态公有继承 3.4静态联编和动态联编 3.5访问控制 3.6ABC理念 一、一个简单的基类 C中的基类是一…...

ARCGIS PRO SDK 使用条件管理 Pro UI

ARCGIS PRO UI简单介绍以下&#xff1a; 第一步&#xff1a;在Config.daml中在</AddInfo>标签下加上条件<conditions>标签&#xff08;必须添加的&#xff09; <conditions><!-- 定义条件 &#xff0c;此处定义了两个--Tab 另一个为 group><insert…...

Halcon经典的边缘检测算子Sobel/Laplace/Canny

Halcon经典的边缘检测算子 文章目录 Halcon经典的边缘检测算子1. Sobel算子2. Laplace 算子3. Canny 算子4. 总结 关于边缘检测&#xff0c;有许多经典的算子&#xff0c;各大图形处理库都有各自的边缘检测算子&#xff0c;这里简要介绍几种。 1. Sobel算子 Sobel算子结合了高…...

用单片机设计PLC电路图

自记&#xff1a; 见另一篇文章&#xff0c;MOS驱动差了一个充电电容&#xff0c;栅极电容充电会有问题&#xff1b; 光耦用的直插&#xff0c;但板子用的贴片&#xff0c;此文档仅供参考 基本列出了PCB板情况&#xff0c;基础元器件&#xff0c;部分连接&#xff0c;原理等…...

【设计模式-6】建造者模式的实现与框架中的应用

建造者模式又被成为生成器模式&#xff0c;是一种使用频率比较低&#xff0c;相对复杂的创建型模式&#xff0c;在很多源码框架中可以看到建造者的使用场景&#xff0c;稍后我们会在本文末尾展示几个框架的使用案例。  建造者模式所构造的对象通常是比较复杂而且庞大的&#x…...

PositiveSSL和Sectigo的多域名证书

首先&#xff0c;我们要知道PositiveSSL是Sectigo旗下的子品牌&#xff0c;提供多种类型的SSL数字证书&#xff0c;包括DV基础型的多域名SSL证书。Sectigo的SSL证书产品同样比较丰富&#xff0c;不仅有DV基础型多域名SSL证书&#xff0c;还有OV企业型以及EV增强型的多域名SSL证…...

Docker:docker exec命令简介

介绍 docker exec [OPTIONS] 容器名称 COMMAND [ARG...] OPTIONS说明&#xff1a; -d&#xff0c;以后台方式执行命令&#xff1b; -e&#xff0c;设置环境变量 -i&#xff0c;交互模式 -t&#xff0c;设置TTY -u&#xff0c;用户名或UID&#xff0c;例如myuser:myu…...

【大数据进阶第三阶段之Hive学习笔记】Hive的数据类型与数据操作

目录 1、Hive数据类型 1.1、基本数据类型 1.2、集合数据类型 1.3、类型转化 2、DDL数据定义 2.1、创建数据库 2.2、查询数据库 2.3删除数据库 2.4、创建表 2.4.1、内部表 2.4.2、外部表 2.4.3管理表与外部表的互相转换 2.5、分区表&#xff08;partition&#xff…...

GPT2:Language Models are Unsupervised Multitask Learners

目录 一、背景与动机 二、卖点与创新 三、几个问题 四、具体是如何做的 1、更多、优质的数据&#xff0c;更大的模型 2、大数据量&#xff0c;大模型使得zero-shot成为可能 3、使用prompt做下游任务 五、一些资料 一、背景与动机 基于 Transformer 解码器的 GPT-1 证明…...

微创新与稳定性的权衡

之前做过一个项目&#xff0c;业务最高峰CPU使用率也才50%&#xff0c;是一个IO密集型的应用。里面涉及一些业务编排&#xff0c;所以为了提高CPU使用率&#xff0c;我有两个方案&#xff1a;一个是简单的梳理将任务可并行的采用并行流、额外线程池等方式做并行&#xff1b;另外…...

对回调函数的各种讲解说明

有没有跟我师弟一样的童靴~&#xff0c;学习和使用ROS节点时&#xff0c;对其中的callback函数一直摸不着头脑的&#xff0c;以下这么多回调函数的讲解&#xff0c;挨个看&#xff0c;你总会懂的O.o 回调函数怎么调用,如何定义回调函数&#xff1a; 回调函数怎么调用,如何定义…...

Java多线程:创建多线程的三种方式

在Java中&#xff0c;有三种方式创建多线程&#xff0c;继承类Thread&#xff0c;继承接口Runnable&#xff0c;继承接口Callable。其中Thread和Runnable需要重写方法run&#xff0c;方法run没有返回值&#xff1b;Callable需要重写方法call&#xff0c;方法call可以返回值。 …...

Unity中打印信息的两种方式

不继承MonoBehaviour的普通C#类中打印信息&#xff1a; 使用Debug类的方法&#xff1a; Unity提供了Debug类&#xff0c;其中包含了一些用于打印信息的静态方法。以下是常用的几种方法&#xff1a; Debug.Log(message)&#xff1a;打印普通信息。Debug.LogWarning(message)&a…...

给定n个字符串s[1...n], 求有多少个数对(i, j), 满足i < j 且 s[i] + s[j] == s[j] + s[i]?

题目 思路&#xff1a; 对于字符串a&#xff0c;b, (a.size() < b.size()), 考虑对字符串b满足什么条件&#xff1a; 由1、3可知a是b的前后缀&#xff0c;由2知b有一个周期是3&#xff0c;即a.size()&#xff0c;所以b是用多个a拼接而成的&#xff0c;有因为a是b的前后缀&…...

Linux磁盘空间与文件大小查看命令详解

1. 查看磁盘空间大小 在Linux系统中&#xff0c;有多个命令可以用来查看磁盘空间的使用情况。最常用的命令是df&#xff08;disk free&#xff09;。 df -hdf命令的 -h 选项以人类可读的方式显示磁盘空间&#xff0c;该命令将显示文件系统的使用情况、剩余空间等信息。 2. 查看…...

网络通信过程的一些基础问题

客户端A在和服务器进行TCP/IP通信时&#xff0c;发送和接收数据使用的是同一个端口吗&#xff1f; 这个问题可以这样来思考&#xff1a;在客户端A与服务器B建立连接时&#xff0c;A需要指定一个端口a向服务器发送数据。当服务器接收到A的报文时&#xff0c;从报文头部解析出A的…...

STL——stack容器和queue容器详解

目录 &#x1f4a1;stack &#x1f4a1;基本概念 常用接口 &#x1f4a1;queue &#x1f4a1;基本概念 &#x1f4a1;常用接口 &#x1f4a1;stack &#x1f4a1;基本概念 栈&#xff08;stack&#xff09;&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端…...

django websocket实现聊天室功能

注意事项channel版本 django2.x 需要匹配安装 channels 2 django3.x 需要匹配安装 channels 3 Django3.2.4 channels3.0.3 Django3.2.* channels3.0.2 Django4.2 channles3.0.5 是因为最新版channels默认不带daphne服务器 直接用命令 python manage.py runsever 默认运行的是w…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发&#xff0c;实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构&#xff0c;服务器端使用Java Servlet处理请求&#xff0c;数据库采用MySQL存储信息&#xff0…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...