【REST2SQL】04 REST2SQL第一版Oracle版实现

【REST2SQL】01RDB关系型数据库REST初设计
【REST2SQL】02 GO连接Oracle数据库
【REST2SQL】03 GO读取JSON文件

REST2SQL的第一个版本,只支持Oracle数据库,以后会逐步加入其它数据看的支持。

项目文件组织如下:
在这里插入图片描述

1 REST2SQL为项目主目录

主控main()函数、请求日志函数、请求响应函数、请求参数返回函数在此目录。

1.1 import引用包

import ("encoding/json""fmt""io""log""net/http""rest2sql/config" //配置信息在config.json文件do "rest2sql/dothing""strings""time"
)

1.2 请求信息放在Map里

// 请求信息map
var (req   map[string]interface{} = make(map[string]interface{}) //请求参数count int                    = 0                            //请求计数器
)

1.3 main() 主控函数

// main()
func main() {// 打印配置信息fmt.Println("config:", config.Conf)//响应所有的请求http.HandleFunc("/", handler)// http.HandleFunc("/REST", restHandler)// http.HandleFunc("/SQL", sqlHandler)println("Starting Http Server at", config.Conf.HostPort, "\n")//启动监听和服务//log.Println(http.ListenAndServe(Conf.HostPort, RequestLogger(http.DefaultServeMux)))http.ListenAndServe(config.Conf.HostPort, RequestLogger(http.DefaultServeMux))//log.Println(err)//测试可以用这个//curl -X POST -d "{\"gpdm\":600800}" -H "Content-Type:application/json" http://localhost:8080/rest/blma}

1.4 请求日志函数

// 请求日志
func RequestLogger(targetMux http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {count++start := time.Now()targetMux.ServeHTTP(w, r)log.Printf("(%v)\t%s\t\t%s\t\t%s\t\t%v",count,r.Method,r.RemoteAddr,r.RequestURI,time.Since(start),)})
}

1.5 请求响应函数

// handler
func handler(w http.ResponseWriter, r *http.Request) {// 1请求主机Hostreq["Host"] = r.Host// 2请求路径Pathreq["Path"] = r.URL.Pathpath := strings.Split(r.URL.Path, "/")if len(path) < 3 {w.Write([]byte("400 Bad Request错误请求。请尝试/rest/xxx or /sql/xxx"))return}//fmt.Println(path)// 3 请求类型REST or SQLrors := strings.ToUpper(fmt.Sprint(path[1]))// 支持的请求类型if !(rors == "REST" || rors == "SQL") {w.Write([]byte("400 Bad Request错误请求。请尝试/REST/xxx or /SQL/xxx"))return}req["RESTorSQL"] = rors //请求类型SQL or REST// 4 资源名 ResNamereq["ResName"] = path[2] //资源名,表名ResName// 5请求方法Methodreq["Method"] = r.Method// 6请求头Content-Typereq["Content-Type"] = r.Header.Get("Content-Type")// 7请求数据Datadata, err := io.ReadAll(r.Body)if err != nil {w.Write([]byte(err.Error()))return}defer r.Body.Close()//反序列化if len(data) > 0 {var idata interface{}//fmt.Println("data:", data)err = json.Unmarshal(data, &idata)if err != nil {w.Write([]byte(err.Error()))return}//fmt.Println("idata:", idata)req["Data"] = idata} else {req["Data"] = ""}// 8 请求参数query := r.URL.Query()req["Where"] = query.Get("where")req["OrderBy"] = query.Get("orderby")//返回http请求参数resReturn(w, req)//根据请求参数执行不同的操作do.DoThing(w, req)
}

1.6 请求参数返回函数

// http请求主要参数直接返回
func resReturn(w http.ResponseWriter, req map[string]interface{}) {w.Write([]byte("{\"Request\":"))str, err := json.MarshalIndent(req, "", "   ")if err != nil {w.Write([]byte(err.Error()))}//fmt.Println(str)w.Write(str)w.Write([]byte(","))
}

2 config配置文件读取子目录

2.1 包名改为 config

//全局变量包package configimport ("encoding/json""io/ioutil""log""strings"
)var Conf config //全局变量func init() {Conf = getConfig()
}// 配置结构体
type config struct {DBType     string //数据库类型 :oracle、mysql等ConnString string `json:"connString"`HostPort   string `json:"hostPort"`REST       string `json:"REST"`SQL        string `json:"SQL"`
}// 取配置信息
func getConfig() config {bytes, err := ioutil.ReadFile("config.json")if err != nil {log.Println("读取json文件失败:", err)panic(nil)}conf := &config{}err = json.Unmarshal(bytes, conf)if err != nil {log.Println("json解析失败", err)panic(nil)}//数据库类型为数据库的第一部分end := strings.Index(conf.ConnString, ":/")if end < 0 {log.Println("连接字符串设置有误。")panic(nil)}conf.DBType = conf.ConnString[0:end]// fmt.Println(conf)// fmt.Println("connString:", conf.ConnString)// fmt.Println("hostPort:", conf.HostPort)return *conf
}

2.2 doc.go 文件设置

// config project doc.go/*
config document
*/
package config

3 dboracle子目录,Oracle数据库操作

3.1 包名:dboracle

// gooracle project main.go
package dboracleimport ("database/sql/driver""encoding/json""io""log""rest2sql/config"go_ora "github.com/sijms/go-ora/v2" // 1 go get github.com/sijms/go-ora/v2
)// Oracle连接字符串
//var ConnStr string = "oracle://blma:5217@127.0.0.1:1521/CQYH"var ConnString string = config.Conf.ConnString/*
func main() {var (sqls   string //sql语句result string //sql执行后返回的结果)// select查询数据sqls = "select sysdate from dual"result = selectData(sqls)fmt.Println(result)// delete 删除数据sqls = "delete from atop where p_id = -5"result = deleteData(sqls)fmt.Println(result)// update 更新数据sqls = "update atop set f_dm = '005217' where p_id = -5217"result = updateData(sqls)fmt.Println(result)// insert 插入一行数据sqls = "insert into atop (p_id) values (FLOOR(DBMS_RANDOM.value(0, 100)))"result = insertData(sqls)fmt.Println(result)
}
*/// 连接Oracle数据库
func connDB(connStr string) *go_ora.Connection {//创建连接DB, err := go_ora.NewConnection(connStr)dieOnError("Can't open the driver:", err)//打开连接err = DB.Open()dieOnError("Can't open the connection:", err)return DB
}// delete
func DeleteData(deleteSql string) string {result, _ := execSQL(deleteSql)rows, err := result.RowsAffected()dieOnError("Can't delete", err)ret := map[string]int{"Delete rowsAffected": int(rows),}jsonBytes, err := json.MarshalIndent(ret, "", "   ")dieOnError("map 转 json失败:", err)return string(jsonBytes)
}// update
func UpdateData(updateSql string) string {result, _ := execSQL(updateSql)rows, err := result.RowsAffected()dieOnError("Can't update", err)ret := map[string]int{"Update rowsAffected": int(rows),}jsonBytes, err := json.Marshal(ret)dieOnError("map 转 json失败:", err)return string(jsonBytes)
}// insert
func InsertData(insertSql string) string {result, _ := execSQL(insertSql)rows, err := result.RowsAffected()dieOnError("Can't insert", err)ret := map[string]int{"Insert rowsAffected": int(rows),}jsonBytes, err := json.MarshalIndent(ret, "", "   ")dieOnError("map 转 json失败:", err)return string(jsonBytes)
}// 执行SQL, execute stmt (INSERT, UPDATE, DELETE, DML, PLSQL) and return driver.Result object
func execSQL(sqls string) (result driver.Result, err error) {//连接数据库DB := connDB(ConnString)//延迟关闭连接defer DB.Close()//准备sql语句stmt := go_ora.NewStmt(sqls, DB)//延迟关闭SQLdefer stmt.Close()//执行SQL, execute stmt (INSERT, UPDATE, DELETE, DML, PLSQL) and return driver.Result objectresult, err = stmt.Exec(nil)dieOnError("Can't execSql() ", err)return result, err
}// select查询,结果为json
func SelectData(sqls string) string {//连接数据库DB := connDB(ConnString)//延迟关闭连接defer DB.Close()//准备sql语句stmt := go_ora.NewStmt(sqls, DB)//延迟关闭SQLdefer stmt.Close()rows, err := stmt.Query(nil)dieOnError("Can't query", err)defer rows.Close()//fmt.Println(rows)columns := rows.Columns()//fmt.Println("columns:", columns)values := make([]driver.Value, len(columns))var dataset []map[string]interface{} //元素为map的切片//Header(columns)for {err = rows.Next(values)if err != nil {break}//fmt.Println("values:", values)row1 := record(columns, values)dataset = append(dataset, row1)}if err != io.EOF {dieOnError("Can't Next", err)}//切片转jsonjsonBytes, err := json.MarshalIndent(dataset, "", "   ")dieOnError("slice 转 json失败:", err)//fmt.Println(string(jsonBytes))return string(jsonBytes)
}// 发生错误退出1
func dieOnError(msg string, err error) {if err != nil {log.Println(msg, err)//os.Exit(1)}
}// func Header(columns []string) {// }// 一行记录加入 map
func record(columns []string, values []driver.Value) map[string]interface{} {mc := make(map[string]interface{}) //一行记录信息放入 mapfor i, c := range values {//fmt.Printf("\"%s\":%v,", columns[i], c)mc[columns[i]] = c}//fmt.Println(mc)return mc //返回一行记录的信息map
}/* 查询表的主键方法
select * from user_cons_columns where table_name = 'ATOP'
and constraint_name = (
select constraint_name from user_constraints
where table_name = 'ATOP' and constraint_type = 'P')
order by position
*/// func returnErr(err error) error {
// 	if err != nil {
// 		return err
// 	}
// 	return nil
// }// // 7调用存储过程
// func callStoredProcedure() error {
// 	var (
// 		id  int
// 		msg string = strings.Repeat(" ", 2000) //先赋值内容
// 	)
// 	//执行存储过程,
// 	_, err := db.Exec(`BEGIN ora_test2_pro(:1, :2 ); END;`,
// 		id,
// 		sql.Out{Dest: &msg},
// 	)
// 	if err != nil {
// 		return err
// 	}
// 	//输出结果
// 	fmt.Println(msg)
// 	return nil
// }// // 8.调用函数
// func callFunction() error {
// 	var (
// 		id  int
// 		msg string = strings.Repeat(" ", 2000) //先赋值内容
// 	)
// 	//执行存储过程,
// 	_, err := db.Exec(`BEGIN :1 := ora_test2_func(:2 ); END;`,
// 		sql.Out{Dest: &msg},
// 		id,
// 	)
// 	if err != nil {
// 		return err
// 	}
// 	//输出结果
// 	fmt.Println(msg)
// 	return nil
// }

3.2 doc.go

// gooracle project doc.go/*
gooracle document
*/
package dboracle

4 dothing主要逻辑处理

4.1 包名dothing

// dothing project dothing.go
package dothingimport ("encoding/json""fmt""net/http""rest2sql/config""rest2sql/dboracle""strings"
)// 当前连接的数据库类型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
)// 根据请求类型参数执行不同的操作 
func DoThing(w http.ResponseWriter, req map[string]interface{}) {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)}
}// 根据请求参数执行不同的操作
func doREST(w http.ResponseWriter, req map[string]interface{}) {//w.Write([]byte("\ndoREST()"))//资源名resName := req["ResName"].(string)// 检查是否有效资源if !isRes(resName) {w.Write([]byte("\nerror:无效资源" + resName))return} else {//w.Write([]byte("\nresName:" + resName))}// 查询条件检查var qry map[string]string = make(map[string]string)qry["ResName"] = resNameqry["Where"] = req["Where"].(string)qry["OrderBy"] = req["OrderBy"].(string)// 有效资源,再看请求方法Get、Post、Put、DeletesMethod := strings.ToUpper(req["Method"].(string))switch sMethod {case "GET":getAll(w, qry)case "POST":var iData interface{}iData = req["Data"]postAdd(w, resName, iData)case "PUT":var iData interface{}iData = req["Data"]putUpdate(w, qry, iData)case "DELETE":deleteDel(w, qry)}
}// 根据请求参数执行不同的操作 
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 = dboracle.SelectData(resSQL)case "INSERT":result = dboracle.InsertData(resSQL)case "UPDATE":result = dboracle.UpdateData(resSQL)case "DELETE":result = dboracle.DeleteData(resSQL)default:// 过滤sql ,只能执行 SELECT INSERT UPDATE DELETEresult = "\"只能执行 SELECT INSERT UPDATE DELETE\""}fmt.Println("SQL://", resSQL)w.Write([]byte(result))w.Write([]byte("}"))
}// 检查资源是否存在 /
func isRes(resName string) bool {resname := strings.ToUpper(resName)var selectSQL stringswitch DBType {case "oracle":{//表和视图selectSQL = "select object_name from user_objects where object_type in ('TABLE','VIEW') and object_name = '" + resname + "'"}case "":{}}//执行数据库查询result := dboracle.SelectData(selectSQL)//检查数据库是否有此表if strings.Contains(result, resname) {return true} else {return false}
}// GET all //
func getAll(w http.ResponseWriter, qry map[string]string) {//w.Write([]byte("\nGET ALL"))w.Write([]byte("\"Response\":"))selectSQL := "select * from " + qry["ResName"]if len(qry["Where"]) > 0 {//fmt.Println("where ", qry["Where"])selectSQL += " where " + qry["Where"] + " and rownum < 52"}if len(qry["OrderBy"]) > 0 {//fmt.Println("OrderBy ", qry["OrderBy"])selectSQL += " order by " + qry["OrderBy"]}//执行 sql并返回 json 结果fmt.Println("REST://", selectSQL)result := dboracle.SelectData(selectSQL)w.Write([]byte(result))w.Write([]byte("}"))
}// GET 1
func get1(w http.ResponseWriter) {w.Write([]byte("\nGET ONE"))
}// POST /
func postAdd(w http.ResponseWriter, resName string, iData interface{}) {//curl "http://localhost:5217/rest/atop" --data "{\"p_id\":190,\"s_mc\":\"龙\"}" -X POST//w.Write([]byte("\nPOST ADD"))w.Write([]byte("\"Response\":{\"Data\":"))//fmt.Println("iData:", iData)str, err := json.MarshalIndent(iData, "", "   ")if err != nil {w.Write([]byte(err.Error()))}//fmt.Println("str", str)w.Write(str)w.Write([]byte(",\"Row\":"))var mapData map[string]interface{}err = json.Unmarshal(str, &mapData)if err != nil {w.Write([]byte(err.Error()))}//fmt.Println(mapData)var keys, values stringfor k, v := range mapData {//fmt.Printf("%s %v %T\n", k, v, v)keys += k + ","if typeofVar(v) == "string" {values += "'" + v.(string) + "',"}if typeofVar(v) == "float64" || typeofVar(v) == "int" {values += fmt.Sprintf("%f", v) + ","}}keys = strings.Trim(keys, ",")values = strings.Trim(values, ",")//fmt.Println(keys, values)insertSQL := "insert into " + resName + "(" + keys + ")" + " values( " + values + " )"//执行 insertSQL 并返回 json 结果fmt.Println("REST://:", insertSQL)result := dboracle.InsertData(insertSQL)w.Write([]byte(result))w.Write([]byte("}}"))}// 数据类型断言 
func typeofVar(variable interface{}) string {switch variable.(type) {case string:return "string"case int:return "int"case float32:return "float32"case float64:return "float64"case bool:return "boolean"case []string:return "[]string"default:return "unknown"}
}// PUT
func putUpdate(w http.ResponseWriter, qry map[string]string, iData interface{}) {//w.Write([]byte("\nPUT UPDATE"))w.Write([]byte("\"Response\":{\"Data\":"))str, err := json.MarshalIndent(iData, "", "   ")if err != nil {w.Write([]byte(err.Error()))}//fmt.Println("str", str)w.Write(str)w.Write([]byte(",\"Row\":"))var mapData map[string]interface{}err = json.Unmarshal(str, &mapData)if err != nil {w.Write([]byte(err.Error()))}//fmt.Println(mapData)var sets stringfor k, v := range mapData {//fmt.Printf("%s %v %T\n", k, v, v)sets += k + "="if typeofVar(v) == "string" {sets += "'" + v.(string) + "',"}if typeofVar(v) == "float64" || typeofVar(v) == "int" {sets += fmt.Sprintf("%f", v) + ","}}sets = strings.Trim(sets, ",")updateSQL := "update " + qry["ResName"] + "  set " + sets + " where " + qry["Where"]//执行 insertSQL 并返回 json 结果fmt.Println("REST://", updateSQL)result := dboracle.UpdateData(updateSQL)w.Write([]byte(result))w.Write([]byte("}}"))
}// DELETE
func deleteDel(w http.ResponseWriter, qry map[string]string) {// 查询条件在URL/?后面//w.Write([]byte("\nDELETE DEL"))w.Write([]byte("\"Response\":"))deleteSQL := "delete from " + qry["ResName"]if len(qry["Where"]) > 0 {//fmt.Println("where ", qry["Where"])deleteSQL += " where " + qry["Where"] + " and rownum < 52"}//执行 sql并返回 json 结果fmt.Println("REST://", deleteSQL)result := dboracle.DeleteData(deleteSQL)w.Write([]byte(result))w.Write([]byte("}"))
}

4.2 doc.go

// Dothing project doc.go/*
dothing document
*/
package dothing

5 部分运行效果图

5.1 启动REST2SQL.exe服务

编译后的rest2sql.exe为14M,启动后的窗口为:
在这里插入图片描述

5.2 浏览器操作演示效果

5.2.1 浏览器REST之GET请求

在这里插入图片描述

5.2.2 浏览器SQL之Select

在这里插入图片描述

5.2.3 执行RESR或SQL请求后,服务窗口返回操作日志

在这里插入图片描述

5.3 详细的操作说明参阅

【REST2SQL】01RDB关系型数据库REST初设计

需要运行程序的可以在评论区留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/605248.shtml

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

相关文章

leetcode动态规划问题总结 Python

目录 一、基础理论 二、例题 1. 青蛙跳台阶 2. 解密数字 3. 最长不含重复字符的子字符串 4. 连续子数组的最大和 5. 最长递增子序列 6. 最长回文字符串 7. 机器人路径条数 8. 礼物的最大价值 一、基础理论 动态规划其实是一种空间换时间的基于历史数据的递推算法&…

linux常见操作,and一些练习题加线上练习网站,无须配置linux.持续更新中。。。。

文章目录 cd命令相对路径特殊的路径表达符和cd一起使用pwdmore 查看文件内容支持翻页小技巧clear用户&#xff0c;用户权限 and 用户的切换如何创建用户 ls和通配符的使用利用通配符 *grep 过滤管道符 |如何学习Linux在线练习网站 https://www.lanqiao.cn/courses/1 cd命令 cd…

Basal前端梳理

Basalt前端逻辑梳理 TBB安装参考 https://zhuanlan.zhihu.com/p/480823197 代码注释参考 https://blog.csdn.net/qq_39266065/article/details/106175701#t7 光流追踪参考 https://blog.csdn.net/weixin_41738773/article/details/130282527 VI Odometry KLT tracking 原理 …

第九届中西部外语翻译大赛初赛阶段已经圆满结束

2023年第九届中西部外语翻译大赛&#xff08;以下简称竞赛&#xff09;&#xff0c;于2023年12月30日至31日举行。历届中西部外语翻译大赛均由中西部翻译协会共同体指导发起&#xff0c;各省市译协共建学术指导委员会&#xff0c;获奖证书盖章单位由四川省翻译协会、广西翻译协…

c# 学习笔记 - 集合(List)

文章目录 1.概论1.1 List 特性1.2 .NET API 2. 基本使用2.1 样例 3. 添加类操作3.1 Insert() 4. 删除类操作4.1 Remove()4.2 RemoveAt() 5. 查找类操作6. 排序类操作6.1 Sort(Comparsion<T>) 7. 其他类操作 1.概论 1.1 List 特性 可通过索引访问的强类型列表&#xff0c…

STM32学习笔记二十二:WS2812制作像素游戏屏-飞行射击游戏(12)总结

至此&#xff0c;飞行射击游戏已经基本实现该有的功能&#xff0c;已经比较接近早期的商业游戏了。 如果采用脚本&#xff0c;可以完成关卡游戏&#xff0c;如果不用&#xff0c;也可以做成无限挑战游戏。 我们汇总一下制作的过程&#xff1a; 1、建模UML 2、主循环处理过程…

设计模式篇章(1)——理论基础

设计模式&#xff1a;在软件开发中会面临许多不断重复发生的问题&#xff0c;这些问题可能是代码冗余、反复修改旧代码、重写以前的代码、在旧代码上不断堆新的代码&#xff08;俗称屎山&#xff09;等难以扩展、不好维护的问题。因此1990年有四位大佬&#xff08;GoF组合&…

3的幂00

题目链接 3的幂 题目描述 注意点 无 解答思路 不断除以3直到除数或余数为0为止&#xff0c;判断除完后的数字是否为1 代码 class Solution {public boolean isPowerOfThree(int n) {while (n / 3 ! 0) {if (n % 3 ! 0) {return false;}n n / 3;}return n 1;} }关键点 …

对称加密技术有哪些类型

对称加密是一种加密方式&#xff0c;其加密和解密所使用的密钥是相同的。这种方式的特点是速度快&#xff0c;效率高&#xff0c;适合用于大量数据的加密和解密。对称加密算法有很多种&#xff0c;常见的有AES、DES、3DES等。 对称加密的应用场景非常广泛&#xff0c;下面是一些…

Linux下配置静态ip地址

问题&#xff1a;虚拟机重启后ip地址动态更新&#xff0c;导致连shell十分麻烦 解决&#xff1a; 1. 进入配置文件 vi /etc/sysconfig/network-scripts/ifcfg-ens33 2.1 修改配置 BOOTPROTOstatic ONBOOTyes2.2 新增配置 #ip地址(自定义) IPADDR192.168.149.131 #子网掩码 …

2023年12月 C/C++(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C++编程(1~8级)全部真题・点这里 第1题:移动路线 桌子上有一个m行n列的方格矩阵,将每个方格用坐标表示,行坐标从下到上依次递增,列坐标从左至右依次递增,左下角方格的坐标为(1,1),则右上角方格的坐标为(m,n)。 小明是个调皮的孩子,一天他捉来一只蚂蚁,不小心把蚂蚁…

一款开源的MES系统

随着工业4.0的快速发展&#xff0c;制造执行系统&#xff08;MES&#xff09;成为了智能制造的核心。今天&#xff0c;将为大家推荐一款开源的MES系统——iMES工厂管家。 什么是iMES工厂管家 iMES工厂管家是一款专为中小型制造企业打造的开源MES系统。它具备高度的可定制性和灵…

[论文笔记] Qwen-7B tokenizer

https://github.com/QwenLM/Qwen/blob/main/tokenization_note_zh.md#%E6%99%AE%E9%80%9Atoken https://huggingface.co/Qwen/Qwen-7B 一、Qwen-7B 介绍 Qwen-7B采用UTF-8字节级别的BPE tokenization方式,并依赖tiktoken这一高效的软件包执行分词。 Qwen-7B中有两类token,即…

Selenium教程:级联选择+日期框+弹框,组件的示例练习

1.Cascader级联选择&#xff0c;通常指的是在多个层级或类别中进行选择&#xff0c;每个层级或类别的选择依赖于前一个层级或类别的选择结果。常用于省市区、公司级层、事务分类等。 网页元素结构 实现代码 # Author : 小红牛 # 微信公众号&#xff1a;WdPython from time i…

ROS-urdf集成gazebo

文章目录 一、URDF与Gazebo基本集成流程二、URDF集成Gazebo相关设置三、URDF集成Gazebo实操四、Gazebo仿真环境搭建 一、URDF与Gazebo基本集成流程 1.创建功能包 创建新功能包&#xff0c;导入依赖包: urdf、xacro、gazebo_ros、gazebo_ros_control、gazebo_plugins 2.编写URD…

HarmonyOS状态管理概述

状态管理概述 在前文的描述中&#xff0c;我们构建的页面多为静态界面。如果希望构建一个动态的、有交互的界面&#xff0c;就需要引入“状态”的概念。 图1 效果图 上面的示例中&#xff0c;用户与应用程序的交互触发了文本状态变更&#xff0c;状态变更引起了UI渲染&…

C#实现个人账本管理系统

git地址&#xff1a;https://gitee.com/myshort-term/personal-ledger-management-system 1.系统简介 LedgerManagementSystem是一个小型的个人账本管理系统&#xff0c;可对收支项目进行增加、删除、修改、查询以及导入和导出。可对每日的各类收支项目进行汇总并查看和修改收…

STM32 基础知识(探索者开发板)--146讲 IIC

IIC特点&#xff1a; 同步串行半双工通信总线 IIC有一个弱上拉电阻&#xff0c;在主机和从机都没有传输数据下拉时&#xff0c;总线会自动上拉 SCL在低电平期间&#xff0c;改变SDA的值来上传数据&#xff0c;方便SCL电平上升时进行数据读取 SCL在高电平期间&#xff0c;不能…

【蓝桥杯软件赛 零基础备赛20周】第7周——二叉树

文章目录 1 二叉树概念2 二叉树的存储和编码2.1 二叉树的存储方法2.2 二叉树存储的编码实现2.3 二叉树的极简存储方法 3 例题4 习题 前面介绍的数据结构数组、队列、栈&#xff0c;都是线性的&#xff0c;它们存储数据的方式是把相同类型的数据按顺序一个接一个串在一起。简单的…