文件最后提交记录最后更新时间
3 年前
3 年前
3 年前
3 年前
3 年前
3 年前
README.md

RDS for MySQL

MySQL是目前最受欢迎的开源数据库之一,其性能卓越,成为WEB开发的高效解决方案。 云数据库 RDS for MySQL拥有稳定可靠、安全运行、弹性伸缩、轻松管理、经济实用等特点。

  • 架构成熟稳定,支持流行应用程序,适用于多领域多行业;支持各种WEB应用,成本低,中小企业首选。
  • 管理控制台提供全面的监控信息,简单易用,灵活管理,可视又可控。
  • 随时根据业务情况弹性伸缩所需资源,按需开支,量身订做。

环境准备

本节内容将为您演示如何使用以 Go 语言编写的代码连接到 RDS for MySQL。 同时还介绍了在数据库中查询、插入、更新和删除数据。

项目地址:MySQL samples

环境软件

配置步骤

Go

Go环境配置

Goland

IDE安装

RDS for MySQL

购买RDS for MySQL实例

代码连接

  1. 购买RDS for MySQL实例后,可通过三种连接方式连接实例,你可根据需要选择。Go代码连接方式如下:

    //连接mysql
    func InitDB() (err error) {
    	// DSN:Data Source Name
    	dsn, err := getDSN()
    	if err != nil {
    		return
    	}
    	Db, err = sql.Open("mysql", dsn)
    	if err != nil {
    		return errors.Wrap(err, "ERR: fail to open mysql")
    	}
    	// 尝试与数据库建立连接(校验数据源是否正确)
    	err = Db.Ping()
    	if err != nil {
    		return errors.Wrap(err, "ERR: fail to connect db")
    	}
    	Db.SetMaxOpenConns(10)
    	Db.SetMaxIdleConns(2)
    	return
    }
    
  2. 云数据库参数保存在yaml文件中,关键代码如下:

    //获取配置参数
    func getDSN() (dsn string, err error) {
    	config, err := GetConfig()
    	if err != nil {
    		return
    	}
    	root := config.Name
    	password := config.Password
    	host := config.Host
    	port := config.Port
    	database := config.Database
    	dsn = fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8mb4&parseTime=True&loc=Local", root, password, host, port, database)
    	return
    }
    
    

    字段说明,如下:

    host:数据库IP或者域名(推荐使用内网)

    port:数据库实例映射端口,默认3306

    database:数据库名

    root:数据库用户名

    password:数据库密码

基础操作

  1. 插入数据

    func insertRowDemo(db *sql.DB) error {
    	sqlStr := "insert into animals(name, age) values (?,?)"
    	_, err := db.Exec(sqlStr, "老虎", 3)
    	if err != nil {
    		return errors.Wrap(err, "ERR: fail to insertRow")
    	}
    	return nil
    }
    
  2. 更新数据

    //更新数据
    func updateRowDemo(db *sql.DB) error {
    	sqlStr := "update animals set age=? where id = ?"
    	ret, err := db.Exec(sqlStr, 39, 1)
    	if err != nil {
    		return errors.Wrap(err, "ERR: fail to updateRow")
    	}
    	n, err := ret.RowsAffected() // 操作影响的行数
    	if err != nil {
    		return errors.Wrap(err, "ERR: fail to get rows")
    	}
    	fmt.Printf("update success, affected rows:%d\n", n)
    	return nil
    }
    
  3. 删除数据

    // 删除数据
    func deleteRowDemo(db *sql.DB) error {
    	sqlStr := "delete from animals where id = ?"
    	ret, err := db.Exec(sqlStr, 3)
    	if err != nil {
    		return errors.Wrap(err, "ERR: fail to deleteRow")
    	}
    	n, err := ret.RowsAffected() // 操作影响的行数
    	if err != nil {
    		return errors.Wrap(err, "ERR: fail to get rows")
    	}
    	fmt.Printf("delete success, affected rows:%d\n", n)
    	return nil
    }
    
  4. 查询数据

    // 查询多条数据示例
    func queryMultiRowDemo(db *sql.DB) error {
    	sqlStr := "select id, name, age from animals where id > ?"
    	rows, err := db.Query(sqlStr, 0)
    	if err != nil {
    		return errors.Wrap(err, "ERR: fail to queryRow")
    	}
    	// 非常重要:关闭rows释放持有的数据库链接
    	defer rows.Close()
    
    	// 循环读取结果集中的数据
    	for rows.Next() {
    		var u animals
    		err := rows.Scan(&u.id, &u.name, &u.age)
    		if err != nil {
    			return errors.Wrap(err, "ERR: fail to scan row")
    		}
    		fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age)
    	}
    	return nil
    }
    

常见问题

mysql预处理

对于一般的sql语句的执行过程,一般流程是这样的:

  1. 客户端对SQL语句中的占位符进行替换得到最终SQL语句。
  2. 然后送把这个SQL语句发送到MySQL服务端
  3. MySQL服务端执行SQL语句把结果返回给客户端

而对于预处理进行的执行过程,流程是这样的:

  1. 先将SQL语句分成命令部分与数据部分。
  2. 然后先把命令部分发送给MySQL服务端,MySQL服务端进行SQL预处理。
  3. 最后把数据部分发送给MySQL服务端,MySQL服务端对SQL语句的占位符进行替换。
  4. MySQL服务端执行完整的SQL语句并将结果返回给客户端。

预处理优点:能优化重复执行的sql,提升服务器性能。避免SQL注入。

GO实现预处理示例代码

// 预处理查询示例
func prepareDemo() {
	sqlStr := "select id, name, age from user where id > ?"
        //预处理方法
	stmt, err := db.Prepare(sqlStr)
	if err != nil {
		return errors.Wrap(err, "ERR: fail to prepare")
		return
	}
	defer stmt.Close()
	rows, err := stmt.Query(0)
	if err != nil {
		return errors.Wrap(err, "ERR: fail to query")
	}
	defer rows.Close()
	// 循环读取结果集中的数据
	for rows.Next() {
		var anim animals
		err := rows.Scan(&anim.id, &anim.name, &anim.age)
		if err != nil {
			return errors.Wrap(err, "ERR: fail to scan")
		}
		fmt.Printf("id:%d name:%s age:%d\n", anim.id, anim.name, anim.age)
	}
}

常用ORM框架

GO连接MySQL数据库还可使用ORM框架,通常采用GORM框架,使用文档参考GORM官方文档,具体项目参考Go入门Web项目