1. 程式人生 > 其它 >go 上傳檔案到阿里雲oss

go 上傳檔案到阿里雲oss

go 上傳檔案到阿里雲oss

1 背景

  • 在實訓期間,做了一個前後分離的微信小程式:美容院,在首頁請求圖片的時候,最開始設計的時候是從後端請求拿到圖片的集合,而圖片的url 表示的是伺服器的相對地址,我想的是,將圖片上傳到阿里雲oss,然後將oss連結直接存入圖片url,這樣在前端頁面就可以直接展示

  • 資料庫表:

    CREATE TABLE `image` (
      `id` BIGINT(11) NOT NULL AUTO_INCREMENT COMMENT '圖片id',
      `imageurl` VARCHAR(100) DEFAULT NULL COMMENT '圖片路徑',
      `imagetitle` VARCHAR(50) DEFAULT NULL COMMENT '圖片標題',
      `imagetype` VARCHAR(50) DEFAULT NULL COMMENT '圖片型別 banner:首頁輪播圖 nav:選單 head:頭像',
      `imagestate` VARCHAR(10) DEFAULT NULL COMMENT '圖片狀態  1:可用  0:不可用',
      PRIMARY KEY (`id`)
    ) ENGINE=INNODB AUTO_INCREMENT=61 DEFAULT CHARSET=utf8;
    
    
    INSERT INTO `image` VALUES (1, 'banner_01.png', 'banner', 'banner', '1');
    INSERT INTO `image` VALUES (2, 'banner_02.png', 'banner', 'banner', '1');
    INSERT INTO `image` VALUES (3, 'banner_03.png', 'banner', 'banner', '1');
    INSERT INTO `image` VALUES (4, 'banner_04.png', 'banner', 'banner', '1');
    INSERT INTO `image` VALUES (5, 'nav_icon_01.png', '推薦', 'nav', '1');
    INSERT INTO `image` VALUES (6, 'nav_icon_02.png', '美甲', 'nav', '1');
    INSERT INTO `image` VALUES (7, 'nav_icon_03.png', '美容', 'nav', '1');
    INSERT INTO `image` VALUES (8, 'nav_icon_04.png', '美髮', 'nav', '1');
    INSERT INTO `image` VALUES (9, 'nav_icon_05.png', '睫毛', 'nav', '1');
    INSERT INTO `image` VALUES (10, 'b1.png', '千峰美容美髮商家', 'bus', '1');
    INSERT INTO `image` VALUES (11, 'p1.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (12, 'p2.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (13, 'p3.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (14, 'p4.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (15, 'p5.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (16, 'p6.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (17, 'p7.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (18, 'p8.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (19, 'p9.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (20, 'p10.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (21, 'p11.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (22, 'p12.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (23, 'p13.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (24, 'p14.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (25, 'p15.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (26, 'p16.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (27, 'p17.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (28, 'p18.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (29, 'p19.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (30, 'p20.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (31, 'p21.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (32, 'p22.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (33, 'p23.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (34, 'p24.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (35, 'p25.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (36, 'p26.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (37, 'p27.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (38, 'p28.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (39, 'p29.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (40, 'p30.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (41, 'p41.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (42, 'p42.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (43, 'p43.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (44, 'p44.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (45, 'p45.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (46, 'p46.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (47, 'p47.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (48, 'p48.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (49, 'p49.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (50, 'p50.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (51, 'p51.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (52, 'p52.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (53, 'p53.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (54, 'p54.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (55, 'p55.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (56, 'p56.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (57, 'p57.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (58, 'p58.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (59, 'p59.png', '產品', 'pro', '1');
    INSERT INTO `image` VALUES (60, 'p60.png', '產品', 'pro', '1');
    
  • 本地 img 檔案 [壓縮包](連結: https://pan.baidu.com/s/1xxGk6gxmAiC3nQTgO_s2VQ?pwd=gsnp 提取碼: gsnp 複製這段內容後開啟百度網盤手機App,操作更方便哦)

2 實施

2.1 新建一個專案,安裝 SDK

go get github.com/aliyun/aliyun-oss-go-sdk/oss		# oss 依賴
go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite		# 剛學,這個是幹嘛的不知道
go get -u github.com/go-sql-driver/mysql	 # mysql 依賴

2.2 去阿里雲oss 幫助文件 copy 一個demo

package main
import (
  "fmt"
  "os"
  "github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func handleError(err error) {
  fmt.Println("Error:", err)
  os.Exit(-1)
}
func main() {
  // Endpoint以杭州為例,其它Region請按實際情況填寫。
  endpoint := "http://oss-cn-hangzhou.aliyuncs.com"
  // 阿里雲賬號AccessKey擁有所有API的訪問許可權,風險很高。強烈建議您建立並使用RAM使用者進行API訪問或日常運維,請登入RAM控制檯建立RAM使用者。
  accessKeyId := "<yourAccessKeyId>"
  accessKeySecret := "<yourAccessKeySecret>"
  bucketName := "<yourBucketName>"
  // <yourObjectName>上傳檔案到OSS時需要指定包含檔案字尾在內的完整路徑,例如abc/efg/123.jpg。
  objectName := "<yourObjectName>"
  // <yourLocalFileName>由本地檔案路徑加檔名包括字尾組成,例如/users/local/myfile.txt。
  localFileName := "<yourLocalFileName>"
  // 建立OSSClient例項。
  client, err := oss.New(endpoint, accessKeyId, accessKeySecret)
  if err != nil {
    handleError(err)
  }
  // 獲取儲存空間。
  bucket, err := client.Bucket(bucketName)
  if err != nil {
    handleError(err)
  }
  // 上傳檔案。
  err = bucket.PutObjectFromFile(objectName, localFileName)
  if err != nil {
    handleError(err)
  }
}

2.3 思路

  • 先填好自己oss 的配置
  • 從本地檔案讀取img 資料夾下面所有的檔案
  • 遍歷檔案,上傳檔案到oss, 路徑為 currentDate/go/fileName
  • 更新資料庫,將 imageurl 為檔名的記錄的 imageurl欄位改為 oss 提供的路徑

2.4 編碼

    • 初始化 database

      func Init() *gorm.DB {
        // 參考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 獲取詳情
        dsn := "root:paswd@tcp(localhost:3306)/shixun_mr?charset=utf8mb4&parseTime=True&loc=Local"
        db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
          Logger: logger.Default.LogMode(logger.Info),
        })
        if err != nil {
          fmt.Printf("err.Error(): %v \n", err.Error())
        }
        return db
      }
      
    • main 方法

      package main
      
      import (
        "fmt"
        "github.com/aliyun/aliyun-oss-go-sdk/oss"
        "gorm.io/gorm"
        "io/ioutil"
        "os"
        "oss/databases"
        "time"
      )
      
      type Image struct {
        Id                                          int
        Imageurl, Imagetitle, Imagetype, Imagestate string
      }
      
      func handleError(err error) {
        fmt.Println("Error:", err)
        os.Exit(-1)
      }
      
      var DB *gorm.DB
      
      func main() {
        // Endpoint以杭州為例,其它Region請按實際情況填寫。
        endpoint := "http://oss-cn-hangzhou.aliyuncs.com"
        // 阿里雲賬號AccessKey擁有所有API的訪問許可權,風險很高。強烈建議您建立並使用RAM使用者進行API訪問或日常運維,請登入RAM控制檯建立RAM使用者。
        accessKeyId := "<yourAccessKeyId>"
        accessKeySecret := "<yourAccessKeySecret>"
        bucketName := "<yourBucketName>"
        // <yourObjectName>上傳檔案到OSS時需要指定包含檔案字尾在內的完整路徑,例如abc/efg/123.jpg。
        //objectName := time.Now().Format("2006-01-02") + "/go/banner_01.png"
        var objectName string
      
      
        // 建立OSSClient例項。
        client, err := oss.New(endpoint, accessKeyId, accessKeySecret)
        if err != nil {
          handleError(err)
        }
        // 獲取儲存空間。
        bucket, err := client.Bucket(bucketName)
        if err != nil {
          handleError(err)
        }
        // 上傳檔案。
        DB = databases.Init()
        files, _ := ioutil.ReadDir("/Users/jalivv/Downloads/實訓/微信筆記/img")
        for _, f := range files {
          objectName = time.Now().Format("2006-01-02") + "/go/" + f.Name()
          // <yourLocalFileName>由本地檔案路徑加檔名包括字尾組成,例如/users/local/myfile.txt。
          localFileName := "/Users/jalivv/Downloads/實訓/微信筆記/img/" + objectName
          // 上傳到oss 阿里雲
          err = bucket.PutObjectFromFile(objectName, localFileName)
          if err != nil {
            handleError(err)
          }
      
          // 更改資料庫
          //   https://meirong-jalivv.oss-cn-shanghai.aliyuncs.com/
      
          // 官網 copy :
          //db.Model(&user).Update("name", "hello")
          // UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE imageurl=??;
          urlPrefix := "https://<yourBucketName>.oss-cn-shanghai.aliyuncs.com/"
          img := Image{Imageurl: f.Name()}
          DB.Debug().Table("image").Model(&img).Where("imageurl=?", f.Name()).Update("imageurl", urlPrefix+objectName)
        }
      
      }
      
      

2.5 效果