# 执行SQL查询的11种常用方式
### 第1种方式
~~~
sql_1_1 := "select * from user"
results, err := engine.QueryBytes(sql_1_1)
//SqlMapClient和SqlTemplateClient传参方式类同如下2种,具体参见第6种方式和第7种方式
sql_1_2 := "select id,userid,title,createdatetime,content from Article where id=?"
results, err := db.SQL(sql_1_2, 2).QueryBytes()
sql_1_3 := "select id,userid,title,createdatetime,content from Article where id=?id"
paramMap_1_3 := map[string]interface{}{"id": 2}
results, err := db.SQL(sql_1_3, ¶mMap_1_3).QueryBytes()
~~~
当调用QueryBytes时,第一个返回值results为[]map[string][]byte的形式。
### 第2种方式
~~~
sql_2_1 := "select * from user"
results, err := engine.QueryString(sql_2_1)
//SqlMapClient和SqlTemplateClient传参方式类同如下2种,具体参见第6种方式和第7种方式
sql_2_2 := "select id,userid,title,createdatetime,content from Article where id=?"
results, err := db.SQL(sql_2_2, 2).QueryString()
sql_2_3 := "select id,userid,title,createdatetime,content from Article where id=?id"
paramMap_2_3 := map[string]interface{}{"id": 2}
results, err := db.SQL(sql_2_3, ¶mMap_2_3).QueryString()
~~~
当调用QueryString时,第一个返回值results为[]map[string]string的形式。
### 第3种方式
~~~
//Value类型本质是[]byte,具有一系列类型转换函数
sql_2_1 := "select * from user"
results, err := engine.QueryValue(sql_2_1)
//SqlMapClient和SqlTemplateClient传参方式类同如下2种,具体参见第6种方式和第7种方式
sql_2_2 := "select id,userid,title,createdatetime,content from Article where id=?"
results, err := db.SQL(sql_2_2, 2).QueryValue()
title := results[0]["title"].String()
sql_2_3 := "select id,userid,title,createdatetime,content from Article where id=?id"
paramMap_2_3 := map[string]interface{}{"id": 2}
results, err := db.SQL(sql_2_3, ¶mMap_2_3).QueryValue()
~~~
当调用QueryValue时,第一个返回值results为[]map[string]xorm.Value的形式。xorm.Value类型本质是[]byte,具有一系列类型转换函数
### 第4种方式:返回的结果类型为 xorm.Result
~~~
//xorm.Value类型本质是[]byte,具有一系列类型转换函数
sql_2_1 := "select * from user"
results, err := engine.QueryResult(sql_2_1).List()
//SqlMapClient和SqlTemplateClient传参方式类同如下2种,具体参见第6种方式和第7种方式
sql_2_2 := "select id,userid,title,createdatetime,content from Article where id=?"
result, err := db.SQL(sql_2_2, 2).QueryResult().List()
title := result[0]["createdatetime"].Time("2006-01-02T15:04:05.999Z")
content := result[0]["content"].NullString()
sql_2_3 := "select id,userid,title,createdatetime,content from Article where id=?id"
paramMap_2_3 := map[string]interface{}{"id": 2}
results, err := db.SQL(sql_2_3, ¶mMap_2_3).QueryResult().List()
~~~
当调用QueryResult时,第一个返回值results为xorm.Result的形式。
### 第5种方式
~~~
sql_3_1 := "select * from user"
results, err := engine.QueryInterface(sql_3_1)
//SqlMapClient和SqlTemplateClient传参方式类同如下2种,具体参见第6种方式和第7种方式
sql_3_2 := "select id,userid,title,createdatetime,content from Article where id=?"
results, err := db.SQL(sql_3_2, 2).QueryInterface()
sql_3_3 := "select id,userid,title,createdatetime,content from Article where id=?id"
paramMap_3_3 := map[string]interface{}{"id": 2}
results, err := db.SQL(sql_3_3, ¶mMap_3_3).QueryInterface()
//Query方法返回的是一个ResultMap对象,它有List(),Count(),ListPage(),Json(),Xml()
//Xml(),XmlIndent(),SaveAsCSV(),SaveAsTSV(),SaveAsHTML(),SaveAsXML(),SaveAsXMLWithTagNamePrefixIndent(),
//SaveAsYAML(),SaveAsJSON(),SaveAsXLSX()系列实用函数
sql_3_4 := "select * from user"
//List()方法返回查询的全部结果集,类型为[]map[string]interface{}
results, err := engine.Sql(sql_3_4).Query().List()
//当然也支持这种方法,将数据库中的时间字段格式化,时间字段对应的golang数据类型为time.Time
//当然你也可以在数据库中先使用函数将时间类型的字段格式化成字符串,这里只是提供另外一种方式
//该方式会将所有时间类型的字段都格式化,所以请依据您的实际需求按需使用
results, err := engine.Sql(sql_3_4).QueryWithDateFormat("20060102").List()
sql_3_5 := "select * from user where id = ? and age = ?"
results, err := engine.Sql(sql_3_5, 7, 17).Query().List()
sql_3_6 := "select * from user where id = ?id and age = ?age"
paramMap_3_6 := map[string]interface{}{"id": 7, "age": 17}
results, err := engine.Sql(sql_3_6, ¶mMap_3_6).Query().List()
//此Query()方法返回对象还支持ListPage()方法和Count()方法,这两个方法都是针对数据库查询出来后的结果集进行操作
//此Query()方法返回对象还支持Xml()方法、XmlIndent()方法和Json()方法,相关内容请阅读之后的章节
//ListPage()方法并非数据库分页方法,只是针对数据库查询出来后的结果集[]map[string]interface{}对象取部分切片
//例如以下例子,是取结果集的第1条到第50条记录
results, err := engine.Sql(sql_3_5, 7, 17).Query().ListPage(1,50)
//例如以下例子,是取结果集的第13条到第28条记录
results, err := engine.Sql(sql_3_5, 7, 17).Query().ListPage(13,28)
//此Count()方法也并非使用数据库count函数查询数据库某条件下的记录数,只是针对Sql语句对数据库查询出来后的结果集[]map[string]interface{}对象的数量
//此Count()方法也并非Engine对象和Session对象下的Count()方法,使用时请区分场景
count, err := engine.Sql(sql_3_5, 7, 17).Query().Count()
~~~
当调用QueryInterface,List或ListPage时,第一个返回值results为[]map[string]interface{}的形式。
### 第6种方式:使用SqlMapClient调用SqlMap配置执行Sql语句
~~~
sql_id_4_1 := "sql_4_1" //配置文件中sql标签的id属性,SqlMap的key
results, err := engine.SqlMapClient(sql_id_4_1).Query().List()
sql_id_4_2 := "sql_4_2"
results, err := engine.SqlMapClient(sql_id_4_2, 7, 17).Query().List()
sql_id_4_3 := "sql_4_3"
paramMap_4_3 := map[string]interface{}{"id": 7, "name": "xormplus"}
results1, err := engine.SqlMapClient(sql_id_4_3, ¶mMap_4_3).Query().List()
~~~
### 第7种方式:使用SqlTemplateClient调用SqlTemplate模板执行Sql语句
~~~
sql_key_5_1 := "select.example.stpl" //配置文件名,SqlTemplate的key
//执行的 sql:select * from user where id=7
//如部分参数未使用,请记得使用对应类型0值,如此处name参数值为空字符串,模板使用指南请详见pongo2
paramMap_5_1 := map[string]interface{}{"count": 2, "id": 7, "name": ""}
results, err := engine.SqlTemplateClient(sql_key_5_1, ¶mMap_5_1).Query().List()
//执行的 sql:select * from user where name='xormplus'
//如部分参数未使用,请记得使用对应类型0值,如此处id参数值为0,模板使用指南请详见pongo2
paramMap_5_2 := map[string]interface{}{"id": 0, "count": 2, "name": "xormplus"}
results, err := engine.SqlTemplateClient(sql_key_5_1, ¶mMap_5_2).Query().List()
~~~
当调用List或ListPage时,第一个返回值results为[]map[string]interface{}的形式。
### 第8种方式:返回的结果类型为对应的[]interface{}
~~~
var categories []Category
err := engine.Sql("select * from category where id =?", 16).Find(&categories)
paramMap_6 := map[string]interface{}{"id": 2}
err := engine.Sql("select * from category where id =?id", ¶mMap_6).Find(&categories)
~~~
### 第9种方式:返回的结果类型为对应的[]interface{}
~~~
sql_id_7_1 := "sql_7_1"
var categories []Category
err := engine.SqlMapClient(sql_id_7_1, 16).Find(&categories)
sql_id_7_2 := "sql_7_2"
var categories []Category
paramMap_7_2 := map[string]interface{}{"id": 25}
err := engine.SqlMapClient(sql_id_7_2, ¶mMap_7_2).Find(&categories)
~~~
### 第10种方式:返回的结果类型为对应的[]interface{}
~~~
//执行的 sql:select * from user where name='xormplus'
sql_key_8_1 := "select.example.stpl" //配置文件名,SqlTemplate的key
var users []User
paramMap_8_1 := map[string]interface{}{"id": 0, "count": 2, "name": "xormplus"}
err := engine.SqlTemplateClient(sql_key_8_1, ¶mMap_8_1).Find(&users)
~~~
### 第11种方式:查询单条数据
使用Sql,SqlMapClient,SqlTemplateClient函数与Get函数组合可以查询单条数据
以Sql与Get函数组合为例:
~~~
//获得单条数据的值,并存为结构体
var article Article
has, err := db.Sql("select * from article where id=?", 2).Get(&article)
//获得单条数据的值并存为map
var valuesMap1 = make(map[string]string)
has, err := db.Sql("select * from article where id=?", 2).Get(&valuesMap1)
var valuesMap2 = make(map[string]interface{})
has, err := db.Sql("select * from article where id=?", 2).Get(&valuesMap2)
var valuesMap3 = make(map[string]xorm.Value)
has, err := db.Sql("select * from article where id=?", 2).Get(&valuesMap3)
//获得单条数据的值并存为xorm.Record
record := make(xorm.Record)
has, err = session.SQL("select * from article where id=?", 2).Get(&record)
id := record["id"].Int64()
content := record["content"].NullString()
//获得单条数据某个字段的值
var title string
has, err := db.Sql("select title from article where id=?", 2).Get(&title)
var id int
has, err := db.Sql("select id from article where id=?", 2).Get(&id)
~~~
### 注:
* 第6种和第9种方式所使用的SqlMap配置文件内容如下
```xml
<sqlMap>
<sql id="sql_4_1">
select * from user
</sql>
<sql id="sql_4_2">
select * from user where id=? and age=?
</sql>
<sql id="sql_4_3">
select * from user where id=?id and name=?name
</sql>
<sql id="sql_id_7_1">
select * from category where id =?
</sql>
<sql id="sql_id_7_2">
select * from category where id =?id
</sql>
</sqlMap>
```
* 第7种和第10种方式所使用的SqlTemplate配置文件内容如下,文件名:select.example.stpl,路径为engine.SqlMap.SqlMapRootDir配置目录下的任意子目录中。使用模板方式配置Sql较为灵活,可以使用pongo2引擎的相关功能灵活组织Sql语句以及动态SQL拼装。
~~~
select * from user
where
{% if count>1%}
id=?id
{% else%}
name=?name
{% endif %}
~~~
* 除以上1种方式外,本库还支持另外3种方式,由于这3种方式支持一次性批量混合CRUD操作,返回多个结果集,且支持多种参数组合形式,内容较多,场景比较复杂,因此不在此处赘述。
* 欲了解另外3种方式相关内容您可移步[批量SQL操作](http://www.kancloud.cn/xormplus/xorm/167121)章节,此3种方式将在此章节单独说明
* 采用Sql(),SqlMapClient(),SqlTemplateClient()方法执行sql调用Find()方法,与ORM方式调用Find()方法不同,此时Find()方法中的参数,即结构体的名字不需要与数据库表的名字映射(因为前面的Sql()方法已经确定了SQL语句),但字段名需要和数据库查询结果集中的字段名字做映射。使用Find()方法需要自己定义查询返回结果集的结构体,如不想自己定义结构体可以使用Query()方法,返回[]map[string]interface{},两种方式请依据实际需要选用。
举例:多表联合查询例子如下
~~~
//执行的SQL如下,查询的是article表与category表,查询的表字段是这两个表的部分字段
sql := `SELECT
article.id,
article.title,
article.isdraft,
article.lastupdatetime,
category.name as categoryname
FROM
article,
category
WHERE
article.categorysubid = category. ID
AND category. ID = 4`
//我们可以定义一个结构体,注意:结构体中的字段名和上面执行的SQL语句字段名映射,字段数据类型正确
//当然你还可以给这个结构体加更多其他字段,但是如果执行上面的SQL语句时,这些其他字段只会被赋值对应数据类型的零值
type CategoryInfo struct {
Id int
Title string
Categoryname string
Isdraft int
Lastupdatetime time.Time
}
var categoryinfo []CategoryInfo
//执行sql,返回值为error对象,同时查询的结果集会被赋值给[]CategoryInfo
//同理,此处也可以使用SqlMapClient(),SqlTemplateClient()函数来获取sql
err = db.Sql(sql).Find(&categoryinfo)
if err != nil {
t.Fatal(err)
}
t.Log(categoryinfo)
t.Log(categoryinfo[0].Categoryname)
t.Log(categoryinfo[0].Id)
t.Log(categoryinfo[0].Title)
t.Log(categoryinfo[0].Isdraft)
t.Log(categoryinfo[0].Lastupdatetime)
~~~
- xorm
- 创建Orm引擎
- 定义表结构体
- 名称映射规则
- 前缀映射,后缀映射和缓存映射
- 使用Table和Tag改变名称映射
- Column属性定义
- 表结构操作
- 获取数据库信息
- 表操作
- 创建索引和唯一索引
- 同步数据库结构
- 导入导出SQL脚本
- SqlMap及SqlTemplate模板
- 初始化SqlMap配置文件及SqlTemplate模板
- SqlMap及SqlTemplate相关功能API
- SqlMap配置文件及SqlTemplate模板加密存储及解析
- 手动管理SqlMap配置及SqlTemplate模板
- 插入数据
- ORM方式插入数据
- 执行SQL命令插入数据
- 创建时间Created
- 查询和统计数据
- ORM方式查询和统计数据
- 查询条件方法
- 临时开关方法
- Get方法
- Find方法
- Join的使用
- Iterate方法
- Count方法
- Rows方法
- Sum系列方法
- Exist方法
- 子查询
- 执行SQL查询
- 执行SQL查询的11种常用方式
- 查询返回json或xml字符串
- 链式查询据操返回某条记录的某个字段的值
- SqlTemplateClient执行过程
- 关于数据库分页查询
- 更新数据
- ORM方式更新数据
- Update方法
- 乐观锁Version
- 更新时间Updated
- 执行SQL命令更新数据
- 删除数据
- ORM方式删除数据
- Delete方法
- 软删除Deleted
- 执行SQL命令删除数据
- 事务处理
- 简单事务模型
- 嵌套事务模型
- 八种事务类型及事务传播机制
- 简单事务相关API
- 嵌套事务相关API
- 嵌套事务示例代码
- 主从数据库(Master/Slave)读写分离
- 创建引擎组
- 负载策略
- 引擎组其他配置方法
- 数据库读写分离
- 批量混合SQL操作
- SQL Builder
- 缓存
- 事件
- 数据导出
- Dump数据库结构和数据
- 查询结果集导出csv、tsv、xml、json、xlsx、yaml、html
- 多Sheet页数据导出
- 日志
- 连接池
- xorm 工具
- 常见问题
- 感谢支持