xormplus是xorm的增强版,为xorm提供类似ibatis的配置文件及动态SQL支持

简介

xorm是一个简单而强大的Go语言ORM库,通过它可以使数据库操作非常简便。本库是基于原版xorm的定制增强版本,为xorm提供类似ibatis的配置文件及动态SQL支持,支持AcitveRecord操作。

github地址:https://github.com/armingli/xorm

//安装
go get -u github.com/xormplus/xorm

数据库映射

ORM框架最重要的就是将数据映射为程序中的数据结构。在Go中结构体是主要的自定义的数据结构,将数据的表格映射为go的结构体,使go程序中可以实用数据库的数据。

在大多数的orm框架中,如果数据库表名和程序中的数据结构名一致,成员变量和数据库表的字段对应,orm底层的设计就可以自动转化过来,查询的数据直接克隆到程序的变量中中。

但是大多数情况下,这些字段使并不对应的,需要通过一些配置和约定来实现。

在这里插入图片描述

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

在go语言中首字母大写表示访问权限,但是这就和数据不一样了,xorm底层使用了core.IMapper来试下数据库映射。

https://static.kancloud.cn/xormplus/xorm/167084

mapper描述
core.SnakeMapper支持struct为驼峰式命名,表结构为下划线命名之间的转换
core.SameMapper支持结构体名称和对应的表名称以及结构体field名称与对应的表字段名称相同的命名
core.GonicMapper和SnakeMapper很类似,但是对于特定词支持更好,比如ID会翻译成id而不是i_d

通过引擎来设置:

engine.SetMapper(core.SameMapper{})

更多规则移步

Mapper的映射来操作是最理想的,但是有些情况并不满足需要使用tag标签来定义,同时还具有以下性质:

  • 如果结构体拥有TableName() string的成员方法,那么此方法的返回值即是该结构体对应的数据库表名。

  • engine.Table()方法可以改变struct对应的数据库表的名称

  • 通过sturct中field对应的Tag中使用xorm:"'column_name'"可以使该field对应的Column名称为指定名称

在这里插入图片描述

数据库操作方法

xorm是一个完全的orm框架,使用改框架几乎可以做到不用写sql语句,但是小编习惯写sql,感觉直接写sql更直观。

插入

insert into <tablename> (cols ...) values (cols...)
engine.Insert(user)

user是一个数据库表映射的结构体实例,将实例传入构建一条插入语句。user可以是指针和变量类型。

在插入单条数据成功后,如果该结构体有自增字段(设置为autoincr),则自增字段会被自动赋值为数据库中的id。这里需要注意的是,如果插入的结构体中,自增字段已经赋值,则该字段会被作为非自增字段插入。

批量插入参数为多个结构体实例。

xorm支持原生sql插入:

engine.Exec()

sql ="insert into user(username,password) values (?, ?)"
res, err := engine.Exec(sql, "xiaoxu", "123456") 

//  ?会被替换为参数

engine.Sql()

sql ="insert into user(username,password) values (?, ?)"
affected, err := engine.Sql(sql, "xiaoxu", "123456").Execute()

stpl配置文件

类似myabtis的xml配置文件。

sql := "insert.example.stpl"
paramMap := map[string]interface{}{"key": "config_3", "value": "3"}
affected, err := engine.SqlTemplateClient(sql, &paramMap).Execute()

stpl配置文件在查询一节详细介绍

更新

affected, err := engine.Id(id).Update(user)

id指定更新的数据项,update指定更新的数据元素。user是一个结构体实例,内部包含更新的数据,作为一个整体更新,如果没有某些字段就不更新,类型的默认值也不会更新。

一般情况下,直接以映射的结构体作为更新的对象,而不是像下面这样对某些字段更新。
affected, err := engine.Id(id).Cols("age").Update(&user)

数据库一般为假删除,即有状态字段,删除就不再叙述。

查找

  1. ORM查询

xorm查询方法为Get()Find()相当于SELECT的条件关键字。前者用于单挑数据的查询,后者用于多条数据的查询。

//根据id查询
var user User
engine.Id(1).Get(&user)
// SELECT * FROM user Where id = 1


//where条件查询
has, err := engine.Where("name = ?", name).Get(&user)
// SELECT * FROM user WHERE name = ? LIMIT 1


//数据元素查询
engine.Cols("age", "name").Get(&usr)
// SELECT age, name FROM user limit 1

//数据元素条件查询
has, err := engine.Where("id = ?", id).Cols(cols...).Get(&valuesSlice)
// SELECT col1, col2, col3 FROM user WHERE id = ?
//查询所有
everyone := make([]Userinfo, 0)
err := engine.Find(&everyone)
//SELECT * FROM user

Get()Find()的区别在于舍去了LIMIT 1其它都是完全一样的,语法规定了两个方法只在末尾为结构体赋值,且参数都为指针类型。

配置文件实现动态SQL(特色)

对于orm操作数据,以及通过engine.Sql()engine.Exec() 原生sql操作数据库,已经满足大部分要求。但是也有特殊情况,如模糊查询,如果没有查询的参数sql就不能生成对应字段。因此需要使用动态sql。

xorm提供了SqlMap配置和SqlTemplate功能支持类ibatis方式的SQL操作

ibatis就是MyBatis那一套通过xml配置文件来生成和1配置sql的方案。该方案需要手写sql,也是小编习惯的一种方式。

SqlMapSqlTemplate

armingli/xorm

SqlMap是针对XML文件的sql配置,SqlTemplate是针对.stpl模板的配置(支持动态sql)。

数据库驱动工具创建数据库会话:

package main

import (
	"fmt"
	_ "gorm.io/driver/mysql"
	"xorm.io/xorm"
)

func db() *xorm.Engine {
	driverName := "mysql"
	dataSource := "root:root@/account?charset=utf8"
	engine, err := xorm.NewEngine(driverName, dataSource)
	if err != nil {
		fmt.Println("数据库连接失败", err)
	}
	return engine

}

func main() {

	//数据项插入
	user1 := User{
		0,
		"test3",
		"admin1",
		"admin",
	}
	db().Insert(user1)

	//元素插入
	db().Table("user").Insert(map[string]interface{}{
		"user":     "test", //map类型的key为数据字段,value为值
		"password": "123",
		"role":     "admin",
	})

	//查询
	var users []User
	err := db().SQL("SELECT * FROM user").Find(&users)
	if err != nil {
		println(err)
	}
	fmt.Println(users)
}

使用sql映射需要先注册sql引擎,SqlMap或者SqlTemplate

1、使用RegisterSqlMap()注册SqlMap配置
2、RegisterSqlTemplate()方法注册SSqlTemplate模板配置
3、SqlMap配置文件总根目录和SqlTemplate模板配置文件总根目录可为同一目录

//注册SqlMap配置,xml格式
err := engine.RegisterSqlMap(xorm.Xml("./sql/oracle", ".xml"))

//注册SqlTemplate配置,使用Pongo2模板引擎
err := engine.RegisterSqlTemplate(xorm.Pongo2("./sql/oracle", ".stpl"))

//注册SqlTemplate配置,使用html/template模板引擎
err := engine.RegisterSqlTemplate(xorm.Default("./sql/oracle", ".tpl"))

db.RegisterSqlMap()过程:
配置文件中sql配置会读入内存并缓存
xml配置文件中sql标签的id属性值作为SqlMap的key,如有重名id,则后加载的覆盖之前加载的配置sql条目
xml的占位符会被参数特换,该方式只能基于简单的sql配置,无法实现动态sql。

db.RegisterSqlTemplate()过程
RegisterSqlTemplate()方法按指定目录遍历所配置的目录及其子目录及其子目录下的所有stpl模板文件
stpl模板文件名作为SqlTemplate存储的key,内容会读入内存并缓存

不管是哪种方式,sql映射都是基于key-value完成的,因此在程序中加载key框架会自动调用value(sql)。

sqlMap

xormplus引擎加载配置文件的key的方法,执行SqlMap配置文件中的Sql语句,返回的结果类型为[]map[string]interface{}。由于sqlmap必须具有通用性因此返回的结果只能是前者的类型,需要开发者自行转化为结构体类型。

package main

import (
	"fmt"
	"github.com/armingli/xorm"
	_ "gorm.io/driver/mysql"
)

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

func db() *xorm.Engine {
	//配置数据库驱动
	driverName := "mysql"
	dataSource := "root:root@/account?charset=utf8"
	engine, err := xorm.NewEngine(driverName, dataSource)
	if err != nil {
		fmt.Println("数据库连接失败", err)
	}

	//注册sqlmap
	err = engine.RegisterSqlMap(xorm.Xml("demo/sqlmap", ".xml"))
	if err != nil {
		fmt.Println("注册sqlmap异常", err)
	}
	return engine

}

func main() {
	queryInterface, err := db().SqlMapClient("selectAllUsers").Query().List()
	if err != nil {
		println(err)
	}
	fmt.Println(queryInterface)

}

在这里插入图片描述

在这里插入图片描述

也可以通过?占位符传参:

<sqlMap>
   <sql id="sql_s_1">
       select id,user,password from user where id = ?
   </sql>
</sqlMap>
queryInterface, err := db().SqlMapClient("selectById", 1).Query().List()
if err != nil {
	println(err)
}

fmt.Println(queryInterface)

在这里插入图片描述

sqmap只能配置一些简单的sql语句,实际上还在功能上并没有太大的扩充,但是将sql与程序分析,减低了程序的耦合性。

SqlTemplate

执行SqlTemplate配置文件中的Sql语句,返回的结果类型为[]map[string]interface{}

在这里插入图片描述

package main

import (
	"fmt"
	"github.com/armingli/xorm"
	_ "gorm.io/driver/mysql"
)

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

func db() *xorm.Engine {
	//配置数据库驱动
	driverName := "mysql"
	dataSource := "root:root@/account?charset=utf8"
	engine, err := xorm.NewEngine(driverName, dataSource)
	if err != nil {
		fmt.Println("数据库连接失败", err)
	}

	//注册sqltemplate
	err = engine.RegisterSqlTemplate(xorm.Pongo2("demo/sqltemplate", ".stpl"))
	if err != nil {
		fmt.Println("注册sqlmap异常", err)
	}
	//engine.ShowSQL(true)
	return engine
}

func main() {
	paramMap_5_2 := map[string]interface{}{"id": 2}
	//paramMap_5_2 := map[string]interface{}{"id": 0, "user": "xiaoxu"}
	results, err := db().SqlTemplateClient("sqltemplate.stpl", &paramMap_5_2).Query().List()

	if err != nil {
		println(err)
	}
	fmt.Println(results)

}

在这里插入图片描述

使用SqlTemplate有三个步骤,

  1. 下载源码

  2. 引擎注册sqltemplate

//注册sqltemplate
err = engine.RegisterSqlTemplate(xorm.Pongo2("demo/sqltemplate", ".stpl"))
if err != nil {
	fmt.Println("注册sqlmap异常", err)
}
  1. 传参并返回数据
// map[string]interface{}定义传递参数
paramMap := map[string]interface{}{"id": 2}
//paramMap:= map[string]interface{}{"id": 0, "user": "xiaoxu"}
//SqlTemplateClient方法加载key,(这里的key就是单个文件)并传入参数
results, err := db().SqlTemplateClient("sqltemplate.stpl", &paramMap).Query().List()

if err != nil {
	println(err)
}
fmt.Println(results)

使用SqlTemplateClient方法时,部分参数未使用,请记得使用对应类型0值(默认值)。

如果SqlTemplateClient执行的为DML(insert,update,delete)时返回的是影响行数,使用Execute()方法。

sql_i_3 := "insert.example.stpl"
paramMap_i_t := map[string]interface{}{"key": "config_3", "value": "3"}
affected, err := engine.SqlTemplateClient(sql_i_3, &paramMap_i_t).Execute()

.stpl是支持pongo2语言的,如下

select *
from user where
{% if id != 0 %}
id=?id
{% else%}
user=?user
{% endif %}

id=?iduser=?user?后面的字段不能去掉,其和程序中map[string]interface{}参数的字段对应并必须一致,才能自动赋值。否则查询不出数据。

pongo2语法:https://github.com/flosch/pongo2

Django内置模板标签

gin框架也是有模板语法的,SqlTemplate也支持使用gin的模板语法,那么将sql引擎注册为gin-html/template模板引擎。


//注册SqlTemplate配置,使用html/template模板引擎
err := engine.RegisterSqlTemplate(xorm.Default("./sql/oracle", ".tpl"))

更多移步:https://www.kancloud.cn/xormplus/xorm/167081

尝试了一下,没有官网的演示还是找不到头脑,希望会的大佬留言指导。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FE_Vue学习笔记 条件渲染[v-show v-if] 列表渲染[v-for] 列表过滤 列表排序

1 条件渲染 v-show v-if 使用template可以使其里面的内容在html的结构中不变。条件渲染&#xff1a; v-if 1&#xff09;v-if“表达式” 2&#xff09;v-else-if“表达式” 3&#xff09;v-else {} 适用于&#xff1a;切换频率较低的场景。特点&#xff1a;不展示的DOM元素直…

( 位运算 ) 231. 2 的幂 / 342. 4的幂 ——【Leetcode每日一题】

❓题目一 231. 2 的幂 难度&#xff1a;简单 给你一个整数 n&#xff0c;请你判断该整数是否是 2 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 如果存在一个整数 x 使得 n 2 x n 2^x n2x &#xff0c;则认为 n 是 2 的幂次方。 …

智慧档案馆建设之八防十防常用的设备

档案八防十防常用的十款设备 序号 名称 1 温湿度传感器 2 空气质量云测仪 3 恒湿净化一体机 4 健康防护一体机 5 综合智能触摸一体化区域控制器 6 空调红外学习控制模块 7 漏水检测控制器及感应线 8 数字烟雾传感器 9 红外防盗传感器 10 系统软件平台 附…

连接器:一种可靠耐用、节约成本的同为科技(TOWE)工业连接器

随着我国经济建设水平的飞速发展&#xff0c;工业连接器被广泛应用于工业、化工、机场、船舶、码头、建筑、铁路、医疗、会展、商业演出等领域。工业连接器的作用是用于连接一个电路导体与另一个电路导体、或一个传输元件与另一个传输元件的装置&#xff0c;并且为两个电路子系…

涅槃重生,BitKeep如何闯出千万用户新起点

在全球&#xff0c;BitKeep钱包现在已经有超过千万用户在使用。 当我得知这个数据的时候&#xff0c;有些惊讶&#xff0c;也有点意料之中。关注BitKeep这几年&#xff0c;真心看得出这家公司的发展之迅速。还记得2018年他们推出第一个版本时&#xff0c;小而美&#xff0c;简洁…

Java每日一练(20230513) 输出最值、盛水容器、旋转数组II

目录 1. 输出最值 ※ 2. 盛最多水的容器 &#x1f31f;&#x1f31f; 3. 搜索旋转排序数组 II &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 输出最值…

阿里云备案服务码是什么?备案服务码申请及限制说明

阿里云备案服务码是什么&#xff1f;ICP备案服务码怎么获取&#xff1f;阿里云备案服务码分为免费和付费两种&#xff0c;申请备案服务码是有限制条件的&#xff0c;需要你的阿里云账号下有可用于申请备案服务码的云产品&#xff0c;如云服务器、建站产品、虚拟主机等&#xff…

LDAP配置与安装

LDAP配置与安装 一、安装LDAP1、安装OpenLDAP及相关依赖包2、查看OpenLDAP版本3、配置OpenLDAP数据库4、设置OpenLDAP的管理员密码5、修改配置文件5.1. 修改{2}hdb.ldif文件5.2. 修改{1}monitor.ldif文件5.3. 修改{-1}frontend.ldif文件 6、验证LDAP的基本配置7、修改LDAP文件权…

如何解决人力资本管理挑战?

人力资本管理&#xff08;HCM&#xff09;是任何企业成功的一个重要因素。得益于高效、多产和敬业的员工队伍&#xff0c;在此领域找到正确的方法和策略可以推动您取得更大的成果。 但是&#xff0c;除了关注HCM的好处和机会之外&#xff0c;你还需要做好准备&#xff0c;以克…

【Linux】volatile | SIGCHLD | 多线程概念

文章目录 1. volatile编译器优化 2.SIGCHLD信号验证SIGCHLD的存在 3. 多线程多线程概念理解概念什么是多线程调度成本低局部性原理 什么叫做进程 1. volatile 在vscode中&#xff0c;创建signal.c文件 故意在while中没有写代码块&#xff0c;让编译器认为在main中&#xff0c;…

Mac上如何装Nacos?

Nacos大家都很熟悉,服务注册中心,那么今天给大家写一篇Mac上如何装Nacos的文章。 安装步骤如下: 1、上官网 http://nacos.io/zh-cn/ 点击跳到nacos的官网上。然后点击前往Github 2、找到release 发布版本 来到GitHub上后,页面往下滑,找到latest stable release,点击…

谷歌慌了!想发论文得审批,优先开发产品,让OpenAI没得看

来源 | 机器之心 ID | almosthuman2014 众所周知&#xff0c;谷歌就像人工智能领域的「黄埔军校」&#xff0c;自深度学习兴起后培养出了整整一代机器学习研究人员和工程师。很长一段时间里&#xff0c;谷歌就是领先 AI 技术的代名词。 人们已经习惯跟随谷歌的脚步&#xff0c…

2023 年第八届数维杯大学生数学建模挑战赛 B 题详细思路 节能列车运行控制优化策略

一种可能的建模方法是基于列车的动力学方程和阻力方程&#xff0c;将列车视为单质点&#xff0c;忽略车厢间的车钩力和速度差。根据给定的参数&#xff0c;可以建立如下的方程&#xff1a; $$m(p1)\frac{dv}{dt}F-f(v)-g(i)$$ $$f(v)2.08950.0098v0.006v^2$$ $$g(i)mgi$$ 其…

酒精和肠内外健康:有帮助还是有害?

谷禾健康 酒精与健康 饮酒作为一种特殊的文化形式&#xff0c;在我们国家有其独特的地位&#xff0c;在几千年的发展中&#xff0c;酒几乎渗透到日常生活、社会经济、文化活动之中。 据2018年发表的《中国饮酒人群适量饮酒状况》白皮书数据显示&#xff0c;中国饮酒人群高达6亿…

NFTScan: 蓝筹 NFT 跌幅严重,如何保持竞争力?

最近的市场大跌影响了 NFT 二级市场&#xff0c;市场情绪冷淡下跌严重&#xff0c;交易量和买家骤然下降&#xff0c;而蓝筹作为市场里的中流砥柱也表现不佳。以 BoerdApeYachtClub 为首的等主流 NFT 价格下跌超过 20%。此外&#xff0c;随着 PFP 的热潮已经过去&#xff0c;市…

外网SSH远程连接linux服务器,看这一篇就够了

文章目录 视频教程1. Linux CentOS安装cpolar2. 创建TCP隧道3. 随机地址公网远程连接4. 固定TCP地址5. 使用固定公网TCP地址SSH远程 转载自内网穿透工具的文章&#xff1a;无公网IP&#xff0c;SSH远程连接Linux CentOS服务器【内网穿透】 本次教程我们来实现如何在外公网环境下…

你真的理解分布式数据的分区吗?

分布式数据存储是指将数据分散存储在多个节点或服务器上的技术。而分区是将数据划分为逻辑上的片段或部分&#xff0c;每个分区可以在分布式系统中的不同节点上存储。分区主要是为了可扩展性。不同的分区可以放在不共享集群中的不同节点上&#xff0c;可以帮助实现负载均衡、高…

MySQL 表操作

目录 创建表 案例 查看表结构 修改表 案例&#xff1a; 删除表 创建表 CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎 ; 说明&#xff1a; field 表示列名 dat…

OTA实现设备升级方案

引言 空中下载技术&#xff08;Over-the-Air Technology&#xff0c; OTA&#xff09;是通过移动通信的空中接口实现对移动终端设备进行远程管理的技术。 该技术在IOT行业非常的重要&#xff0c;当随着市场上的产品越来越多&#xff0c;保有量也越来越多&#xff0c;随着时间…

Vue换肤主题

拷贝颜色选择组件 **ThemePicker <template><!-- navabar的换肤组件 --><el-color-pickerv-model="theme":predefine="[#409EFF,