培训型网站建设方案,商业网站设计制作公司,免费软件是什么意思,企业管理培训公司排行榜golang的数据库操作xorm使用起来非常方便#xff0c;不用再自己写SQl语句#xff0c;而且xorm自己给我们做了SQL防注入等操作#xff0c;用起来既方便又安全。此次文章我不会记录xorm的基本操作#xff0c;我值记录一些特殊用法问题#xff0c;包括动态创建表单、基于xorm… golang的数据库操作xorm使用起来非常方便不用再自己写SQl语句而且xorm自己给我们做了SQL防注入等操作用起来既方便又安全。此次文章我不会记录xorm的基本操作我值记录一些特殊用法问题包括动态创建表单、基于xorm的联合查询、基于xorm的跨表查询。 首先是基于xorm的数据库连接的创建代码如下
import (github.com/go-xorm/xorm
)engine, err : xorm.NewEngineGroup(mysql,root:passwordtcp(127.0.0.1:3306)/dbname?charsetutf8)
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.ipwhitelistdata.ip).select(*)//等价于执行如下mysql语句最后返回的结果是两个表的组合的数据
//SELECT * FROM resource inner join whitelistdata on resource.ipwhitelistdata.ip;//如果只想通过筛选获取resource的数据
engine.Table(resource).Join(inner, whitelistdata, resource.ipwhitelistdata.ip).select(resource.*)
//等价于mysql语句
//SELECT resource.* FROM resource inner join whitelistdata on resource.ipwhitelistdata.ip;
数据库的执行结果如下所示如下两条数据 然后再使用Find指令将查询的数据保存在数组当中。 然后是left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录
left是返回包括左表中的所有记录和右表中联结字段相等的记录 真实逻辑也是将两个表组合根据查询条件查询出数据左表数据是全部返回的如果有不满足条件则右边用null来填充操作代码如下
engine.Table(resource).Join(left, whitelistdata, resource.ipwhitelistdata.ip).select(*)//等价于执行如下mysql语句最后返回的结果是两个表的组合的数据
//SELECT * FROM resource left join whitelistdata on resource.ipwhitelistdata.ip;//如果只想通过筛选获取resource的数据
engine.Table(resource).Join(left, whitelistdata, resource.ipwhitelistdata.ip).select(resource.*)
//等价于mysql语句
//SELECT resource.* FROM resource left join whitelistdata on resource.ipwhitelistdata.ip;
数据库的执行结果如下所示如下图所示 然后left还有一种用法就是需要查询左边数据不满足那个条件查询的数据即查询满足条件查询的剩余不满足条件的数据操作命令如下
engine.Table(resource).Join(left, whitelistdata, resource.ipwhitelistdata.ip).select(*).where(whitelistdata.ip?,nil)//等价于执行如下mysql语句最后返回的结果是两个表的组合的数据
//SELECT * FROM resource left join whitelistdata on resource.ipwhitelistdata.ip where whitelistdata.ip is null;查询结果如下 3、基于xorm的跨表查询
因为之前的数据库查询用的是xorm操作但是我们遇到个需求需要联表查询项目里面防止数据太做了分表处理所以查询的时候就存在跨表查询。但是xorm这个插件不存在直接的跨表查询最后查阅了资料发现可以使用xorm的builder模块来实现跨表查询即mysql原生语句里面的union。这种情况是针对那些两个表的数据类型完全一致的情况适用。例子如下
他的原理是先使用builder生成原生的sql语句然后再使用xorm来执行语句使用起来还是很方便
import (xorm.io/builderfmt
)//使用builder组合union的查询mysql语句
sqlBuilder builder.Select(*).From(agentlogstablestartMonth).Union(all, builder.Select(*).From(agentlogstableendMonth))//转换成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否则会报错