全部产品
Search
文档中心

云原生多模数据库 Lindorm:基于Go的应用开发

更新时间:Apr 25, 2024

本文介绍使用Go语言的database/sql包和SQL语句在Lindorm宽表应用中进行开发的方法和示例。

前提条件

  • 已安装GO环境,建议安装Go 1.17及以上版本。如何安装,请参见Go

  • 已开通MySQL协议兼容功能。如何开通,请参见开通MySQL协议兼容功能

  • 已将客户端IP添加至白名单,具体操作请参见设置白名单

操作步骤

  1. 在Go项目的go.mod文件中,添加Golang MySQL Driver依赖。

    require github.com/go-sql-driver/mysql v1.7.1
  2. 配置连接参数。

    const ( 
        user = "user"
        password = "test"
        host = "ld-uf6k8yqb741t3****-proxy-sql-lindorm.lindorm.rds.aliyuncs.com"
        port = 33060
        database = "default"
        connectTimeout = "10s"
    )

    参数说明

    参数

    说明

    user

    如果您忘记用户密码,可以通过Lindorm宽表引擎的集群管理系统修改密码。具体操作,请参见修改用户密码

    password

    host

    Lindorm宽表引擎的MySQL兼容地址。如何获取,请参见查看连接地址

    重要
    • 如果应用部署在ECS实例,建议您通过专有网络访问Lindorm实例,可获得更高的安全性和更低的网络延迟。

    • 如果应用部署在本地,在通过公网连接Lindorm实例前,需在控制台开通公网地址。开通方式:在控制台选择数据库连接 > 宽表引擎,在宽表引擎页签单击开通公网地址

    • 通过专有网络访问Lindorm实例,host请填写MySQL兼容地址对应的专有网络地址。通过公网访问Lindorm实例,host请填写MySQL兼容地址对应的公网地址。

    port

    Lindorm宽表引擎MySQL协议的端口,固定为33060。

    database

    需要连接的数据库名称。默认连接default数据库。

    connectTimeout

    数据库连接的超时时间。单位为秒(s)。

  3. 创建连接,通过宽表SQL语法使用Lindorm宽表引擎。以查询所有数据库为例。

    url := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?timeout=%s", user, password, host, port, database, connectTimeout)
    db, err := sql.Open("mysql", url)
    if err != nil {
    	panic(err.Error())
    }
    //设置可打开连接数的最大值,默认值为0,表示不限制。
    db.SetMaxOpenConns(20)
    //设置最大闲置连接数, 默认值为2。
    db.SetMaxIdleConns(20)
    // 设置连接的最大空闲时间,默认值为0,表示不超时。
    db.SetConnMaxIdleTime(8 * time.Minute)
    defer db.Close()
    
    // 获取数据库中所有的database
    {
    	rows, err := db.Query("show databases")
    	if err != nil {
    		panic(err.Error())
    	}
    	for rows.Next() {
    		var dbName string
    		err := rows.Scan(&dbName)
    		if err != nil {
    			panic(err.Error())
    		}
    		fmt.Println(dbName)
    	}
    }

完整示例

完整示例代码如下:

package main
import (
    "database/sql"
    "fmt"
    "time"
    _ "github.com/go-sql-driver/mysql"
)
const (
    //user为Lindorm宽表引擎的用户名
    user = "user"
    //password为Lindorm宽表引擎的密码
    password = "test"
    //host为Lindorm宽表引擎的MySQL兼容地址
    host = "ld-uf6k8yqb741t3****-proxy-sql-lindorm-public.lindorm.rds.aliyuncs.com"
    //Lindorm宽表引擎MySQL协议的端口,固定为33060
    port = 33060
    //database为需要连接的数据库名称
    database = "default"
    //数据库连接的超时时间
    connectTimeout = "10s"
)
func main() {
	//打开数据库连接
	url := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?timeout=%s", user, password, host, port, database, connectTimeout)
	db, err := sql.Open("mysql", url)
	if err != nil {
		panic(err.Error())
	}
	//设置可打开连接数的最大值,默认值为0,表示不限制
	db.SetMaxOpenConns(20)
	//设置最大闲置连接数, 默认值为2
	db.SetMaxIdleConns(20)
	//设置连接的最大空闲时间,默认值为0,表示不超时
	db.SetConnMaxIdleTime(8 * time.Minute)
	defer db.Close()

	//获取数据库中所有的database
	{
		rows, err := db.Query("show databases")
		if err != nil {
			panic(err.Error())
		}
		for rows.Next() {
			var dbName string
			err := rows.Scan(&dbName)
			if err != nil {
				panic(err.Error())
			}
			fmt.Println(dbName)
		}
	}

	//创建表
	{
		_, err := db.Exec("create table if not exists user_test(id int, name varchar,age int, primary key(id))")
		if err != nil {
			fmt.Println("create table error ", err)
			return
		}
	}

	//写入数据

	//写入方法一:直接写入数据。
	{
		_, err = db.Exec("upsert into user_test(id,name,age) values(1,'zhangsan',17)")
		if err != nil {
			fmt.Println("insert data error", err)
			return
		}
	}

	//写入方法二:通过绑定参数的方式进行写入数据。
	{
		stmt, err := db.Prepare("upsert into user_test(id,name,age) values(?,?,?)")
		if err != nil {
			fmt.Println("prepare error", err)
			return
		}
		_, err = stmt.Exec(2, "lisi", 18)
		if err != nil {
			fmt.Println("upsert error", err)
			return
		}
	}

	//查询数据

	//查询方法一:直接查询数据。

	{
		rows, err := db.Query("select * from user_test")
		if err != nil {
			fmt.Println("query data error", err)
			return
		}
		defer rows.Close()
		var id int
		var name string
		var age int
		for rows.Next() {
			err = rows.Scan(&id, &name, &age)
			if err != nil {
				fmt.Println("scan data error", err)
				return
			}
			fmt.Println("id:", id, "name:", name, "age:", age)
		}
	}

	// 查询方法二:通过绑定参数的方式执行参数化查询。
	{
		stmt, err := db.Prepare("select * from user_test where id=?")
		if err != nil {
			fmt.Println("prepare error", err)
			return
		}
		rows, err := stmt.Query(1)
		if err != nil {
			fmt.Println("query data error", err)
			return
		}
		defer rows.Close()
		var id int
		var name string
		var age int
		for rows.Next() {
			err = rows.Scan(&id, &name, &age)
			if err != nil {
				fmt.Println("scan data error", err)
				return
			}
			fmt.Println("id:", id, "name:", name, "age:", age)
		}
	}

	//删除数据
	{
		_, err = db.Exec("delete from user_test where id=1")
		if err != nil {
			fmt.Println("delete data error", err)
			return
		}
	}
}

如果当前实例仅有default一个数据库,执行成功后将返回如下结果:

default
information_schema
id: 1 name: zhangsan age: 17
id: 2 name: lisi age: 18