xorm数据库操作之Join、Union

        golang的数据库操作xorm使用起来非常方便,不用再自己写SQl语句,而且xorm自己给我们做了SQL防注入等操作,用起来既方便又安全。此次文章我不会记录xorm的基本操作,我值记录一些特殊用法问题,包括动态创建表单、基于xorm的联合查询、基于xorm的跨表查询。

        首先是基于xorm的数据库连接的创建:代码如下

import ("github.com/go-xorm/xorm"
)engine, err := xorm.NewEngineGroup("mysql","root:password@tcp(127.0.0.1:3306)/dbname?charset=utf8")
if err != nil {log.Fatal("创建lgoxorm引擎失败", err)return nil}
engine.SetMaxIdleConns(dbMaxIdleConns)   //连接池的空闲数大小
engine.SetMaxOpenConns(dbMaxOpenConns)   //设置最大打开连接数
engine.SetConnMaxLifetime(dbMaxLiftTime) //设置连接的最大生存时间
engine.ShowSQL(true)                    //显示每次xorm操作数据库打印SQL语句,可以注释掉

后面的操作就完全使用engine这个数据库句柄来操作数据库

1、动态创建数据库表单

我目前遇到的需求是这样的,在开发过程中,有这么一种情况,数据库表单的键值是完全一样的,用一个结构体表示就可以了,但是表需要多个,而且名字需要动态的添加,有一个资源对应的请求来,然后平台根据资源的信息创建一个专属的表,这样就形成了不同表名,表键值完全一样的情况。经过多次尝试,最后找到了如下方法:

type tablestruct struct {Id             int    `json:"id" xorm:"pk autoincr comment('自动生成id')"`Name           string `json:"name" xorm:" comment('姓名')"`Info           string `json:"info" xorm:"varchar(1024) comment('信息,长度为1024,不指定默认长度为255')"`
}//动态创建数据table方法1:
engine.Table("newtable1").CreateTable(&tablestruct{})//动态创建数据table方法2:
engine.Table("newtable2").Sync2(&tablestruct{})//查询表是否存在,不存在则使用上面两种方法进行动态创建数据库,表名字可以自定义
has, _ := engine.IsTableExist("newtable1")
if has{//已经存在表
}

CreateTable新建数据库新建的时候如果名字一样,则会报错,这种如果tablestruct有更新,也不会更新到后台;Sync2方法是同步或者新建数据库表,就算存在表名也不会出错,而且如果tablestruct有更新,会同步更新字段到表单,所以我一般用第二种方法来动态新建表。

2、基于xorm的联合查询

联合查询在mysql里面的关键字是join,连表查询存在两种情况,一种就是我只取其中一个表的数据,联表查询的另一个表只是作为查询条件作用;还有一种就是联表查询需要查询两个表的数据。

join含有三个参数:第一个参数是INNER, LEFT中的一个值, 第二个参数被联合查询的表名,可以为字符串或者bean, 第三个参数为连接条件

我下面只记录两种常见也是我用的比较多的情况,inner和left,我建了两张表,一张是叫resource,表示存储的资源信息,另一一张表叫whitelistdata,表示存储的IP白名单,下面我将用这两个表来展示join的用法:目前两个表的内容如下所示:

表whitelistdata内容:

表resource内容:

首先是inner join(等值连接) 只返回两个表中联结字段相等的行

inner的意思是将满足条件的两个表的数据组合成新的数据成为一个新的表,最后的功能是获取资源的ip在白名单的ip里面的数据,操作代码如下所示:

engine.Table("resource").Join("inner", "whitelistdata", "resource.ip=whitelistdata.ip").select("*")//等价于执行如下mysql语句,最后返回的结果是两个表的组合的数据:
//SELECT * FROM resource inner join whitelistdata on resource.ip=whitelistdata.ip;//如果只想通过筛选获取resource的数据
engine.Table("resource").Join("inner", "whitelistdata", "resource.ip=whitelistdata.ip").select("resource.*")
//等价于mysql语句
//SELECT resource.* FROM resource inner join whitelistdata on resource.ip=whitelistdata.ip;

数据库的执行结果如下所示如下两条数据:

然后再使用Find指令将查询的数据保存在数组当中。

然后是left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 

left是返回包括左表中的所有记录和右表中联结字段相等的记录 ,真实逻辑也是将两个表组合根据查询条件查询出数据,左表数据是全部返回的,如果有不满足条件,则右边用null来填充,操作代码如下:

engine.Table("resource").Join("left", "whitelistdata", "resource.ip=whitelistdata.ip").select("*")//等价于执行如下mysql语句,最后返回的结果是两个表的组合的数据:
//SELECT * FROM resource left join whitelistdata on resource.ip=whitelistdata.ip;//如果只想通过筛选获取resource的数据
engine.Table("resource").Join("left", "whitelistdata", "resource.ip=whitelistdata.ip").select("resource.*")
//等价于mysql语句
//SELECT resource.* FROM resource left join whitelistdata on resource.ip=whitelistdata.ip;

数据库的执行结果如下所示如下图所示:

然后left还有一种用法就是:需要查询左边数据,不满足那个条件查询的数据,即查询满足条件查询的剩余不满足条件的数据,操作命令如下:

engine.Table("resource").Join("left", "whitelistdata", "resource.ip=whitelistdata.ip").select("*").where("whitelistdata.ip=?",nil)//等价于执行如下mysql语句,最后返回的结果是两个表的组合的数据:
//SELECT * FROM resource left join whitelistdata on resource.ip=whitelistdata.ip where whitelistdata.ip is null;

查询结果如下:

3、基于xorm的跨表查询

因为之前的数据库查询用的是xorm操作,但是我们遇到个需求需要联表查询,项目里面防止数据太,做了分表处理,所以查询的时候就存在跨表查询。但是xorm这个插件不存在直接的跨表查询,最后查阅了资料,发现可以使用xorm的builder模块来实现跨表查询,即mysql原生语句里面的union。这种情况是针对那些两个表的数据类型完全一致的情况适用。例子如下:

他的原理是先使用builder生成原生的sql语句,然后再使用xorm来执行语句,使用起来还是很方便

import ("xorm.io/builder""fmt"
)//使用builder组合union的查询mysql语句
sqlBuilder = builder.Select("*").From(agentlogstable+startMonth).Union("all", builder.Select("*").From(agentlogstable+endMonth))//转换成sql原生语句
sql, _, err := sqlBuilder.ToSQL()
if err != nil {//转换mysql语句错误fmt.Printfn("err = ",err.Error())}//生成最终builder格式的mysql查询语句
sqlBuilder = builder.Dialect(builder.MYSQL).Select("*").From("(" + sql + ") as newtb")//getdata是定义的存储数据的数组或者切片,获取跨表查询的数据
err = engine.SQL(sqlBuilder).Find(&getdata)

备注:查询的时候需要用:builder.Dialect(builder.MYSQL),不能用builder,否则会报错

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

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

相关文章

探索科技前沿,科东带你深度解读2023上海工博会

科东软件诚邀您亲临现场 感受软件定义控制新趋势 这是一场集结全球创新力量与科技创新成果的璀璨盛宴,也是推动未来科技与产业发展的新型工业盛会,更是一次助力构建数字化、低碳化发展格局的重量级活动。 2023年9月19日,备受瞩目的第23届中国…

133.【MySQL_运维篇】

MySQL_运维 (一)、日志 ⭐1.日志_错误日志 (ERROR-LOG)(1).错误日志_介绍(2).错误日志_示列 2.日志_二进制日志 (BINARY-LOG)(1).二进制日志_介绍(2).二进制日志_作用(3).二进制日志_格式(4).二进制日志_查看 (CMD)(5).二进制日志_删除 3.日志_查询日志 (GENERAL-LOG)(1).开启_…

基于PLE结合卡尔曼滤波的RSSI定位算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 ............................................................... for Num_xb Num_xb2Num_…

现在的国内MBA教育是否同质化太严重?

如今在国内的MBA教育领域可以说是一片欣欣向荣,两百余所高校开设MBA项目招生,而报考市场也随着时代的发展持续升温,但是在这背后也存在一些问题伴随发生,其中就是MBA项目的同质化与跟风化趋势越来越明显,主要有以下几个…

Elasticsearch:什么是向量和向量存储数据库,我们为什么关心?

Elasticsearch 从 7.3 版本开始支持向量搜索。从 8.0 开始支持带有 HNSW 的 ANN 向量搜索。目前 Elasticsearch 已经是全球下载量最多的向量数据库。它允许使用密集向量和向量比较来搜索文档。 矢量搜索在人工智能和机器学习领域有许多重要的应用。 有效存储和检索向量的数据库…

MySQL ——多表连接查询

一、(左、右和全)连接概念 内连接: 假设A和B表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录查询出来。A和B两张表没有主付之分,两张表是平等的。 关键字:inner join on 语句&#xf…

Android ConstraintLayout app:layout_constraintHorizontal_weight

Android ConstraintLayout app:layout_constraintHorizontal_weight <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:…

软件设计模式系列之十一——装饰模式

当谈到设计软件系统时&#xff0c;经常需要考虑如何使系统更加灵活、可扩展和易维护。设计模式是一种被广泛采用的方法&#xff0c;用于解决常见的设计问题&#xff0c;并提供了一套可重用的解决方案。装饰模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&…

crypto:RSA

题目 利用代码跑一下解码 import gmpy2 e 17 p 473398607161 q 4511491 d gmpy2.invert(e,(p-1)*(q-1)) print(d)总结 RSA&#xff08;Rivest-Shamir-Adleman&#xff09;是一种非对称加密算法&#xff0c;常用于数据加密和数字签名。它基于两个大素数的乘积难以分解的数…

python实现命令tree的效果

把所有的文档都传到了git上,但是内容过多找起来不方便,突发奇想如果能在readme中,递归列出所有文件同时添加上对应的地址,这样只需要搜索到对应的文件点击就能跳转过去了… 列出文件总得有个显示格式,所以就按照tree的来了… 用python实现命令tree的效果 首先,这是tree的效果…

ATA-8000系列射频功率放大器——应用场景介绍

ATA-8000系列是一款射频功率放大器。其P1dB输出功率500W&#xff0c;饱和输出功率最大1000W。增益数控可调&#xff0c;一键保存设置&#xff0c;提供了方便简洁的操作选择&#xff0c;可与主流的信号发生器配套使用&#xff0c;实现射频信号的放大。 图&#xff1a;ATA-8000系…

算法 杨辉三角求解 java打印杨辉三角 多路递归打印杨辉三角 递归优化杨辉三角 记忆法优化递归 帕斯卡三角形 算法(十二)

1. 杨辉三角&#xff1a; 是二项式系数在三角形中的一种几何排列&#xff0c;中国南宋数学家杨辉1261年所著的《详解九章算法》一书中出现。在欧洲&#xff0c;帕斯卡&#xff08;1623----1662&#xff09;在1654年发现这一规律&#xff0c;所以这个表又叫做帕斯卡三角形。帕斯…

41. Linux系统配置FTP服务器并在QT中使用QFtp实现文件上传

1. 说明 这篇博客主要记录一些在Linux系统中搭建FTP服务器时踩过的一些坑,以及在使用QFtp上传文件时需要注意的问题。 2. FTP环境搭建 在linux系统中,需要安装vsftpd,可以在终端中输入下面的命令进行安装: sudo apt-get install vsftpd使用上述命令安装后,系统中会有一…

Cannot find module ‘core-js/modules/es6.regexp.constructor‘

npm run dev 之后报如下错误 解决方法&#xff1a;npm install core-js2 如果超时或者下载时间慢可以尝试 用cnpm install core-js2

记一次hyperf框架封装swoole自定义进程

背景 公司准备引入swoole和rabbitmq来处理公司业务。因此&#xff0c;我引入hyperf框架&#xff0c;想用swoole的多进程来实现。 自定义启动服务封装 <?php /*** 进程启动服务【manager】*/ declare(strict_types1);namespace App\Command;use Swoole; use Swoole\Proce…

Android 编译插桩操纵字节码

本文讲解如何编译插桩操纵字节码。 就使用 ASM 来实现简单的编译插桩效果&#xff0c;通过插桩实现在每一个 Activity 打开时输出相应的 log 日志。实现思路 过程主要包含两步&#xff1a; 1、遍历项目中所有的 .class 文件​ 如何找到项目中编译生成的所有 .class 文件&#…

pycharm中恢复原始界面布局_常用快捷键_常用设置

文章目录 1 恢复默认布局1 .1直接点击file→Manage IDE Settings→Restore Default Settings&#xff08;如下图所示&#xff09;&#xff1a;1.2 直接点击Restore and Restart&#xff0c; 然后Pycharm就会自动重启&#xff0c;重启之后的界面就是最原始的界面了 2 改变主题2.…

时序预测 | MATLAB实现NGO-GRU北方苍鹰算法优化门控循环单元时间序列预测

时序预测 | MATLAB实现NGO-GRU北方苍鹰算法优化门控循环单元时间序列预测 目录 时序预测 | MATLAB实现NGO-GRU北方苍鹰算法优化门控循环单元时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现NGO-GRU北方苍鹰算法优化门控循环单元时间序列预测&#…

接口测试——接口协议抓包分析与mock_L2

目录&#xff1a; 抓包工具charles抓包工具fiddler抓包工具证书配置app抓包实战练习接口测试实战练习 1.抓包工具charles 工具介绍 支持 SSL 代理支持流量控制支持重发网络请求&#xff0c;方便后端调试支持修改网络请求参数支持网络请求的截获并动态修改可以自动将 json 或…

探索Moonbeam路由流动性的强大功能

Moonbeam的GMP预编译作为MRL的接口&#xff0c;有助于将带有Token的消息从GMP协议&#xff08;通过XCMP&#xff09;传输到与Moonbeam链接的平行链。 为何是个重磅消息&#xff1f;因为这项技术使得将流动性从外部区块链转移到其他波卡平行链成为可能&#xff01; 这里补充一…