Golang 获取MySQL表元信息

Golang 获取MySQL表元信息

本文介绍Golang如何操作数据库,并通过获取Mysql表元信息进行实例演示。

1. Golang 操作DBMS

Golang 通过标准database/sql包实现了对关系型数据库很好的支持,如MySQL, MS SQL Server, Oracle 和 Postgres,当然NoSql也没有问题,如MongoDB、Redis。

使用Golang标准库可以很容易与Mysql交互,其他数据库也一样,可以参加Golang数据库驱动列表

SQL标准库提供通用接口及常用方法用于访问或操作数据库。数据库包包括连接池,正确使用可确保线程安全。数据库包必须和具体数据库驱动包一起使用。

2. 连接Mysql

连接Mysql需要使用标准SQL包和Mysql驱动,Mysql驱动包实现标准包方法和接口。一般实现SQl标准包通常通过标准包暴露驱动接口,入口点代码在SQL驱动的Go文件。

SQL包是存在于Go标准库中的标准SQL包。因为init()函数是在任何其他函数之前执行的,所以可以肯定的是,只要在代码中包含了MySQL包,则Mysql驱动会被自动注册并通过标准SQL包调用。

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
)

这里下划线_表示载入包但不直接使用,我们通过标准SQL包使用。没有下划线,编译器会提示导入没有使用错误。

加载包的动作即使是静态方式,但包中的init()方法仍会执行,初始化方法会注册Mysql驱动给标准包,从而使用对标准包的方法调用转为对具体Mysql实现的方法调用。

为了数据库处理对象可以重用,定义全局数据库处理指针:

var db *sql.DB

与数据库交互的第一个函数是sql.Open(),获取数据库对象,用于执行查询和命令。第一个参数指定数据库驱动,这里是mysql。第二个参数是连接字符串。

db, err = sql.Open("mysql", "root:pass123@/sakila?charset=utf8&parseTime=true")

sql.Open()函数返回数据库连接处理器,用于对数据库执行查询和命令。同时返回错误对象,没有错误则为nil。
连接字符串包括用户名和密码,这里还指定字符集和解析时间类型,完整内容请参考官网

在init方法中调用Open方法:

func init()  {
	db, err = sql.Open("mysql", "root:a123@/sakila?charset=utf8&parseTime=true")
	checkErr(err)
}

检查错误方法:

func checkErr(err error) {
	if err != nil {
		panic(err)
	}
}

3. 获取Mysql数据库元信息

获取元信息主要包括获取数据库中表信息以及表的字段信息。从INFORMATION_SCHEMA.TABLES表中查询表信息:

SELECT table_name name,IFNULL(TABLE_COMMENT,table_name) value
 FROM INFORMATION_SCHEMA.TABLES 
WHERE UPPER(table_type)='BASE TABLE'
AND LOWER(table_schema) = 'sakila' 
ORDER BY table_name asc;

获取表字段信息,从information_schema.columns表查询字段信息:

SELECT COLUMN_NAME fName,column_comment fDesc,DATA_TYPE dataType,
       IS_NULLABLE isNull,IFNULL(CHARACTER_MAXIMUM_LENGTH,0) sLength
FROM information_schema.columns 
WHERE table_schema = 'sakila' AND table_name = 'actor';  

3.1. 查询数据库表信息

使用?作为参数占位符,db.Query()执行查询,参数为SQL字符串和数据库名。

func TableInfo(dbName string) map[string]string  {
	sqlStr := `SELECT table_name tableName,TABLE_COMMENT tableDesc
			FROM INFORMATION_SCHEMA.TABLES 
			WHERE UPPER(table_type)='BASE TABLE'
			AND LOWER(table_schema) = ? 
			ORDER BY table_name asc`

	var result = make(map[string]string)

	rows, err := db.Query(sqlStr,dbName)
	checkErr(err)

	for rows.Next() {
		var tableName,tableDesc string
		err = rows.Scan(&tableName, &tableDesc)
		checkErr(err)

		if len(tableDesc) == 0 {
			tableDesc = tableName
		}
		result[tableName] = tableDesc
	}
	return result
}

遍历查询结果,数据库名称和注释信息作为键值对存储在Map中。

3.2. 查询表字段信息

定义FieldInfo函数,参数为数据库名和表名,返回Field类型切片,我们首先看Field结构体:

type Field struct {
	fieldName string
	fieldDesc string
	dataType  string
	isNull    string
	length    int
}

查询字段函数FieldInfo():

func FieldInfo(dbName,tableName string) [] Field{
	sqlStr := `SELECT COLUMN_NAME fName,column_comment fDesc,DATA_TYPE dataType,
						IS_NULLABLE isNull,IFNULL(CHARACTER_MAXIMUM_LENGTH,0) sLength
			FROM information_schema.columns 
			WHERE table_schema = ? AND table_name = ?`


	var result [] Field
	
	rows, err := db.Query(sqlStr,dbName,tableName)
	checkErr(err)

	for rows.Next() {
		var f Field
		err = rows.Scan(&f.fieldName, &f.fieldDesc, &f.dataType, &f.isNull, &f.length)
		checkErr(err)

		result = append(result, f)
	}
	return result
}

3.3. 测试

下面在main函数中进行测试:

func main() {
	defer db.Close()

	tableInfo := TableInfo("sakila")
	fmt.Println(tableInfo)

	filedInfo := FieldInfo("sakila","actor")

	for _,item := range filedInfo {
		fmt.Println(item)
	}
}

defer db.Close()语句确保执行完毕后关闭数据库连接。

4. 总结

本文介绍了标准database/sql包及Mysql驱动,最后通过获取Mysql表元信息示例说明如何执行数据库操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章