Golang仿云盘项目-3.2云存储系统之持久化

本文来自博客园,作者:Arway,转载请注明原文链接:https://www.cnblogs.com/cenjw/p/16478717.html

项目结构

.
├── db
│   ├── file.go
│   └── mysql
│       └── conn.go
├── doc
│   └── 建表语句.sql
├── go.mod
├── go.sum
├── handler
│   └── handler.go
├── main.go
├── meta
│   └── filemeta.go
├── static
│   └── view
│       └── index.html
└── util
    └── util.go

创建表

create database fileserver;
use fileserver;
CREATE TABLE tbl_file (
    id int(11) NOT NULL AUTO_INCREMENT,
    file_sha1 char(40) NOT NULL DEFAULT '' COMMENT '文件hash',
    file_name varchar(256) NOT NULL DEFAULT '' COMMENT '文件名',
    file_size bigint(20) DEFAULT '0' COMMENT '文件大小',
    file_addr varchar(1024) NOT NULL DEFAULT '' COMMENT '文件存储位置',
    create_at datetime DEFAULT NOW() COMMENT '创建日期',
    update_at datetime DEFAULT NOW() on update current_timestamp() COMMENT '更新日期',
    status int(11) NOT NULL DEFAULT '0' COMMENT '状态(可用|禁用|已删除等状态)',
    ext1 int(11) DEFAULT '0' COMMENT '备用字段1',
    ext2 text COMMENT '备用字段2',
    PRIMARY KEY (id),
    UNIQUE KEY idx_file_hash (file_sha1),
    KEY idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

连接mysql

db/mysql/conn.go

点击查看代码

package mysql

import (
    "database/sql"
    "log"

    _ "github.com/go-sql-driver/mysql"  // 导入mysql驱动
)

// 声明mysql连接对象
var db *sql.DB

func init() {
    db, _ = sql.Open("mysql", "root:123456@tcp(127.0.0.1:3307)/fileserver?charset=utf8")
    db.SetConnMaxIdleTime(1000)
    err := db.Ping()  // test connection
    if err != nil {
        log.Fatal("Failed to connect to mysql, err: " + err.Error())
    }
}

// DBConn返回数据库连接对象
func DBConn() *sql.DB {
    return db
}

文件上传完后,保存文件元信息到mysql

db/file.go

点击查看代码

// OnFileUploadOK: 文件上传完成,保存meta到数据库
func OnFileUploadOK(fsha1, filename, fileaddr string, filesize int64) bool {
    stmt, err := mydb.DBConn().Prepare(
        "insert ignore into tbll_file(file_sha1, file_name, file_size, " +
            "file_addr, status)values(?,?,?,?,1)")
    if err != nil {
        fmt.Println("Failed to prepare statement, err: " + err.Error())
        return false
    }

    defer stmt.Close()

    ret, err := stmt.Exec(fsha1, filename, filesize, fileaddr)
    if err != nil {
        fmt.Println(err.Error())
        return false
    }

    // 判断是否已经插入过相同fsha1的记录, 插入相同的会直接忽略
    if rf, err := ret.RowsAffected(); nil == err {
        if rf

Golang仿云盘项目-3.2云存储系统之持久化

修改新增/更新文件元信息接口

meta/filemeta.go

// UpdateFileMetaDB: 新增/更新文件元信息到数据库
func UpdateFileMetaToDB(fm FileMeta) bool {
    return mydb.OnFileUploadOK(fm.FileSha1, fm.FileName, fm.Location, fm.FileSize)
}

handler/handler.go

// UploadHandler: 文件上传接口
func UploadHandler(w http.ResponseWriter, r *http.Request) {
    ...
    else if r.Method == "POST" {
        ...
        // meta.UpdateFileMeta(fileMeta)
        // 持久化到数据库
        _ = meta.UpdateFileMetaToDB(fileMeta)
        ...

修改文件元信息查询接口

db/file.go

点击查看代码

func GetFileMeta(fhash string) (*TableFile, error) {
    stmt, err := mydb.DBConn().Prepare(
        "SELECT file_sha1, file_name, file_addr, file_size "+
        "FROM tbll_file where file_sha1=? limit 1")
    if err != nil {
        fmt.Println(err.Error())
        return nil, err
    }
    defer stmt.Close()

    tf := TableFile{}
    // Scan可以把数据库取出的字段值赋值给指定的数据结构
    err = stmt.QueryRow(fhash).Scan(&tf.FileSha1, &tf.FileName, &tf.FileAddr, &tf.FileSize)
    if err != nil {
        fmt.Println(err.Error())
        return nil, err
    }

    return &tf, nil
}

<br></code>meta/filemeta.go

// GetFileMetaDB:从mysql获取元信息
func GetFileMetaFromDB(fhash string) (FileMeta, error) {
    tf, err := mydb.GetFileMeta(fhash)
    if err != nil {
        return FileMeta{}, err
    }

    fm := FileMeta{
        FileSha1: tf.FileSha1,
        FileName: tf.FileName.String,
        Location: tf.FileAddr.String,
        FileSize: tf.FileSize.Int64,
    }
    return fm, nil
}

handler/handler.go

// GetFileMetaHandler:通过文件sha1值获取文件元信息的接口
func GetFileMetaHandler(w http.ResponseWriter, r *http.Request) {
    ...
    // fm := meta.GetFileMeta(fh)
    fm, err := meta.GetFileMetaFromDB(fh)
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
    }
    ...

测试:
http://localhost:8080/file/meta?filehash=1ce11ed4a3f0ebae4d78e0b66faf32ecc2c82ea7

Original: https://www.cnblogs.com/cenjw/p/16478717.html
Author: micromatrix
Title: Golang仿云盘项目-3.2云存储系统之持久化

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/712528/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【新特性速递】左侧选项卡不再费脖子了

    FineUI 的下个版本(v8.0.0),我们会为选项卡新增 TabTitleVertical 属性,一般用于在左侧或者右侧显示中文选项卡标题,这样就不会再费脖子了。 网友贡献代码…

    技术杂谈 2023年6月1日
    0117
  • 2021最新搜索引擎蜘蛛名称UA(user-agent)集合

    搜索引擎对一个网站很重要,是很多网站重要的流量来源。熟悉各大搜索引擎的蜘蛛就显得必要呢。蜘蛛爬得勤快,网页收录也快。通过分析网站访问日志:查看访问者的user-agent,我们也可…

    技术杂谈 2023年5月31日
    073
  • go 单元测试testify

    testify用go实现的一个assert风格的测试框架,这个包提供了我们需要的断言的功能,提供了非常丰富的断言方法。 提供了测试suite、断言、mock三种功能。 官方文档:h…

    技术杂谈 2023年5月31日
    082
  • 整合redis并完成短信验证服务

    添加依赖 com.tencentcloudapi tencentcloud-sdk-java 3.1.509 org.springframework.boot spring-boo…

    技术杂谈 2023年7月25日
    094
  • kubernetes网络模型

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    技术杂谈 2023年7月24日
    067
  • NoteOfMySQL-07-索引

    1. 索引概述 创建索引的目的是为了优化数据库的查询速度,不添加索引的情况下需要遍历所有数据才能进行删、查、改等操作。 2. 索引存储类型 存储类型 支持的存储引擎 B型树(BTR…

    技术杂谈 2023年7月11日
    058
  • a-form-model的简单例子

    html;gutter:true; 请选择</p> <pre><code> {{ item.text }} 提交 </code>&l…

    技术杂谈 2023年5月31日
    078
  • pip3安装库时报超时问题小结

    在Linux测试服务器上使用pip3安装组件时,遇到下面错误: 查了一下相关资料弄清楚了这个错误出现的原因:一般出现这个错误跟本地网络状况或配置有关。一般而言,你可能默认使用了国外…

    技术杂谈 2023年5月31日
    089
  • 为什么 C# 访问 null 字段会抛异常?

    一:背景 1. 一个有趣的话题 最近在看 &#x786C;&#x4EF6;&#x5F02;&#x5E38; 相关知识,发现一个有意思的空引用异常问题…

    技术杂谈 2023年5月31日
    0104
  • qt中出现error:C2059:语法错误:“namespace”未定义等大量错误的问题

    昨天下载了一个github上的qt工程,拿回来一编译出现了N多错误,但是工程明明是正确的,没有什么特殊的配置设置,但是就是几乎所有的代码都在报错。可以看到关于类的操作都有问题 …..

    技术杂谈 2023年7月24日
    087
  • Object.observe将不加入到ES7

    先请看 Object.observe 的 API javascript;gutter:true; Object.observe(obj, callback[, acceptList…

    技术杂谈 2023年6月1日
    091
  • 史上最强IDEA工具使用教程,你想要的全都有!

    课程导读 俗话说:工欲善其事必先利其器。想要快速写出好的代码,更是离不开一个好的工具。在这个快速发展的社会,一个好的工具,能帮我们在开发过程中节省大量的开发时间。本套课程给同学们带…

    技术杂谈 2023年7月25日
    075
  • 华为IPv6 GRE隧道

    IPv6 over IPv4 GRE封装隧道 实验目标: 该实验参考了华为官网案例配置https://support.huawei.com/enterprise/zh/doc/ED…

    技术杂谈 2023年6月21日
    0125
  • 30道关于linux的基础命令小题,先练练手

    1.修改主机名为yuanlai0224命令是: 2.切换⽬录到/yuchao01/data/,再创建脚本/my_website/scripts/start.sh。 绝对路径、相对路…

    技术杂谈 2023年7月10日
    074
  • hosts文件作用

    1、加快域名解析对于要经常访问的网站,我们可以通过在Hosts中配置域名和IP的映射关系,提高域名解析速度。由于有了映射关系,当我们输入域名计算机就能很快解析出IP,而不用请求网络…

    技术杂谈 2023年7月11日
    078
  • graylog 源码结构&构建简单说明

    graylog 的源码属于一个单体系统,构建比较符合maven 构建系统,包含了web 以及server backend 模块,一些一些其他依赖模块web 构建使用了fronten…

    技术杂谈 2023年5月30日
    0101
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球