xorm数据库操作之Join、Union

news2024/11/19 21:18:05

        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.coloradmin.cn/o/1046500.html

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

相关文章

Spring大白话--三级缓存解决循环依赖问题

文章目录 前言一、Spring 循环依赖是什么?二、Spring 三级缓存解决单例的循环依赖:2.1 Bean 单例对象生成的过程:2.2 三级缓存工作过程: 三、Spring 三级缓存无法解决的单例循环依赖情况:3.1 通过构造方法注入的bean &…

如何优化网站排名(百度SEO指南与优化布局方法)

百度SEO指南介绍:蘑菇号-www.mooogu.cn 首先,为了提高网站的搜索引擎优化排名,需要遵循百度SEO指南的规则和标准。这包括使用符合规范的网站结构、页面内容的质量和与目标用户相关的关键词。避免使用非法技术和黑帽SEO的方法。 增加百度SEO…

如何快速重置模型原点

1、什么是模型原点? 模型原点是三维建模中的概念,它是指在一个虚拟三维空间中确定的参考点。模型原点通常位于模型的几何中心或基本组件的中心位置。如图所示: 可以看到模型的原点在模型的几何中心 2、模型原点的作用 知道了什么是模型原点&…

AVL Cruise 2020.1 安装教程

文章目录 安装包安装破解 安装包 链接:https://pan.baidu.com/s/1GxbeDj_SyvKFyPeTsstvTQ?pwd6666 提取码:6666 安装 安装文件: 双击setup.exe: 一直netx,中间要修改两次路径,第一次是安装位置&#xf…

常用螺栓标准、规格、用途汇总表

螺栓 1 常用螺栓标准、用途 常用螺栓标准、规格、用途见表1。 表1 常用螺栓标准、规格、用途汇总表 注:1.冷镦工艺生产的小六角头螺栓具有材料利用率高、生产效率高、机械性能高等优点,但由于头部尺寸较小, 不宜用于多次装拆、被联接件强度较低和易锈蚀等场合。 2.…

Mac多协议传输和文件管理工具ForkLift 4

ForkLift 4 for Mac 是一个强大的文件管理工具,具有直观的界面和强大的功能。它提供了一个直观的界面,使用户能够轻松地管理他们的文件和目录,以及进行各种操作,如复制、移动、重命名、删除等。 它还支持多种文件传输协议&#x…

PHP开发框架及特点

PHP有许多开发框架,每个框架都有其独特的特点和用途。以下是一些常见的PHP开发框架以及它们的特点,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1.Laravel Laravel是一个流行的PHP框架…

踩坑 | vue动态绑定img标签src属性的一系列报错

文章目录 踩坑 | vue项目运行后使用require()图片也不显示问题描述vue中动态设置img的src不生效问题的原因require is not defined 解决办法1:src属性直接传入地址解决办法2 踩坑 | vue项目运行后使用require()图片也不显示 问题描述 在网上查阅之后,发…

攻防世界题目练习——Reverse新手+引导模式

题目目录 1. 6662.Reversing-x64Elf-1003. easyRE14. insanity5. open-source6. game7. Hello, CTF8. re1 1. 666 下载附件 用IDA Pro打开文件,直接看到main入口,反编译查看代码如下: 注:strcmp(a,b)函数当ab时返回值为0。 int …

深度学习|如何确定 CUDA+PyTorch 版本

对于深度学习初学者来说,配置深度学习的环境可能是一大难题,因此本文主要讲解CUDA; cuDNN; Pytorch 三者是什么,以及他们之间的依赖关系。 CUDA CUDA(Compute Unified Device Architecture)是由NVIDIA开发的用于并行计…

【CMU15-445 Part-12】Query Execution I

Part12-Query Execution I Processing Models Processing Model主要指的是明确如何去执行一个查询计划(top 2 bottom or bottom 2 top,operator之间的传递)。 Iterator Model (volcano model/pipeline model);每个算子实现一个Next( ),父…

Matlab中clear,close all,clc功能详细说明

背景: 我们在写matlab程序时,首行总是先敲入:clear; close all; clc;,但你真的知道这三句话的具体作用嘛,下面进行详细说明和演示。 一、clear的功能 clear的功能:清理工作区变量,不清理前是…

每日一练 | 华为认证真题练习Day115

1、FEC(Forwarding Equivalence Class)转发等价类,是一组具有某些共性的数据流的集合;FEC可以根据地址进行划分,但是不能根据业务类型、QoS等要素进行划分。 A. 对 B. 错 2、关于OSI参考模型中网络层的功能说法正确的是? A. OS…

Linux部署elk日志监控系统

目录 一、简介 二、部署elasticsearch 2.1 安装jdk11(jdk版本>11) 2.2 下载安装包 2.3 授权elk用户 2.4 配置elasticsearch.yml 2.5 启动elasticsearch 三、部署logstash 3.1 启动测试 3.2 可能出现的报错 3.3 指定配置文件启动logstash 3.4 安装El…

【基于Qt和OpenCV的多线程图像识别应用】

基于Qt和OpenCV的多线程图像识别应用 前言多线程编程为什么需要多线程Qt如何实现多线程线程间通信 图像识别项目代码项目结构各部分代码 项目演示小结 前言 这是一个简单的小项目,使用Qt和OpenCV构建的多线程图像识别应用程序,旨在识别图像中的人脸并将…

作为产品经理,你是如何分析和管理你的产品需求的?

作为一名产品经理,分析和管理产品需求是非常重要的工作。在产品开发周期中,需求调研、需求分析、需求管理等环节都是非常关键的,因为好的需求管理能够直接影响产品的质量和用户体验。 需求调研 在进行需求调研的过程中,我们首先…

App开发者如何从立项着手,奠定商业化基础,完成0到1转变?

随着移动互联技术的发展,流量即价值的观念深入人心,大量不同细分领域的移动应用进入市场。根据工信部公布数据,2023年上半年,我国国内市场上监测到活跃的APP数量为260万款(包括安卓和苹果商店),…

Visual Studio 如何删除多余的空行,仅保留一行空行

1.CtrlH 打开替换窗口(注意选择合适的查找范围) VS2010: VS2017、VS2022: 2.复制下面正则表达式到上面的选择窗口: VS2010: ^(\s*)$\n\n VS2017: ^(\s*)$\n\n VS2022:^(\s*)$\n 3.下面的替换窗口皆写入 \n VS2010: \n VS2017: \n VS2022: \n …

铁路用热轧钢轨

声明 本文是学习GB-T 2585-2021 铁路用热轧钢轨. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了铁路用钢轨的订货内容、分类、尺寸、外形、质量及允许偏差、技术要求、试验方法、检 验规则、标志及质量证明书。 本标准适用于3…

react import爆红

如上所示,会标红, 解决办法:在vscode内部SHiftCtrlP 输入Reload window, 如上的第一个,选中后回车,标红就没了,非常好用。