本文来自博客园,作者: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
修改新增/更新文件元信息接口
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/
转载文章受原作者版权保护。转载请注明原作者出处!