xorm实战——结构体映射到实现数据库操作(包含导出数据库脚本)

news2024/11/16 18:04:09

下载引入框架

go语言中要使用orm框架需要先下载框架,并引入:

// 安装工具包
go get xorm.io/xorm

//安装数据库驱动(这里是mysql)

go get -u github.com/go-sql-driver/mysql
//引入框架

import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

数据库构建
数据库构建,xorm也提供了数据表的构建功能,直接将结构体以构建为数据的表,专业事还是交给专业的人来做,有navicat这种构建和管理工具更专业。

构建如下数据库:

在这里插入图片描述

创建数据库引擎

创建引擎,所有数据库操作都需要基于数据库引擎,xorm提供两种数据库引擎,单例引擎和引擎组(一般直接命名为(Engine和Engine Group)。一个 Engine 引擎用于对单个数据库进行操作,一个 Engine Group 引擎用于对读写分离的数据库或者负载均衡的数据库进行操作。Engine 引擎和 EngineGroup 引擎的API基本相同,所有适用于 Engine 的API基本上都适用于 EngineGroup。

数据库引擎是单例模式,因此只能用指针类型。

var Engine *xorm.Engine

一般情况下引擎在包初始化函数init()中初始化

func init(){
	var err error
	Engine, err = xorm.NewEngine("mysql", "root:123@/test?charset=utf8")
	// err的错误处理	
}

可以通过Engine.Ping()来进行数据库的连接测试是否可以连接到数据库。通过Engine可以完成数据的CURD操作。

日志组件

xorm提供了日志组件来显示SQL,默认的显示级别为INFO。日志既可以通过运行的控制台来打印也可以保存到日志文件中。

Engine.ShowSQL(true)会在控制台打印出生成的SQL语句;

engine.Logger().SetLevel(core.LOG_DEBUG)更改控制台日志打印级别(这里是debug级别)

也可以将SQL信息保存到日志文件

f, err := os.Create("sql.log")
if err != nil {
    println(err.Error())
    return
}
Engine.SetLogger(xorm.NewSimpleLogger(f))

数据库连接池

Engine内部支持连接池接口和对应的函数。

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

数据库映射

创建完数据库引擎后,在使用时查询的数据需要赋值给go的数据结构(一般为结构体),xorm框架提供了多种映射方式。基于约定大于配置的原则。

  • SnakeMapper 支持struct为驼峰式命名,表结构为下划线命名之间的转换也是默认方式。
//设置其他映射方式
Engine.SetMapper(core.SameMapper{})
type StuTests struct {
	StuId   int
	StuName string
	StuAge  int
	StuSex  string
}

//拆入数据
stu0 := StuTests{
	0,
	"xiaoxu1",
	18,
	"man",
}
//插入
Engine.Insert(&stu0)

//查询
var stu1 StuTests
Engine.Get(&stu1)

type Accounts struct {
	Id       int
	User     string
	Password string
	Role     string
}

var act Accounts
Engine.Table("accounts").Where("id = ?", 1).Cols("user").Get(&act)
fmt.Println(act)
Engine.Get(&act)
fmt.Println(act)

在这里插入图片描述

数据库表和字段如下

在这里插入图片描述

如上图所示,使用该方式首字母大写的驼峰命名还是以单个单词的方式表名和字段名都可以成功映射。

还有其他映射方式访问非常优秀的学习网站xorm

  • tag标签映射补充映射规则

在go的序列化一章,tag标签能够序列化json字符串,在xorm框架中也延用了这一特性。

type StuTests struct {
	StuId   int    `xorm:"stu_id"`
	StuName string `xorm:"stu_name"`
	StuAge  int    `xorm:"stu_age"`
	StuSex  string `xorm:"stu_sex"`
}

tag标签一般用来做上一个映射方式的补充,应用于一些特殊的命名方式,另外如果表名命名方式也特殊的话可以使用engine.Table() 指定的临时表名。

导出数据库脚本

如果需要在web端通过按钮导出数据库脚本,实际上是通过Go语言执行数据库脚本,将sql文件导出到本地。

engine.DumpAll(w io.Writer)方法返回数据库表的结构和数据的字节数组。

engine.DumpAllToFile(fpath string)方法将数据库表的结构和数据写入到sql文件。

Engine.DumpAllToFile("./demo.sql")

执行后在文件夹下生成sql文件:
在这里插入图片描述

同样的也提供了导入的支持

engine.Import(r io.Reader)

engine.ImportFile(fpath string)

时间字段

在插入数据时需要时间可以在数据中设置生成当前时间,一般情况下编程语言生成的时间类型都是很全面的,在实际使用中一般只需要部分数据YYYY-MM-DD hh:mm:ss类型。

Datetime:时间日期,格式是YYYY-mm-dd HH:ii:ss,表示的范围是从1000到9999年,有0值:0000-00-00 00:00:00。
Date:日期,就是datetime中的date部分。
Time:时间段,指定的某个区间之间,-时间到+时间。
Timestamp:时间戳,只是从1970年开始的YYYY-mm-dd HH:ii:ss 格式与datetime完全一致。
Year:年份,两种格式, year(2)和year(4):1901到2156

因此程序插入数据语言时都需要转化,xorm提供了自动转化的组件。

type StuTests struct {
	StuId      int       `xorm:"stu_id"`
	StuName    string    `xorm:"stu_name"`
	StuAge     int       `xorm:"stu_age"`
	StuSex     string    `xorm:"stu_sex"`
	CreateTime time.Time `xorm:"created"`
}

在xorm标记中使用created标记,对应的字段可以为time.Time或者自定义的time.Time或者int,int64等int类型。

stu0 := StuTests{
	0,
	"xiaoxu1-1",
	18,
	"man",
	time.Now(),
}
Engine.Insert(&stu0)

然后正常插入即可,数据库的大的对应字段设置为datetimeUpdated用于更新时自动同步当前时间。

数据库操作

xorm提供了众多方法,实现数据库操作,但是小编个人还是比较喜欢直接写sql语句的方式,因此接下来只介绍编写sql语句的方法。(习惯直接用框架方法的可以跳过了 😃)

  • Query 最原始的也支持SQL语句查询,返回的结果类型为 []map[string][]byte。QueryString 返回 []map[string]string, QueryInterface 返回 []map[string]interface{}

第一个方法返回字节数组,第二个方法返回struct的json字符串的形式,第三个方法返回空接口。一般使用第三个方法返回map数组[]map[string]interface{}

result, _ := Engine.QueryInterface("select * from stu_tests")
for index, item := range result {
	fmt.Println(index)
	fmt.Println(item)
}

在这里插入图片描述

Engine.Query系列只用于执行DQL。

  • Engine.SQL()返回值是一个Engine,用于sql和引擎方法混用。
var stu2 []StuTests
Engine.SQL("select * from stu_tests").Find(&stu2)
fmt.Println(stu2)

在这里插入图片描述
该方法返回的基本元素为结构体类型,因此查询多条数据需要返回结构体数组。

一般结合条件查询使用。

  • Engine.Exec()用于执行DML,且支持表达式,?作为占位符
//Engine.Exec()
sql := "update stu_tests set stu_name =? where stu_id =? "
result, err := Engine.Exec(sql, "hebei", 5)
if err != nil {
	fmt.Println("demo4.main:update error", err)
	return
}

返回result类型为sql.Result,包含两个方法,分别返回最后插入行数的主键id和影响的行数。

//sql.Result
type Result interface {
    LastInsertId() (int64, error)
    RowsAffected() (int64, error)
}

Engine.Exec()支持Insert, Update, Delete方法,支持表达式和占位符。插入就不要写sql了直接用engine.Insert()方法。

实用方法

  • 查询
    Engine.SQL(DQL).Find(&变量)

DQL可以是任意结构化查询语言,通过Find批量查找返回的是一个结构体数组,实用起来非常方便。

// Engine.SQL() /*
//stu2 := make([]StuTests, 0)
var stu2 []StuTests
Engine.SQL("select * from stu_tests").Find(&stu2)
fmt.Println(stu2)
  • 插入

Engine.Insert(...&变量)

通过结构体一键插入数据,(结构体于数据库表映射),支持单个和批量

  • 更新

更新情况比较复杂,使用最多的为根据主键更新或者根据结构体更新。

  1. 根据主键更新Engine.ID(1).Update(&user)
UPDATE user SET ... Where id = ?

前一个方法的为主键参数,后一个参数为更新的结构体,该方法已一个结构体为整体,需要注意是否需要回显。

  1. Engine.Update(&user, &User{Name:name})
UPDATE user SET ... Where name = ?

结构体更新就是传入两个结构体变量,将满足第二个结构体数据的表中的数据,修改为第一个参数的结构体数据。

  1. Engine.Exec("update user set age = ? where name = ?", age, name)

单个字段修改,使用Engine.Exec方法对单个字段修改。

  • 删除

数据库一般为软删除在数据库添加状态字段,查询时选择查询即可。

  • SQL函数

在sql中经常使用sql函数,例如求和函数sum(),获取记录函数count(*),平均数avg()等,也可以使用一个较为通用的方法Engine.QueryString()

Engine.QueryString()方法返回一个如下的map数组,在SQL查询中几乎所有数据都是以一个二维表的形式展现的。

[]map[string]string

那么这个二维表的数据项处理转化为结构体外,map类型也是比较直观的类型,对于一个数据项,列名为key,值为value,通过数组在存储多个数组。于是大多是查询的数据都可以直接转化为map的类型。

对于需要经常使用单个字段的转化为map不方便还需要解析,但是使用SQL方法一般查询的返回的比较少直接转化为map也具有通用性。

//count(*)函数

queryString, err := Engine.QueryString("select count(*) as sum from stu_tests")
if err != nil {
	print(err)
	return
}
fmt.Println(queryString)
fmt.Println(queryString[0]["sum"])

在这里插入图片描述

事务

对于一些重要的数据都需要事物的支持,xorm也提供了事物的支持。

Engine.NewSession()创建一个事务数据库引擎,默认开启事物,并提供事物关闭方法,事务是原子操作需要提交。

session := Engine.NewSession()

//方法结束后关闭事务
defer session.Close()

// add Begin() before any action
if err := session.Begin(); err != nil {
    // if returned then will rollback automatically
    return err
}

/**
action
**/

// add Commit() after all actions
err = session.Commit()
if err != nil {
    return
}

http://xorm.topgoer.com/
https://gitea.com/xorm/xorm/src/branch/master/README_CN.md

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

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

相关文章

4月26日,每日互动(个推)与您相约第六届数字中国建设峰会

4月26日-30日,第六届数字中国建设峰会及成果展览会将在福州隆重举行。本届峰会以“加快数字中国建设,推进中国式现代化”为主题,由国家网信办、国家发改委、科技部、工信部、国务院国资委、福建省人民政府共同主办,福州市人民政府…

嵌入式Linux(4):应用层和内核层数据传输

文章目录 简介1、如果在应用层使用系统IO对设备节点进行打开,关闭,读写等操作会发生什么呢?写个例子2、假如驱动层的file_operations里面没有实现read之类的操作函数,会发生什么?3、应用层和内核层室不能直接进行数据传…

Go语言面试题--基础语法(27)

文章目录 1.下面这段代码输出什么?2.下面这段代码输出什么?3.下面这段代码输出什么? 1.下面这段代码输出什么? func main() {var a [5]int{1, 2, 3, 4, 5}var r [5]intfor i, v : range a {if i 0 {a[1] 12a[2] 13}r[i] v}f…

ROS学习第五节——话题通信之发布

首先补充一个命令ROS计算图 rosrun rqt_graph rqt_graph 1.原理讲解 话题通信实现模型是比较复杂的,该模型如下图所示,该模型中涉及到三个角色: ROS Master (管理者)Talker (发布者)Listener (订阅者) ROS Master 负责保管 Talker 和 Listener 注册的信息&…

数字孪生(1)

目前接触的客户群体是做大屏展示,闲鱼上5元包邮的那种科技感前端(不好意思我买了)各路模型大整合 实景GISiOT,如果再来点动画就好,然满屏动起来,火灾烧起来,水面荡漾起来,工程车开起…

关于GeoServer发布的wfs服务的精度问题

本周基于arcgis/core组件,利用arcgis api for js 4.22版本加载GeoServer发布的同一数据源的wms和wfs服务,出现了偏移的问题。 分析:同一数据源不同的访问方式,出现了偏移,这是很严重的问题。初步判断为js api加载方式的…

2023年4月北京/江苏/深圳CDGA/CDGP数据治理专家认证考试报名

DAMA认证为数据管理专业人士提供职业目标晋升规划,彰显了职业发展里程碑及发展阶梯定义,帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力,促进开展工作实践应用及实际问题解决,形成企业所需的新数字经济下的核心职业…

【社区图书馆】Go语言程序设计感想

随着 Go 语言的越来越流行,越来越多的人对其设计和语法进行了评价。以下是一些关于 Go 技术的感想: Go语言的特色: 没有继承多态的面向对象强一致类型interface不需要显式声明(Duck Typing)没有异常处理(Error is value)基于首字母的可访问…

大学计划《数字化转型赋能教育创新发展高峰论坛》成功举办

2023年4月8日,由航天科技控股集团股份有限公司(简称“航天科技”)主办,CFF上海与上海电子信息职业技术学院承办、智慧树网支持的《数字化转型赋能教育创新发展高峰论坛》线上会议顺利召开。此次会议邀请到了众多教育界专家、教学名…

Linux 文件描述符

Linux 文件描述符 Linux 中一切皆文件,比如 C 源文件、视频文件、Shell脚本、可执行文件等,就连键盘、显示器、鼠标等硬件设备也都是文件。 一个 Linux 进程可以打开成百上千个文件,为了表示和区分已经打开的文件,Linux 会给每个…

基于AT89C51单片机的电子万年历系统

点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87708258 源码获取 主要内容: 电子万年历系统以实时时钟芯片DS1302和AT89C52单片机为主要研究对象,着重进行51单片机控制系统的设计研究和如…

天梯赛 L3-025 那就别担心了

原题链接: PTA | 程序设计类实验辅助教学平台 题目描述: 下图转自“英式没品笑话百科”的新浪微博 —— 所以无论有没有遇到难题,其实都不用担心。 博主将这种逻辑推演称为“逻辑自洽”,即从某个命题出发的所有推理路径都会将结…

DHCP的原理和配置

DHCP在一个广播域里动态修改IP地址 背景 DHCP (Dynamic Host Configuration Protocol,动态主机配置协议)由Internet工作任务小组设计开发专门用于为TCP/IP网络中的计算机自动分配TCP/IP参数的协议 使用DHCP的好处 减少管理员的工作量避免输入错误的可能避免IP地…

Java每日一练(20230421)

目录 1. 整数排列 🌟 2. 数组排序 🌟 3. 单词搜索 🌟🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 整数排列 十位数的所有排列…

jmeter的界面介绍

前言 jmeter是一款进行接口自动化,性能测试的开源的工具 界面 jmeter菜单里面有个文件--模板,这个主要是一些请求不知道怎么设置时可以选择预制的一些模板 选择对应的模板点击创建,就可以生成一个对应的记录,我们选择jdbc&…

2021遥感应用组二等奖:基于机器学习回归算法的鄱阳湖水质遥感定量反演及时序变化监测研究

作品介绍 一、作品背景 鄱阳湖是中国第一大淡水湖,也是中国第二大湖,它在调节长江水位、涵养水源、改善当地气候等方面起着重大的作用。但近年来受围垦、环境污染等人类活动影响,鄱阳湖湿地退化严重,同时使鄱阳湖的容量减少&…

C语言中static的作用

在 C语言 中,static 通常用来修饰变量和函数。 static 修饰变量 变量按照作用域不同,分为全局变量和局部变量。 当static修饰全局变量时,该变量仍然可以在该文件的全局区域内引用,并且在编译阶段时为该变量分配内存,…

Ubuntu 安装 Samba 服务器

1. Ubuntu 安装 Samba 服务器 确认安装: dpkg -l | grep samba 安装: sudo apt-get install samba samba-common 卸载: sudo apt-get autoremove samba2. Samba 服务器配置 sudo vi /etc/samba/smb.conf在文件最后添加 [Share] commentThis is samba …

Leetcode-day3【215】数组中的第K个最大元素

文章目录 215. 数组中的第K个最大元素题目解题思路解题思路【学习】基于快速排序的选择方法 215. 数组中的第K个最大元素 题目 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素&#…

osg实现地球并在指定经纬度放置一个飞机模型(非osgEarth方式)

代码如下&#xff1a; #include<osgViewer/Viewer> #include<osgGA/TrackBallManipulator> #include<osg/Shape> #include<osg/ShapeDrawable> #include<osg/Texture2D> #include<osgDB/readFile> #include<osg/MatrixTransform> #…