在这篇文章《ShardingSphereProxy:快速入门》中,我们介绍了如何通过 Navicat 连接 ShardingSphere-Proxy。
实际上,ShardingSphere-Proxy 兼容标准的 SQL 和原生数据库协议,因此你可以使用任何 MySQL 客户端与其进行连接,包括 Golang 的原生 SQL 库和流行的 ORM 框架 GORM。
接下来,我们将展示如何使用 Golang 原生 SQL 和 GORM 连接并操作 ShardingSphere-Proxy。
使用 Golang 原生 SQL 连接 ShardingSphere-Proxy
话不多少,我们直接上示例。
基于我们的测试实例。
由于 Proxy 运行在 Docker 容器上,并且暴露了端口 13308,使用以下连接信息:
主机:localhost 或 Docker 容器的 IP 地址
端口:13308
用户名:root 或 sharding(根据我们在 global.yaml 中的配置)
密码:对应的密码
以下是使用 Golang 原生 SQL 连接 ShardingSphere-Proxy 的示例代码:
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
)
func main() {
// ShardingSphere Proxy的连接字符串
dsn := "sharding:sharding@tcp(localhost:13308)/sharding"
// 打开数据库连接
db, err := sql.Open("mysql", dsn)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 验证连接
err = db.Ping()
if err != nil {
log.Fatal(err)
}
fmt.Println("Successfully connected to ShardingSphere Proxy!")
// 执行查询(示例)
rows, err := db.Query("SELECT * FROM orders LIMIT 10")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
// 处理查询结果
for rows.Next() {
var column1 int64
var column2 string
var column3 int
var column4 int
var column5 string
// 根据你的表结构调整字段类型和数量
err := rows.Scan(&column1, &column2, &column3, &column4, &column5)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Column1: %s, Column2: %d\n", column1, column2)
}
// 检查是否有错误发生
if err = rows.Err(); err != nil {
log.Fatal(err)
}
}
使用 GORM 连接并操作 ShardingSphere-Proxy
GORM 是一个流行的 Golang ORM 框架,它使得数据库操作更加简洁和高效。以下是如何使用 GORM 连接 ShardingSphere-Proxy 并进行基本操作的示例:
package main
import (
"fmt"
"math/rand"
"time"
"github.com/bwmarrin/snowflake"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var globalDB *gorm.DB
type Order struct {
ID int64 `gorm:"primaryKey"`
OrderId string `gorm:"sharding:order_id"` // 指明 OrderId 是分片键
UserID int64 `gorm:"sharding:user_id"`
ProductID int64
OrderDate int64
}
type Product struct {
ID int64 `gorm:"primaryKey"`
Name string `gorm:"name"`
}
// 定义结构体,用于接收查询结果
type OrderGroup struct {
ID int64 `gorm:"primaryKey"`
OrderId string `gorm:"sharding:order_id"` // 指明 OrderId 是分片键
UserID int64 `gorm:"sharding:user_id"`
ProductID int64
OrderDate int64
SumProduct int64
MaxProduct int64
}
type OrderProduct struct {
Order
Product
}
type User struct {
ID int64 `gorm:"primaryKey"`
Name string `gorm:"name"`
}
type OrderUser struct {
Order
User
}
func main() {
InitDb()
// 示例:插入订单数据
InsertRandomOrders()
// 场景1:全表查询,不含分表键
FindAllOrders()
}
// 随机生成一些订单数据插入
func InsertRandomOrders() {
node, err := snowflake.NewNode(1)
if err != nil {
fmt.Println("Error creating snowflake node:", err)
return
}
now := time.Now()
for i := 0; i < 10; i++ {
// 雪花id生成
// 生成一个ID
id := node.Generate()
order := Order{
ID: id.Int64(),
OrderId: fmt.Sprintf("20240101ORDER%04d", rand.Int31n(10000)),
UserID: int64(rand.Int31n(10000)),
ProductID: int64(rand.Int31n(1000)),
OrderDate: now.Unix(),
}
InsertOrder(order)
}
// orderDate 用2025年,拼接当前月,日,时,分秒
orderDate := time.Date(2025, now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.UTC)
for i := 0; i < 10; i++ {
id := node.Generate()
order := Order{
ID: id.Int64(),
OrderId: fmt.Sprintf("20250101ORDER%04d", rand.Int31n(10000)),
UserID: int64(rand.Int31n(10000)),
ProductID: int64(rand.Int31n(1000)),
OrderDate: orderDate.Unix(),
}
InsertOrder(order)
}
}
// 插入订单数据
func InsertOrder(order Order) error {
err := globalDB.Create(&order).Error
if err != nil {
fmt.Println("Error creating order:", err)
}
return nil
}
// 场景1:全表查询,不含分表键
func FindAllOrders() ([]Order, error) {
var orders []Order
err := globalDB.Table("orders").Find(&orders).Error
if err != nil {
fmt.Println("Error finding orders:", err)
return nil, err
}
fmt.Println("场景1:全表查询,不含分表键 orders:", orders)
return orders, err
}
// InitDb 初始化数据库连接
func InitDb() *gorm.DB {
log := logger.Default.LogMode(logger.Info)
// 连接到 MySQL 数据库
dsn := "sharding:sharding@tcp(localhost:13308)/sharding"
db, err := gorm.Open(mysql.New(mysql.Config{
DSN: dsn,
}), &gorm.Config{
Logger: log,
})
if err != nil {
panic("failed to connect database")
}
globalDB = db
return db
}
通过这两个示例,你可以看到使用 Golang 原生 SQL 和 GORM 连接并操作 ShardingSphere-Proxy 是非常简单和直观的。ShardingSphere-Proxy 的透明分片特性使得你可以像操作单个数据库一样操作分布式数据库集群,从而大大简化了分库分表带来的复杂性。