SpringBoot对于大多数Java程序猿已经是生活必备,golang在云原生的浪潮中也是势头正猛,主要的应用领域有区块链、容器开发,当我们深层次使用容器技术时,golang是必不可少的,当我们学习一门新的技术,总是想,我们是否可以往我们以往所熟知的知识上靠,这个项目模板,就是我尝试像使用SpringBoot一样来搭建的go web项目
项目技术框架:gin+gorm
项目结构:
├─common 公共模块
│ └─utils 工具包
├─config 配置包(包含配置加载器)
│ └─middle_ware gin中间件
├─controller 控制层(前后端分离,只返回json)
├─dao 数据层
├─model 实体包
├─resources 资源包
├─routers 路由
├─service 业务层
└─test 测试包
application.yml 项目配置文件
(1)首先,就是项目的配置,这里使用application.yml统一配置【还支持yaml,json格式配置】
application.yml内容
server:
port: 9000
datasource:
url: "root:root@(127.0.0.1:3306)/my_music?charset=utf8mb4&parseTime=True&loc=Local"
debug: true
(2)config使用策略模式,解析配置文件内容
编写配置文件中的配置项所对应的结构体
server_config.go
package config
import "my_music_server/common/utils"
// 配置加载,这里使用策略模式
//Viper可以处理多种格式的配置,目前已支持从JSON、TOML、YAML、HCL、INI和Java properties文件中读取配置数据。
//Viper还能监视配置文件的变动、重新读取配置文件。在项目中可以用作热加载
// TODO 热加载
//var ServerAllConfig = ServerConfig{}
var AppicationConfig = Config{}
type ServerConfig struct {
Port int `json:"server.port"` //服务端口
DatasourceUrl string `json:"datasource.url"` //数据库连接
IsDatasourceDebug bool `json:"datasource.debug"` //是否开启数据库debug
}
//ymal
type Config struct {
Server Server `yaml:"server" json:"server"`
DataSource DataSource `yaml:"datasource" json:"datasource"`
}
type Server struct {
Port int `yaml:"port" json:"port"`
}
type DataSource struct {
Url string `yaml:"url" json:"url"`
Debug bool `yaml:"debug" json:"debug"`
}
func InitServerConfig() (err error) {
//构建加载执行器
loader := NewLoader()
//加载yaml
isYamlFileExists, _ := utils.PathExists("application.yaml")
isYmlFileExists, _ := utils.PathExists("application.yml")
if isYamlFileExists || isYmlFileExists {
//构建yaml加载策略
err := loader.executeLoad(&YamlLoadStrategy{})
return err
}
//加载properties
isPropFileExists, _ := utils.PathExists("application.properties")
if isPropFileExists {
//构建properties加载策略
err := loader.executeLoad(&PropertiesStrategy{})
return err
}
isJsonFileExists, _ := utils.PathExists("application.json")
if isJsonFileExists {
//构建json加载策略
err := loader.executeLoad(&JsonLoadStrategy{})
return err
}
return err
}
编写文件加载策略
load_config.go
package config
import (
"errors"
"fmt"
"github.com/spf13/viper"
"my_music_server/common/utils"
)
//Loader 执行加载器
type loader struct {
}
//NewLoader 使用工厂模式构建配置加载执行器
func NewLoader() *loader {
return new(loader)
}
func (loader *loader) executeLoad(strategy LoadStrategy) (err error) {
err = strategy.Load()
return err
}
//LoadStrategy 策略规则
type LoadStrategy interface {
Load() error
}
//YamlLoadStrategy 加载yaml文件的策略
type YamlLoadStrategy struct {
}
func (yamlLoadStrategy *YamlLoadStrategy) Load() error {
//导入配置文件
viper.SetConfigType("yaml")
isYamlFileExists, _ := utils.PathExists("application.yaml")
isYmlFileExists, _ := utils.PathExists("application.yml")
if isYmlFileExists {
viper.SetConfigFile("./application.yml")
}else if isYamlFileExists{
viper.SetConfigFile("./application.yaml")
}else {
return errors.New("文件名称错误")
}
//读取配置文件
err := viper.ReadInConfig()
if err != nil {
fmt.Println(err.Error())
}
//将配置文件读到结构体中
err = viper.Unmarshal(&AppicationConfig)
if err != nil {
fmt.Println(err.Error())
}
return err
}
//JsonLoadStrategy 加载json文件的策略
type JsonLoadStrategy struct {
}
func (jsonLoadStrategy *JsonLoadStrategy) Load() error {
//导入配置文件
viper.SetConfigType("json")
viper.SetConfigFile("./application.json")
//读取配置文件
err := viper.ReadInConfig()
if err != nil {
fmt.Println(err.Error())
}
//将配置文件读到结构体中
err = viper.Unmarshal(&AppicationConfig)
if err != nil {
fmt.Println(err.Error())
}
return err
}
//加载properties
type PropertiesStrategy struct {
}
func (propertiesStrategy *PropertiesStrategy) Load() error {
//导入配置文件
viper.SetConfigType("properties")
viper.SetConfigFile("./application.properties")
//读取配置文件
err := viper.ReadInConfig()
if err != nil {
fmt.Println(err.Error())
}
//将配置文件读到结构体中
err = viper.Unmarshal(&AppicationConfig)
if err != nil {
fmt.Println(err.Error())
}
return err
}
(3)配置应用
mysql.go
package dao
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"my_music_server/config"
)
var (
DB *gorm.DB
)
//initializal mysql config
func InitMySQL() (err error) {
//使用配置文件中的db url配置信息
dst := config.AppicationConfig.DataSource.Url
DB, err = gorm.Open("mysql", dst)
//Whether to enable debug
//使用配置文件中的db debug配置信息,是否开启sql打印
if config.AppicationConfig.DataSource.Debug {
DB = DB.Debug()
}
if err != nil {
return
}
return DB.DB().Ping()
}
func Close() {
//Recovery of Resources
DB.Close()
}
main.go
package main
import (
"fmt"
"my_music_server/common"
"my_music_server/config"
"my_music_server/dao"
"my_music_server/routers"
)
func init() {
//加载server配置
err:=config.InitServerConfig()
if err!=nil{
panic(common.ERROR_JSON_PARSE)
}
err = dao.InitMySQL()
if err != nil {
panic(common.DB_CONN_FAIL)
}
}
func main() {
defer dao.Close()
//模型绑定【可选】
//映射路由
router := routers.SetupRouters()
//使用配置项中的port
router.Run(":"+fmt.Sprintf("%d",config.AppicationConfig.Server.Port))
}
源码地址
持续完善中…