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

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

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

收录于:23天前

下载介绍框架

要使用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

. . .

相关推荐

额外说明

带注释的RocketMQ源代码,可执行可调试

github地址:带注释可指定的RocketMQ源码地址 我也是拷贝的芋道源码的github上的源码。当然之后添加了大量的自己的注释和总结,同时调整了RocketMQ的启动形式。 clone了源码后,可以直接运行NamesrvStartup和Broker

额外说明

leetcode141(循环链表:双指针方法)

给定一个链表,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中

额外说明

C++实现鼠标左键点击关闭控制台

这里提供一种实现鼠标点击实现关闭控制台的方法。 #include "iostream" #include"windows.h" //必须包含的头文件 using namespace std; int main() { HWND handle =

额外说明

JVM00_面试官对类加载子系统、运行时数据区、内存分配、执行引擎的精神折磨。你能坚持回答多少个问题?

因为热爱所以坚持,因为热爱所以等待。熬过漫长无戏可演的日子,终于换来了人生的春天。他逐渐被人熟知,被人喜爱 三年前,在苏州园区某个国企面试,第一道题目便是:JVM是什么吗?然后就是拿着笔试题目被面试官吊打,面对面试官的灵魂拷问,你坚持到了第几问?希望从今

额外说明

11章MySQL:数据处理之增删改

写在前面: 跟随B站的康师傅学习mysql的笔记摘要和自我总结。 1、插入数据 方式1:使用VALUES添加 情况1:为表的所有字段按默认顺序插入数据 INSERT INTO 表名 VALUES (value1,value2,....); 注意点: 值

额外说明

简单的生成不重复随机数

 import java.util.Arrays; class T {   public static void main(String[] args) {     int a[] = new int[6];     for (int i = 0; i

额外说明

正则表达式判断账号和邮箱正确

实现用户名长度为 6-10,且只能由字母组成的正则表达式。 邮箱的 @ 符前面有 5 到 10 个字符,@ 后面至少 1 个字符,以 com、net、org 结尾 如果账号和邮箱同时判断正确,即登录成功 要求:准备一个输入登录成功的html文件 <!DO

额外说明

【NLP】⚠️学不会打我! 半小时学会基本操作 4⚠️词向量模型

【NLP】⚠️学不会打我! 半小时学会基本操作 4⚠️词向量模型 概述 词向量 词向量维度 Word2Vec CBOW 模型 Skip-Gram 模型 负采样模型 词向量的训练过程 1. 初始化词向量矩阵 2. 神经网络反向传播 词向量模型实战 训练模型

额外说明

Pytorch 最全入门介绍,Pytorch入门看这一篇就够了

本文通过详细且实践性的方式介绍了 PyTorch 的使用,包括环境安装、基础知识、张量操作、自动求导机制、神经网络创建、数据处理、模型训练、测试以及模型的保存和加载。 1. Pytorch简介 在这一部分,我们将会对Pytorch做一个简单的介绍,包括它

额外说明

计算机视觉教程2-6:八大图像特效算法制作你的专属滤镜(附Python代码)

目录 0 写在前面 1 毛玻璃特效 2 浮雕特效 3 油画特效 4 马赛克特效 5 素描特效 6 怀旧特效 7 流年特效 8 卡通特效 0 写在前面 图像特效处理是基于图像像素数据特征,将原图像进行一定步骤的计算——例如像素作差、灰度变换、颜色通道融合等

ads via 小工具