小工具      在线工具  汉语词典  css  js  c++  java

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

# xorm,mysql,golang,xorm 额外说明

收录于:157天前

下载介绍框架

要使用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这种构建和管理工具更专业。

建立以下数据库:

在这里插入图片描述

创建数据库引擎

创建一个引擎。所有的数据库操作都需要基于数据库引擎。 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.SetMaxIdleConns()来实现。
如果需要设置最大打开连接数,则可以使用engine.SetMaxOpenConns()来实现。

数据库映射

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

  • SnakeMapper支持结构体驼峰命名和表结构下划线命名之间的转换,这也是默认的方式。
//设置其他映射方式
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)

在这里插入图片描述

数据库表和字段如下

在这里插入图片描述

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

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

  • 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

然后这个二维表的数据项被处理并转换成结构。地图类型也是比较直观的类型。对于数据项,列名是键,值是值。多个数组通过数组来存储。因此,大部分查询的数据都可以直接转换为地图类型。

对于需要经常使用单个字段的人来说,将其转换为地图很不方便,需要分析。但是,使用 SQL 方法的一般查询将返回较少的数据。直接转换为地图也是通用的。

//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

. . .

相关推荐

额外说明

redis常见的五种数据结构-Hash场景

          这里有个问题,如果想把整个表上百万的数据全放到redis怎么做了?  可以使用分段,比如按id取模,搞100个userkey,(分段key)每个key存几千.个数据。     127.0.0.1:6379> hset cart:100

额外说明

IntelliJ IDEA分享超实用技巧,提高开发效率!

前言 工欲善其事 必先利其器 最近受部门的邀请,给入职新人统一培训IDEA,发现有很多新人虽然日常开发使用的是IDEA,但是还是很多好用的技巧没有用到,只是用到一些基本的功能,蛮浪费IDEA这个优秀的IDE。  同时,在这次分享之后,本人自己也学习到了一

额外说明

【Docker】Docker安全与安全实践(五)

前言: Docker安全性的作用和意义在于确保容器化应用程序和镜像的隔离性、保护数据和系统资源、防止恶意攻击,以及提高应用的整体安全性。 文章目录 1. Docker安全性 1.1 `隔离性` 1.2 `镜像安全` 1.3 `特权访问` 1.4 `数据保

额外说明

IO流 02_byte 字符流、缓冲流、标准输入、输出流、打印流

文章目录 ①. IO流概述及分类 ②. 字节输入流 - FileInputStream ③. 字节输出流 - FileOutputStream ④. 字符输入流 - FileReader ⑤. 字符输出流 - FileWriter ⑥. 字节缓冲流 -

额外说明

vulntarget漏洞靶场-vulntarget-b

vulntarget-b 环境准备 github地址: 百度云 相关漏洞技术 网络拓扑图 环境搭建过程 centos7 极致CMS 域控2016 域成员win10 禅道 网络配置 centos7 域成员win10 域控win2016 测试网络环境 渗透

额外说明

【Unity ShaderGraph】| 给模型添加一个 边缘光效果 实战

前言 【Unity ShaderGraph】| 边缘光效果实战 一、效果展示 二、简易边缘光效果 三、进阶边缘光效果 四、应用实例 前言 本文将使用Unity ShaderGraph制作一个模型边缘光的效果,可以直接拿到项目中使用。 对ShaderGra

额外说明

云桌面初体验 之 爱上无影云桌面

 什么是无影云桌面 无影云桌面 (Elastic Desktop Service),一台长在云上的“超级电脑”,是基于云计算和虚拟化技术的云上桌面服务。 支持桌面环境的快速创建、部署、统一管控与运维;在便捷性、弹性、安全、高性能等方面,具有超越传统PC的

额外说明

深度解析自然语言处理之篇章分析

在本文中,我们深入探讨了篇章分析的概念及其在自然语言处理(NLP)领域中的研究主题,以及两种先进的话语分割方法:基于词汇句法树的统计模型和基于BiLSTM-CRF的神经网络模型。 关注TechLead,分享AI全维度知识。作者拥有10+年互联网服务架构、

额外说明

Oracle视图、自定义函数、存储过程、触发器

视图是一种虚拟表,是实际表的一种映射,主要针对一些复杂查询的一个封装,实际表数据修改,视图数据自动更改 CREATE OR REPLACE VIEW V_TONY AS SELECT A.EMPNO AS EMPNO,A.EMPNO AS EMPNO1,

额外说明

Maven 如何下载依赖包的源码包

使用Maven下载依赖包的时候, 默认是不会下载源码包的,但是有时候, 需要Debug代码,或是看看依赖项的源码的写法, 就需要下载源码包了。 这里以 Apache 的 commons-text 为例, 在Maven中添加如下依赖配置: <depen

ads via 小工具