项目目录规范
-
blogger:
- controller:页面控制相关
- dao:数据层
- model :实体
- service:业务逻辑
- static:css,js
- utils :工具
- views :HTML模板
- main.go:入口,定义路由
-
数据库:blogger:库
-
表:
-
article:文章表
image.png -
category:分类表
image.png -
comment:评论表
image.png -
leave 留言表
image.png
-
-
实体类
- 分类的结构体
- 文章的结构体(可不写内容,占文本)
study/lwz/blog/model/category.go
package model
//定义分类结构体
type Category struct {
CategoryId int64 `db:"id"`
CategoryName string `db:"category_name"`
CategoryNo int `db:"category_no"`
}
study/lwz/blog/model/article.go
package model
import "time"
//定义文章结构体
type ArticleInfo struct {
Id int64 `db:"id"`
CategoryId int64 `db:"category_id"`
//文章摘要
Summary string `db:"summary"`
Title string `db:"title"`
ViewCount uint32 `db:"view_count"`
//时间
CreateTime time.Time `db:"create_time"`
CommentCount uint32 `db:"comment_count"`
Username string `db:"username"`
}
//用于文章详情页的实体
//为了提高效率
type ArticleDetail struct {
ArticleInfo
//文章内容
Content string `db:"content"`
Category
}
//用于文章上下页
type ArticleRecord struct {
ArticleInfo
Category
}
- 数据层
- init()数据库初始化函数
- 分类相关的操作(添加,查询,查1个分类,查多个分类,查所有分类)
- 文章相关的操作(添加文章(投稿),查询所有文章,根据文章id查看内容)
study/lwz/blog/dao/db/db.go
package db
import (
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
var (
DB *sqlx.DB
)
//初始化
func Init(dns string)error{
var err error
DB,err = sqlx.Open("mysql",dns)
if err != nil{
return err
}
//查看是否连接成功
err = DB.Ping()
if err != nil{
return err
}
DB.SetMaxOpenConns(100)
DB.SetMaxIdleConns(16)
return nil
}
study/lwz/blog/dao/db/category.go
package db
import (
"github.com/cold-rivers-snow/study/lwz/blog/model"
"github.com/jmoiron/sqlx"
)
//添加分类
func InsertCategory(category *model.Category)(categoryId int64,err error){
sqlstr := "insert into category(category_name,category_no) value(?,?)"
result,err := DB.Exec(sqlstr,category.CategoryName,category.CategoryNo)
if err != nil{
return
}
categoryId,err = result.LastInsertId()
return
}
//获取单个分类
func GetCategoryById(id int64)(category *model.Category,err error){
category = &model.Category{}
sqlStr := "select id,category_name,category_no from category where id = ?"
err = DB.Get(category,sqlStr,id)
return
}
//获取多个分类
func GetCategoryList(categoryIds []int64)(categoryList []*model.Category,err error){
sqlStr,args,err := sqlx.In("select id,category_name,category_no from category where id in (?)",categoryIds)
if err != nil{
return
}
//查询
err = DB.Select(&categoryList,sqlStr,args...)
return
}
//获取所有分类
func GetAllCategoryList()(categoryList []*model.Category,err error){
sqlStr := "select id,category_name,category_no from category order by category_no asc"
//查询
err = DB.Select(&categoryList,sqlStr)
return
}
study/lwz/blog/dao/db/category_test.go
package db
import (
"testing"
)
func init(){
//parseTime=true 将mysql中时间类型,自动解析为go结构体中的时间类型
//不加报错
dns := "root:root@tcp(127.0.0.1:3306)/blogger?parseTime=true"
err := Init(dns)
if err != nil{
panic(err)
}
}
func TestGetCategoryById(t *testing.T) {
catagoy,err := GetCategoryById(1)
if err != nil{
panic(err)
}
t.Logf("category:%#v",catagoy)
}
func TestGetCategoryList(t *testing.T) {
var categoryIds []int64
categoryIds = append(categoryIds,1,2,3)
categoryList,err := GetCategoryList(categoryIds)
if err != nil{
panic(err)
}
for _,v := range categoryList{
t.Logf("id:%d category:%#v\n",v.CategoryId,v)
}
}
func TestGetAllCategoryList(t *testing.T) {
categoryList,err := GetAllCategoryList()
if err != nil{
panic(err)
}
for _,v := range categoryList{
t.Logf("id:%d category:%#v\n",v.CategoryId,v)
}
}
- 业务逻辑层
- 获取分类列表(用于展现分类云)
- 获取所有文章和对应分类信息
- 根据分类id,获取该类文章和其对应的分类信息
study/lwz/blog/service/category.go
package service
import (
"github.com/cold-rivers-snow/study/lwz/blog/dao/db"
"github.com/cold-rivers-snow/study/lwz/blog/model"
)
//获取所有分类
func GetAllCategoryList()(categoryList []*model.Category,err error){
categoryList,err = db.GetAllCategoryList()
if err != nil{
return
}
return
}
study/lwz/blog/service/article.go
package service
import (
"github.com/cold-rivers-snow/study/lwz/blog/dao/db"
"github.com/cold-rivers-snow/study/lwz/blog/model"
)
//获取文章和对应的分类
func GetArticleRecodeList(pageNum,pageSize int)(articleRecodeList []*model.ArticleRecord,err error){
//获取文章列表
articleInfoList,err := db.GetArticleList(pageNum,pageSize)
if err != nil{
return
}
if len(articleInfoList) <= 0{
return
}
//获取文章对应的分类(多个)
categoryIds := getCategoryIds(articleInfoList)
categoryList,err := db.GetCategoryList(categoryIds)
if err != nil{
return
}
//返回页面,做聚合
//遍历所有文章
for _,article := range articleInfoList{
//根据当前文章,生成结构体
articelRecord := &model.ArticleRecord{
ArticleInfo:*article,
}
//文章取出分类id
categoryId := article.CategoryId
//遍历分类列表
for _,category := range categoryList{
if categoryId == category.CategoryId{
articelRecord.Category = *category
break
}
}
articleRecodeList = append(articleRecodeList,articelRecord)
}
return
}
//根据多个文章id,获取多个分类id的集合
func getCategoryIds(articleInfoList []*model.ArticleInfo)(ids []int64){
//遍历文章,得到每个文章
for _,article := range articleInfoList{
//从当前文章取出分类id
categoryId := article.CategoryId
//去重,防止重复
for _,id := range ids{
//看当前id是否存在
if id != categoryId{
ids = append(ids,categoryId)
}
}
}
return
}
//根据分类id,获取该类文章和他们对应分类信息
func GetArticleRecodeListByID(categoryId,pageNum,pageSize int)(articleRecodeList []*model.ArticleRecord,err error){
//获取文章列表
articleInfoList,err := db.GetArticleListByCategoryId(categoryId,pageNum,pageSize)
if err != nil{
return
}
if len(articleInfoList) <= 0{
return
}
//获取文章对应的分类(多个)
categoryIds := getCategoryIds(articleInfoList)
categoryList,err := db.GetCategoryList(categoryIds)
if err != nil{
return
}
//返回页面,做聚合
//遍历所有文章
for _,article := range articleInfoList{
//根据当前文章,生成结构体
articelRecord := &model.ArticleRecord{
ArticleInfo:*article,
}
//文章取出分类id
categoryId := article.CategoryId
//遍历分类列表
for _,category := range categoryList{
if categoryId == category.CategoryId{
articelRecord.Category = *category
break
}
}
articleRecodeList = append(articleRecodeList,articelRecord)
}
return
}
- controller层
- 访问主页,展现所有文章和分类云
- 点击分类云,展示具体的分类内容
study/lwz/blog/controller/handler.go
package controller
import (
"github.com/cold-rivers-snow/study/lwz/blog/service"
"github.com/gin-gonic/gin"
"net/http"
"strconv"
)
//访问主页的控制器
func IndexHandle(c *gin.Context){
//从service取数据
//1、加载文章数据
articleRecordList,err := service.GetArticleRecodeList(0,15)
if err != nil{
c.HTML(http.StatusInternalServerError,"views/500.html",nil)
return
}
//2、加载分类数据
categoryList,err := service.GetAllCategoryList()
if err != nil{
c.HTML(http.StatusInternalServerError,"views/500.html",nil)
return
}
//gin.H本质是一个map,与下面的代码一样
//var data map[string]interface{} = make(map[string]interface{},16)
//data["article_list"] = articleRecordList
//data["category_list"] = categoryList
//c.HTML(http.StatusOK,"viewd/index.html",data)
c.HTML(http.StatusOK,"views/index.html",gin.H{
"article_list":articleRecordList,
"category_list":categoryList,
})
}
//点击分类云进行分类
func CategoryList(c *gin.Context){
categoryIdStr := c.Query("category_id")
//转
categoryId,err := strconv.ParseInt(categoryIdStr,10,64)
if err != nil{
c.HTML(http.StatusInternalServerError,"views/500.html",nil)
return
}
//根据分类id,获取文章列表
articleRecordList,err := service.GetArticleRecodeListByID(int(categoryId),0,15)
if err != nil{
c.HTML(http.StatusInternalServerError,"views/500.html",nil)
return
}
//再次加载所有分类数据,用于分类云显示
categoryList,err := service.GetAllCategoryList()
c.HTML(http.StatusOK,"views/index.html",gin.H{
"article_list":articleRecordList,
"category_list":categoryList,
})
}
study/lwz/blog/main.go
package main
import (
"github.com/cold-rivers-snow/study/lwz/blog/controller"
"github.com/cold-rivers-snow/study/lwz/blog/dao/db"
"github.com/gin-gonic/gin"
)
func main(){
router := gin.Default()
dns := "root:root@tcp(127.0.0.1:3306)/blogger?parseTime=true"
err := db.Init(dns)
if err != nil{
panic(err)
}
//加载静态文件
router.Static("/static/","./static")
//加载模板
router.LoadHTMLGlob("views/*")
router.GET("/",controller.IndexHandle)
router.GET("/category/",controller.CategoryList)
router.Run(":8000")
}
网友评论