C++项目——博客管理系统

需求分析:

编写一个博客系统,提供一个浏览器页面, 能够让管理员在后台管理我们的博客(增删改查);能够让用户对自己的博客进行管理,查看别人的博客。

项目的概要设计:

后台的业务处理,后台的数据管理,前端页面展示操作

博客服务器

  1. 对博客的增删改查管理能力
  2. 对标签的增删查改能力

博客客户端

  1. 博客标题列表页面
  2. 博客内容展示页面
  3. 博客管理页面
  4. 博客内容编辑页面

关于数据存储和交互

  1. 服务器存储 markdown 格式的数据
  2. 前端通过 editor.md 这个工具将markdown的文档内容提交给服务器, 或者解析服务器返回的 markdown 作为前端页面内容

采用MVC框架实现
用一种业务逻辑、数据、界面显示分离的方法组织代码。

项目的详细设计:从各个框架的模块出发

数据管理模块:进行数据管理
使用mysql数据库进行数据的管理
业务逻辑模块:完成业务处理
向用户提供页面进行数据的操作(博客/标签/用户的增删改查)

数据库模块设计

使用mysql数据库进行数据的管理

表的设计

用户表:table_uesr

在这里插入图片描述

博客标签表:table_tag

在这里插入图片描述

博客表:table_blog

在这里插入图片描述

数据管理模块:封装访问接口。

将数据的校验以及数据库的访问操作封装起来。

数据库编写

CREATE DATABASE  IF NOT EXISTS blog_system charset=utf8 collate utf8_general_ci;                                                   
use blog_system;    
    
drop table if exists table_tag;    
create table table_tag(    
    tag_id int primary key auto_increment,    
    tag_name varchar(30) unique    
);    
    
drop table if exists table_user;    
create table table_user(    
    user_id int primary key auto_increment,    
    user_name varchar(30) unique    
);    
    
drop table if exists table_blog;    
create table table_blog(    
    blog_id int primary key auto_increment,    
    user_id int,    
    tag_id int,    
    title varchar(255),    
    content text,    
    ctime datetime,    
    foreign key (user_id) references table_user(user_id),    
    foreign key (tag_id) references table_tag(tag_id)    
);

代码编写

将json字符串转化为json对象,进而进行校验,实现数据传递
libjsoncpp库实现字符串与json对象的数格式据交换:
Json::Value — json数据对象
Json::Read ---- json字符串到json对象的解析— json反序列化
Json::Writer —从json对象到json字符串的组织— json序列化

TagTable
class table_tag                                                                                                                
{                         
public:                         
    table_tag(MYSQL *mysql)                         
        :_mysql(mysql)                         
    {}                         
    bool Insert(const Json::Value &tag);                         
    bool Delete(int tag_id);                         
    bool UpDate(int tag_id, const Json::Value &tag);                         
    bool GetAll(Json::Value &tags);                         
    bool GetOne(int tag_id, Json::Value &tag);                         
private:                         
    MYSQL *_mysql;                         
};
UserTable
class table_user
{
public:
    table_user(MYSQL *mysql)
        :_mysql(mysql)
    {}
    bool Insert(const Json::Value &user);
    bool Delete(int user_id);
    bool UpDate(int user_id, const Json::Value &user);
    bool GetAll(Json::Value &users);
    bool GetOne(int user_id, Json::Value &user);
private:
    MYSQL *_mysql;
};
BlogTable
class table_blog
{
public:
    table_blog(MYSQL *mysql)
        :_mysql(mysql)
    {}
    bool Insert(const Json::Value &blog);
    bool Delete(int blog_id);                                                                                                  
    bool UpDate(int blog_id, const Json::Value &blog);
    bool GetAll(Json::Value &blogs);
    bool GetOne(int blog_id, Json::Value &blog);
    bool GetTag(int tag_id, Json::Value &blogs);
    bool GetUser(int user_id, Json::Value &blogs);
private:
    MYSQL *_mysql;
};

操作流程

使用C语言mysql的API接口实现mysq|数据库的访问:实际上就是编写一个mysq|客户端

1.初始化mysq|句柄

MYSQL *mysql_init(MYSQL *mysql)

2.连接mysq|服务器

MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)

MYSQL *mysql_ real connect(MYSQL *mysq|, const char *host, const char *user, const char *passwd, const char *db,unsigned int port, const char *unix_ socket, unsigned long client flag);

mysql:初始化完毕的句柄;
host:连接的mysq|服务器IP
user: mysq|数据库的用户名
passwd:数据库密码
db:连接数据库的同时可以选择使用的数据库名称;
port:连接的mysq|服务器端口-默认0表示3306
unix_ socket: 套接字文件,通常置NULL;
client_ flag: 客户端标志,通常置0;
返回值:成功返回句柄首地址,失败返回NULL;

3.设置客户端的字符编码集

int mysql_set_character_set(MYSQL *mysql, const char *csname)

零成功。如果发生错误,则为非零值。
4.语句执行(增删改查)

int mysql_query(MYSQL *mysql, const char *stmt_str)

零成功。如果发生错误,则为非零值。
5.增删改–只要知道执行结果如何就能判断成功与否;对于查询执行成功,还得去获取数据
查询: 1. 获取结果集。2. 遍历结果集获取各条数据。3. 释放结果集

MYSQL_RES *mysql_store_result(MYSQL *mysql) 获取结果集 uint64_t
mysql_num_rows(MYSQL_RES *result)返回结果集中的行数。 unsigned int
mysql_num_fields(MYSQL_RES *result)返回结果集中的列数。 void
mysql_free_result(MYSQL_RES *result)释放结果集 MYSQL_ROW
mysql_fetch_row(MYSQL_RES *result)检索结果集的下一行

6.关闭数据库

void mysql_close(MYSQL *mysql)

业务逻辑模块设计

向用户提供页面进行数据的操作(博客/标签/用户的增删改查)

整体设计

用户通过浏览器获取博客首页
——涉及的就是前端客户端与后台服务器之间的数据交互—网络通信

数据的交互接口:

客户端发送什么样的请求,服务端应该给与什么样的响应—采用HTTP协议进行通信

通信接口的设计:

采用Restful风格的接口设计–基于HTTP协议,使用json的一种数据格式风格

Restful通信接口规范:

请求方法: POST–新增 / GET–获取/ DELETE–删除/ PUT–修改
正文: json序列化的数据格式—独立于语言,简洁、清晰、可视化

json序列化和反序列化使用库实现: libjsoncpp
用户:增删改查
标签:增删改查
博客:增删改查

Json串的解析以及组织

Json::Value — json对象
Json::Reader – -实现json字符串解析的对象bool Json::Reader:parse(std:string,Json::Value)
Json::FastWriter —实现json对象到json字符串的组织std:string Json::FastWriter::write(son::Value)

httplib中如何获取查询字符串

req.params -> /path?key= val&key=val… .
bool httplib::Request::has_ param(char *key) —判断有没有某个key的查询字符串
stl::string httplb::Request.:get_param_val(char *key) — 通过key获取value

httplib中如何获取资源路径中的id

/path/(\d+) -> req.matches[1]
httplib中如何添加正文
httplib::Response::set_ content(stl:string body, std:string type)

接口设计

用户的增删改查接口设计:
增添用户:
POST /user HTTP/1.1\r\n
Content-Type: application/json\r\n
Content-Length: \r\n
\r\n
{ " name'":" zhangwenchao" }

成功响应
HTTP/1.1 200 OK\r\n
Content-Length:
\r\n
{
"result":"ok"
"reason":
}

失败响应
HTTP/1.1 400 Bad Request\r\n
Content-Length: \r\n
\r\n
{
"result":"failed",
"reason":"format error"
}


删除用户:
DELETE /user/user_ id HTTP/1.1\r\n
Content-Length: 0\r\n

响应
HTTP/1.1 200 OK\r\n
Content-Length: 0\r\n


修改用户:
PUT /user/user_id HTTP/1.1\r\n
Content-Length:
Content-Type:
\r\n
{ "name":"newname" }

响应
HTTP/1.1 200 OK\r\n
Content-Length: 0\r\n


获取所有用户:
GET /user HTTP/1.1\r\n
Content-Length: 0\r\n

响应
HTTP/1.1 200 OK\r\n 
Content-Length: \r\n
\r\n
{
    [ {"id":1, "name":"zhangsan"}, 
     {"id":2, "name":"lisi"} ]
}


获取单个用户:
GET /user/user_id HTTP/1.1\r\n
Content-Length: 0\r\n

响应
HTTP/1.1 200 OK\r\n 
Content-Length: \r\n
\r\n
{
   {"id":1, "name":"zhangsan"}
}


标签的增删改查接口设计
添加标签:
POST /tag HTTP/1.1\r\n
Content-Length:
Content Type: \r\n
\r\n
{"name": "C++"} 

响应
HTTP/1.1 200 OK\r\n
Content-Length: 0\r\n
\r\n


删除标签
DELETE /tag/tag_id HTTP/1.1\r\n
Content-Length: 0\r\n
Content- Type: \r\n
\r\n

响应
HTTP/1.1 200 OK\r\n
Content-Length: 0\r\n
\r\n


修改标签
PUT /tag/tag_id HTTP/1.1
Content-Length: \r\n
Content-Type: \r\n
\r\n
{"name" : "Java"}

响应
HTTP/1.1 200 OK\r\n 
Content-Length: 0\r\n
\r\n


获取所有标签:
GET /tag HTTP/1.1\r\n 
Content-Length: 0\r\n
\r\n

响应
HTTP/1.1 200 OK\r\n
Content-Length: \r\n
\r\n
{
    [{"id":1, "name'":"C++"}, 
     {"id":2, "name":" Java"}]
}


获取单个标签:
GET /tag/tag_id HTTP/1.1\rn
Content-Length: 0\r\n
\r\n

响应
HTTP/1.1 200 OK\r\n
Content-Length: \r\n
\r\n
{"id'":1, "name":"C++"}


博客信息通信接口的设计:
添加博客:
POST /blog HTTP/1.1\r\n
Content-Length: \r\n 
Content-Type: \r\n
\r\n
{"tag_id": 1, "user. id": 1, "title":"精彩", "content": "非常精彩"}

响应
HTTP/1.1 200 OK\r\n 
Content-Length: 0\r\n
\r\n


删除博客:
DELETE /blog/blog_id HTTP/1.1\r\n
Content-Length: 0\r\n
\r\n

响应
HTTP/1.1 200 OK\r\n 
Content-Length: 0\r\n
\r\n


修改博客:
PUT /blog/blog_id HTTP/1.1\r\n
Content-Length: 0\r\n\r\n
{"tag_ id": 1, "user. id": 1, "title":" 精彩", "content": "内容非常精彩"}

响应
HTTP/1.1 200 OK\r\n 
Content-Length: 0\r\n
\r\n


获取所有博客:
GET /blog HTTP/1.1\rn
Content-Length: 0\r\n\r\n

响应
HTTP/1.1 200 OK\r\n
Content-Length: 0\r\n\r\n
{[
{"tag_ id": 1, "user_ id": 1, "title":"精彩", "content": "内容非常精彩" },
{"tag_ id": 1, "user. id": 1, "title":" 精彩", "content": "内容非常精彩"}
]}


获取指定标签类型的所有博客(GET方法没有正文,所以提交的数据不能放在正文中)
GET /blog?tag_id=1 HTTP/1.1\r\n

响应
HTTP/1.1 200 OK\r\n
Content-Length: 0\r\n\r\n
{[
{"tag_ id": 1, "user_ id": 1, "title":"精彩", "content": "内容非常精彩" },
{"tag_ id": 1, "user. id": 1, "title":" 精彩", "content": "内容非常精彩"}
]}


获取指定用户的所有博客
GET /blog?user_ id=1 HTTP/1.1\r\n

响应
HTTP/1.1 200 OK\r\n
Content-Length: 0\r\n\r\n
{[
{"tag_ id": 1, "user_ id": 1, "title":"精彩", "content": "内容非常精彩" },
{"tag_ id": 1, "user. id": 1, "title":" 精彩", "content": "内容非常精彩"}
]}


获取指定博客
GET /blog/blog_ id HTTP/1.1\r\n

响应
HTTP/1.1 200 OK\r\n
Content-Length: 0\r\n\r\n
{
    {"tag_ id": 1, "user. id": 1, "title":" 精彩", "content": "内容非常精彩"}
}

搭建环境:

库的安装
sudo yum -y install epel-release
sudo yum install jsoncpp-devel
gcc升级:
sudo yum install centos-release-scl-rh centos-release-scl
sudo yum install devtoolset-4-gcc devtoolset-4-gcc-c++
source /opt/rh/devtoolset-4/enable

服务端搭建完毕之后
虚拟机:需要虚拟机关闭防火墙,我们的主机才能通过浏览器访问
systemctl stop firewalld --关闭防火墙服务—下次登录依然需要重新关闭
systemctl disable firewalld --停用防火墙服务—下次登录就不需要重新关闭

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值