文章目录

  • XORM
    • 1 概念
      • 1.1 ORM
      • 1.2 Mysql
      • 1.3 Mysql命令大全
    • 2 XORM 的基本使用
      • 2.1 下载xorm
      • 2.2 安装驱动
      • 2.3 xorm引擎
        • 2.3.1 创建引擎
        • 2.3.2 打印日志
        • 2.3.3 连接池
        • 2.3.4 名称映射规则
        • 2.3.5 数据类型对应规则
        • 2.3.6 xorm对数据类型的定义
      • 2.4 创建引擎组
      • 2.5 基本操作
    • 3 XORM数据库操作
      • 3.1 表操作
      • 3.2 增
      • 3.3 删除
      • 3.4 查改

XORM

1 概念

1.1 ORM

ORM 是 Object Relational Mapping 的缩写,译为“对象关系映射”框架。

ORM 框架是一种数据持久化技术,是一种为了解决面向对象与关系型数据库中数据类型不匹配的技术,它通过描述对象与数据库表之间的映射关系,自动将应用程序中的对象持久化到关系型数据库的表中。

Gorm和Xorm都是Go语言的ORM库,其他相关的数据库框架库参考:https://my.oschina.net/u/168737/blog/1531834

执行一下两条命令  安装mysql引擎 以及 安装xorm库
go get -u github.com/go-sql-driver/mysql
go get github.com/go-xorm/xorm

1.2 Mysql

下载安装:https://cloud.tencent.com/developer/article/1636375

启动/停止服务:net start/stop mysql

登录:mysql -u root -p密码

列出数据库:show databases,退出数据库:quit

1.3 Mysql命令大全

Mysql常用命令大全:https://www.cnblogs.com/bluecobra/archive/2012/01/11/2318922.html

CREATE DATABASE IF NOT EXISTS golang;
USE golang;
DROP TABLE IF EXISTS user;CREATE TABLE user (id INT NOT NULL AUTO_INCREMENT,name VARCHAR(30) NOT NULL,PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO classes(id, name) VALUES (1, 'sommer');
INSERT INTO classes(id, name) VALUES (2, 'Jack');
INSERT INTO classes(id, name) VALUES (3, 'hapu');
INSERT INTO classes(id, name) VALUES (4, 'Dim');select * from user;

2 XORM 的基本使用

参考资源:

  • xorm操作

  • 使用go xorm来操作mysql的方法实例

  • xorm使用

  • xorm官方文档

  • Go语言的ORM库xorm实战篇

  • xorm基础

2.1 下载xorm

go get github.com/go-xorm/xorm
go get github.com/go-xorm/cmd

2.2 安装驱动

go get github.com/go-sql-driver/mysql  //Mysql
go get github.com/ziutek/mymysql/godrv  //MyMysql
go get github.com/lib/pq  //Postgres
go get github.com/mattn/go-sqlite3  //SQLite
go get github.com/denisenkom/go-mssqldb  //MSSQL

2.3 xorm引擎

Engine 引擎用于对单个数据库进行操作

Engine Group 引擎用于对读写分离的数据库或者负载均衡的数据库进行操作

2.3.1 创建引擎

import (_ "github.com/go-sql-driver/mysql""xorm.io/xorm"
)var engine *xorm.Enginefunc main() {var err error/**配置连接数据库信息格式:用户名:密码@(数据库服务器地址:端口)/数据库名称?charset=字符集*/engine, err = xorm.NewEngine("mysql", "root:root@(127.0.0.1)/golang?charset=utf8")engine.Ping() //连接测试defer engine.Close() //延迟关闭数据库
}

2.3.2 打印日志

engine.ShowSQL(true)//在控制台打印出生成的SQL语句;
engine.Logger().SetLevel(core.LOG_DEBUG)//在控制台打印调试及以上的信息;
--------------------------------------------------------------------
// 将日志保存为文件
f, err := os.Create("sql.log")
if err != nil {println(err.Error())return
}
engine.SetLogger(xorm.NewSimpleLogger(f))

2.3.3 连接池

如果需要设置连接池的空闲数大小,使用 engine.SetMaxIdleConns() 来实现。
如果需要设置最大打开连接数,则使用 engine.SetMaxOpenConns() 来实现。
如果需要设置连接的最大生存时间,则使用 engine.SetConnMaxLifetime() 来实现。

2.3.4 名称映射规则

xorm 内置了三种 Mapper 实现:names.SnakeMappernames.SameMappernames.GonicMapper

SnakeMapper 支持struct为驼峰式命名,表结构为下划线命名之间的转换,这个是默认的Maper; // user_table——UserTable,user_id——UserId
SameMapper 支持结构体名称和对应的表名称以及结构体field名称与对应的表字段名称相同的命名;
GonicMapper 和SnakeMapper很类似,但是对于特定词支持更好,比如ID会翻译成id而不是i_d。
engine.SetMapper(names.GonicMapper{})
// 给表加前缀
tbMapper := names.NewPrefixMapper(names.SnakeMapper{}, "prefix_")
engine.SetTableMapper(tbMapper)
// 加后缀
names.NewSuffixMapper(names.SnakeMapper{}, "suffix")

表名的优先级顺序如下:

engine.Table() 指定的临时表名优先级最高
TableName() string 其次
Mapper 自动映射的表名优先级最后

字段名的优先级顺序如下:

结构体tag指定的字段名优先级较高  xorm:"'column_name'"
Mapper 自动映射的表名优先级较低
type User struct {Id   int    //`xorm:"INT 'id'"`Name string //`xorm:"VARCHAR(30) 'name'"`
}

2.3.5 数据类型对应规则

Go中的Type类型 XORM映射的Type类型
implemented Conversion Text
int, int8, int16, int32, uint, uint8, uint16, uint32 Int
int64, uint64 BigInt
float32 Float
float64 Double
complex64, complex128 Varchar(64)
[]uint8 Blob
array, slice, map except []uint8 Text
bool Bool
string Varchar(255)
time.Time DateTime
cascade struct BigInt
struct Text
Others Text

2.3.6 xorm对数据类型的定义

name 当前field对应的字段的名称,可选,如不写,则自动根据field名字和转换规则命名
pk 是否是Primary Key
autoincr 是否是自增
[not ]null 或 notnull 是否可以为空
unique 是否是唯一
index 是否是索引
extends 应用于一个匿名成员结构体或者非匿名成员结构体之上
- Field将不进行字段映射
-> Field将只写入到数据库而不从数据库读取
<- Field将只从数据库读取,而不写入到数据库
created Field将在Insert时自动赋值为当前时间
updated Field将在Insert或Update时自动赋值为当前时间
deleted Field将在Delete时设置为当前时间,并且当前记录不删除
version Field将会在insert时默认为1,每次更新自动加1
default 0或default(0) 设置默认值,紧跟的内容如果是Varchar等需要加上单引号
json 表示内容将先转成Json格式,然后存储到数据库中,数据库中的字段类型可以为Text或者二进制
comment 设置字段的注释(当前仅支持mysql)
//用户表
type UserTable struct {UserId   int64 `xorm:"pk autoincr"`  //用户id  主键UserName string `xorm:"varchar(32)"` //用户名称UserAge  int64 `xorm:"default 1"`    //用户年龄UserSex  int64 `xorm:"default 0"`    //用户性别
}
//学生表
type StudentTable struct {Id          int64  `xorm:"pk autoincr"` //主键 自增StudentName string `xorm:"varchar(24)"` //StudentAge  int    `xorm:"int default 0"`StudentSex  int    `xorm:"index"` //sex为索引
}//人类表
type PersonTable struct {Id         int64     `xorm:"pk autoincr"`   //主键自增PersonName string    `xorm:"varchar(24)"`   //可变字符PersonAge  int       `xorm:"int default 0"` //默认值PersonSex  int       `xorm:"notnull"`       //不能为空City       CityTable `xorm:"-"`             //不映射该字段 那就不会在数据库里面创建该字段
}

2.4 创建引擎组

在xorm中,通过创建引擎组EngineGroup来实现对从数据库(Master/Slave)读写分离的支持。在创建引擎章节中,我们已经介绍过了,在xorm里面,可以同时存在多个Orm引擎,一个Orm引擎称为Engine,一个Engine一般只对应一个数据库,而EngineGroup一般则对应一组数据库。EngineGroup通过调用xorm.NewEngineGroup生成,如:

import (_ "github.com/lib/pq""github.com/xormplus/xorm"
)var eg *xorm.EngineGroupfunc main() {conns := []string{"postgres://postgres:root@localhost:5432/test?sslmode=disable;","postgres://postgres:root@localhost:5432/test1?sslmode=disable;","postgres://postgres:root@localhost:5432/test2?sslmode=disable",}var err erroreg, err = xorm.NewEngineGroup("postgres", conns)
}

or

import (_ "github.com/lib/pq""github.com/xormplus/xorm"
)var eg *xorm.EngineGroupfunc main() {var err errormaster, err := xorm.NewEngine("postgres", "postgres://postgres:root@localhost:5432/test?sslmode=disable")if err != nil {return}slave1, err := xorm.NewEngine("postgres", "postgres://postgres:root@localhost:5432/test1?sslmode=disable")if err != nil {return}slave2, err := xorm.NewEngine("postgres", "postgres://postgres:root@localhost:5432/test2?sslmode=disable")if err != nil {return}slaves := []*xorm.Engine{slave1, slave2}eg, err = xorm.NewEngineGroup(master, slaves)
}

创建完成EngineGroup之后,并没有立即连接数据库,此时可以通过eg.Ping()来进行数据库的连接测试是否可以连接到数据库,该方法会依次调用引擎组中每个Engine的Ping方法。另外对于某些数据库有连接超时设置的,可以通过起一个定期Ping的Go程来保持连接鲜活。EngineGroup可以通过eg.Close()来手动关闭,但是一般情况下可以不用关闭,在程序退出时会自动关闭。

  • NewEngineGroup方法
    func NewEngineGroup(args1 interface{}, args2 interface{}, policies ...GroupPolicy) (*EngineGroup, error)
    前两个参数的使用示例如上,有两种模式。
    模式一:通过给定DriverName,DataSourceName来创建引擎组,每个引擎使用相同的Driver。每个引擎的DataSourceNames是[]string类型,第一个元素是Master的DataSourceName,之后的元素是Slave的DataSourceName。
    模式一:通过给定*xorm.Engine[]*xorm.Engine来创建引擎组,每个引擎可以使用不同的Driver。第一个参数为Master的*xorm.Engine,第二个参数为Slave的[]*xorm.Engine

NewEngineGroup方法,第三个参数为policies,为Slave给定负载策略,该参数将在负载策略章节详细介绍,如示例中未指定,则默认为轮询负载策略。

  • Master方法
    func (eg *EngineGroup) Master() *Engine
    返回Master数据库引擎
  • Slave方法
    func (eg *EngineGroup) Slave() *Engine
    依据给定的负载策略返回一个Slave数据库引擎
  • Slaves方法
    func (eg *EngineGroup) Slaves() []*Engine
    返回所以Slave数据库引擎
  • GetSlave方法
    func (eg *EngineGroup) GetSlave(i int) *Engine
    依据一组Slave数据库引擎[]*xorm.Engine下标返回指定Slave数据库引擎。通过给定DriverName,DataSourceName来创建引擎组,则DataSourceName的第二个元素的数据库为下标0的Slave数据库引擎。
  • SetPolicy方法
    func (eg *EngineGroup) SetPolicy(policy GroupPolicy) *EngineGroup
    设置引擎组负载策略

2.5 基本操作

package mainimport ("fmt"_ "github.com/go-sql-driver/mysql" //千万不要忘记导入"github.com/go-xorm/xorm""xorm.io/core"
)var engine *xorm.Engine
func main() {//1.创建数据库引擎对象var err error engine, err = xorm.NewEngine("mysql", "root:root@(127.0.0.1:3306)/golang?charset=utf8mb4")engine.Ping() //连接测试,连接正常输出 PING DATABASE mysqlif err != nil {panic(err.Error())}// 2.延迟关闭数据库引擎defer engine.Close()//  3.数据库引擎设置engine.ShowSQL(true)                     //将sql语句显示在控制台中engine.Logger().SetLevel(core.LOG_DEBUG) // 设置日志级别,在控制台打印调试及以上的信息// 查询表中所有的数据session := engine.Table("user")count, err := session.Count()if err != nil {panic(err.Error())}fmt.Println(count)// 使用原生sql语句进行查询result, err := engine.Query("select * from user")if err != nil {panic(err.Error())}for key, value := range result {fmt.Println(key, value)}
}

测试

package main
import ("fmt""github.com/go-xorm/xorm""github.com/go-xorm/core"_ "github.com/go-sql-driver/mysql"
)
// 对应数据库的tablename必须为student
// 执行mysql时,对应的字段为xxx,yyy,zzz; 也可以省掉,默认的mysql字段为id,username,address
type Student struct {Id    int    `xorm:"INT(11) 'xxx'"`Username string  `xorm:"VARCHAR(64) 'yyy'"`Address string  `xorm:"VARCHAR(256) 'zzz'"`
}
func main() {engine, err := xorm.NewEngine("mysql", "root@/taoge?charset=utf8") // dbname是taogeif err != nil{fmt.Println(err)return}// 如下Ping可以不要// if err := engine.Ping(); err != nil{//   fmt.Println(err)//   return// }//engine.ShowSQL(true) // 显示SQL的执行, 便于调试分析engine.SetTableMapper(core.SnakeMapper{})st1 := new(Student)st1.Username = "taoge"st1.Address = "China"affected, err := engine.Insert(st1)fmt.Println(affected)st2 := new(Student)result,err := engine.Where("xxx=?", 1).Get(st2)fmt.Println(result)fmt.Println(st2.Username)fmt.Println(st2.Address)
}

创建数据库:

CREATE TABLE `student` (`xxx` int(11) NOT NULL AUTO_INCREMENT,`yyy` varchar(64) NOT NULL,`zzz` varchar(256) NOT NULL ,PRIMARY KEY (`xxx`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

3 XORM数据库操作

3.1 表操作

engine.DBMetas() // 获取数据库中所有的表,字段,索引的信息。
engine.CreateTables() //创建表,参数为一个或多个空的对应Struct的指针。
engine.IsTableEmpty() //判断表是否为空,参数和 CreateTables 相同
engine.IsTableExist() //判断表是否存在
engine.DropTables() //删除表 参数为一个或多个空的对应Struct的指针或者表的名字。如果为string传入,则只删除对应的表,如果传入的为Struct,则删除表的同时还会删除对应的索引。
engine.CreateIndexes //根据struct中的tag来创建索引
engine.CreateUniques //根据struct中的tag来创建唯一索引err := engine.Sync(new(User), new(Group)) //同步数据库结构
err := engine.Sync2(new(User), new(Group))// 导出数据库的结构和数据
engine.DumpAll(w io.Writer)
engine.DumpAllToFile(fpath string)
// 执行SQL脚本
engine.Import(r io.Reader)
engine.ImportFile(fpath string)
//判断一个表当中内容是否为空
personEmpty, err := engine.IsTableEmpty(new(PersonTable))
if err != nil {panic(err.Error())
}
if personEmpty {fmt.Println("人员表是空的!")
}else{fmt.Println("人员表不为空!")
}//判断表结构是否存在
studentExist, err := engine.IsTableExist(new(StudentTable))
if err != nil {panic(err.Error())
}
if studentExist {fmt.Println("学生表存在!")
}else{fmt.Println("学生表不存在!")
}

3.2 增

// 插入单条记录
user1 := new(User)
user1.Id = 6
user1.Name = "Dim"
affected, err := engine.Insert(user1)
fmt.Println("插入单条数据:", affected, err)// 插入多条数据
users := make([]*User, 3)
users[0] = new(User)
users[0].Id = 11
users[0].Name = "name11"
users[1] = new(User)
users[1].Id = 12
users[1].Name = "name12"
users[2] = new(User)
users[2].Id = 13
users[2].Name = "name13"
affects, errs := engine.Insert(&users)
fmt.Println("插入多条数据:", affects, errs)

3.3 删除

删除数据Delete方法,参数为struct的指针并且成为查询条件。

软删除Deleted,不真正的删除数据,而是标记一个删除时间。

// 删除
affdel, errdel := engine.Delete(user)
fmt.Println(affdel, errdel)

3.4 查改

func main(){engine, err := xorm.NewEngine("mysql", "root:root@/elmcms?charset=utf8")if err != nil {panic(err.Error())}//条件查询//1.ID查询//首先你得要有一个结构体来存放查询出来的数据var person PersonTable//select * from person_table where id = 1  并且get只获取到一条记录哈!engine.Id(1).Get(&person)fmt.Println(person)fmt.Println("----------------------------")//2.where多条件查询//首先你得要有一个结构体来存放查询出来的数据var person1 PersonTable//select * from person_table where person_age = 26 and person_sex = 2engine.Where(" person_age = ? and person_sex = ?", 30, 1).Get(&person1)fmt.Println(person1)fmt.Println("----------------------------")//3.and条件查询//首先你得要有一个结构体来存放查询出来的数据var persons []PersonTable//select * from person_table where person_age = 26 and person_sex = 2   find 会返回一条或者多条记录err = engine.Where(" person_age = ?", 30).And("person_sex = ?", 1).Find(&persons)if err != nil {panic(err.Error())}fmt.Println(persons)fmt.Println("----------------------------")//4.or条件查询var personArr []PersonTable//select * from person_table where person_age = 26 or person_sex = 1err = engine.Where(" person_age = ?", 26).Or("person_sex = ?", 1).Find(&personArr)if err != nil {panic(err.Error())}fmt.Println(personArr)fmt.Println("----------------------------")//5.原生sql语句查询 支持likevar personNative []PersonTable//执行原生的sql语句err = engine.SQL(" select * from person_table where person_name like '%i%' ").Find(&personNative)if err != nil {panic(err.Error())}fmt.Println(personNative)fmt.Println("----------------------------")//6.排序条件查询var personOrderBy []PersonTable//select * from person_table orderby person_age  升序排列//engine.OrderBy(" person_age ").Find(&personsOrderBy)  不写desc默认就是asc升序排序err = engine.OrderBy(" person_age desc ").Find(&personOrderBy)if err != nil {panic(err.Error())}fmt.Println(personOrderBy)fmt.Println("----------------------------111")//7.查询特定字段var personCols []PersonTableengine.Cols("person_name", "person_age").Find(&personCols)for _,col := range personCols {fmt.Println(col)}//fmt.Println(personCols)fmt.Println("----------------------------")//增加记录//插入你得先有数据  弄到结构体里面去personInsert := PersonTable{PersonName: "wahaha",PersonAge:  40,PersonSex:  10,}rowNum, err := engine.Insert(&personInsert)fmt.Println(rowNum)  //rowNum表示受影响的行数fmt.Println("----------------------------")//删除操作personDelete := PersonTable{}//根据id删除rowNum1, err := engine.Id(4).Delete(&personDelete)fmt.Println(rowNum1)  //rowNum1也是表示受影响的行数fmt.Println("----------------------------")//更新操作personUpdate := PersonTable{PersonName: "胡绍良",PersonAge:  30,PersonSex:  1,}rowNum2, err := engine.Id(1).Update(&personUpdate)fmt.Println(rowNum2) // rowNum2也是表示受影响的行数fmt.Println("----------------------------")//统计功能countcount, err := engine.Count(new(PersonTable))fmt.Println("persontable表总记录数:",count)//事务操作personsArray := []PersonTable{PersonTable{PersonName: "Jack",PersonAge:  28,PersonSex:  1,},PersonTable{PersonName: "Mali",PersonAge:  28,PersonSex:  1,},PersonTable{PersonName: "Ruby",PersonAge:  28,PersonSex:  1,},}session := engine.NewSession()session.Begin()for i:=0;i<len(personsArray);i++{_, err = session.Insert(personsArray[i])if err != nil {session.Rollback()session.Close()}}err = session.Commit()session.Close()if err != nil {panic(err.Error())}}//人员结构表
type PersonTable struct {Id                 int64  `xorm:"pk autoincr"`PersonName      string `xorm:"varchar(24)"`PersonAge       int    `xorm:"int default 0"`PersonSex       int     `xorm:"notnull"`City            CityTable `xorm:"-"`
}type CityTable struct {CityName      stringCityLongitude float32CityLatitude  float32}

Go语言数据库框架——xorm相关推荐

  1. Gorm—Go语言数据库框架

    文章目录 一.GORM简介 1.什么是Gorm? 2.为什么选择GORM? 3.如何使用GORM? 4.约定大于配置大于编码 GORM 默认使用ID作为表的主键 GORM 默认使用结构体名的 snak ...

  2. 在线车辆推荐网 Python语言+Django框架+Mysql数据库 基于用户、物品的协同过滤推荐算法 开发在线汽车推荐系统 二手车网站推荐系统 分布式大数据、机器学习、人工智能开发

    在线车辆推荐网 Python语言+Django框架+Mysql数据库 基于用户.物品的协同过滤推荐算法 开发在线汽车推荐系统 二手车网站推荐系统 分布式大数据.机器学习.人工智能开发 CarRecom ...

  3. Java-ORM数据库框架CDM介绍

    cdm-core Cdm Framework 一个使用简单,零配置,容错率高,效率的Java™ ORM 数据库框架 ✨ 特性 使用简单 没有依赖,一行代码即可初始化连接,调用接口像使用脚本语言一样畅爽 ...

  4. Go实战--也许最快的Go语言Web框架kataras/iris初识三(Redis、leveldb、BoltDB)

    生命不止,继续 go go go !!! 之前介绍了iris框架,介绍了如何使用basic认证.Markdown.YAML.Json等:  Go实战–也许最快的Go语言Web框架kataras/iri ...

  5. 干货分享:六个知名的Go语言web框架

    框架一直是敏捷开发中的利器,能让开发者很快的上手并做出应用,甚至有的时候,脱离了框架,一些开发者都不会写程序了.成长总不会一蹴而就,从写出程序获取成就感,再到精通框架,快速构造应用,当这些方面都得心应 ...

  6. 安卓进阶系列-06数据库框架(LitePal)的使用

    LitePal的使用 背景 安卓内置了一个轻量数据库SQLite,然而很多时候使用SQLite是不方便的,更多开发者习惯服务器部署MySQL之类的数据库,而且复杂的SQL语言对于很多没有系统学习过数据 ...

  7. Go 语言 Gin 框架实战项目笔记

    Go 语言 Gin 框架实战 后端 Goland 操作 创建项目 运行项目 数据库操作 jwt.Response 配置管理 获取请求参数 数据验证 使用 UUID 前端 环境搭建 创建项目 ESLin ...

  8. go web框架_干货分享:六个知名的Go语言web框架

    框架一直是敏捷开发中的利器,能让开发者很快的上手并做出应用,甚至有的时候,脱离了框架,一些开发者都不会写程序了.成长总不会一蹴而就,从写出程序获取成就感,再到精通框架,快速构造应用,当这些方面都得心应 ...

  9. 微信 WCDB 正式开源——高效易用的移动数据库框架

    前沿介绍 腾讯开源微信数据库框架WCDB,他是一个高效.完整.易用的移动数据库框架,基于SQLCipher,支持iOS, macOS和Android. 便捷地定义表.索引.约束,并进行增删改查操作 项 ...

最新文章

  1. 精通python-精通Python设计模式
  2. Linux 使用ntpdate自动对时
  3. 【深度学习】Panoptic FCN:真正End-to-End的全景分割
  4. cygwin This indicates that the /etc/passwd (and possibly /etc/group) files should be rebuilt 问题解决办法
  5. axure html显示效果,Axure RP基础篇: 实现循环显示效果的两种方法
  6. redis中zset底层实现原理
  7. markdown备忘
  8. 1.7 什么时候该改变开发_测试集和指标
  9. 智能玩具 数据采集 首页展示 注册 登录 自动登录 二维码图片
  10. 罗永浩回应做主播赚钱还债;360 否认裁员;Kubernetes 1.18 版本发布| 极客头条
  11. python微博爬虫实战_Python爬虫实战演练:爬取微博大V的评论数据
  12. 关于Linux下使用Windows应用程序的尝试总结
  13. C# 程序中使用 SQLite 数据库
  14. 国赛助力:第三类边界条件热传导方程及基于三对角矩阵的数值计算MATLAB实现(2020A)
  15. Apple苹果EDI案例
  16. 原生js或uni-app生成二维码(可修改二维码样式,带logo)
  17. DMIS 5.3 编程基本要义
  18. Mac 更新系统后无法正常启动
  19. 我跑了香港六家银行,把境外开户的事整明白了
  20. Python笔记 | 数据筛选

热门文章

  1. java 集成grizzly_使用Grizzly的嵌入式Java服务器:如何启用http2
  2. 黑客如何赚钱?黑客是怎么赚钱的
  3. 3度带6度带换算以及带号计算
  4. centos7下安装Acunetix wvs 12.x详细过程
  5. 期刊论文格式要求笔记
  6. 教育已成中国人不折不扣的国耻
  7. 2022年在uniapp中引入vant Weapp
  8. springboot+maven/gradle整合swag及生成静态文档
  9. mysql checksum_mysql8 参考手册--CHECKSUM TABLE语句
  10. 大学计算机作业实验六PPT,实验六MSI计数器应用.ppt