私人博客定制----封装数据库接口
封裝MySQLAPI
我們先把初始化句柄和斷開句柄進(jìn)行一個(gè)封裝
static MYSQL* MySQLInit(){ //1.初始化一個(gè)Mysql句柄建立連接 MYSQL* connect_fd = mysql_init(NULL); //2.和數(shù)據(jù)庫建立連接 if (mysql_real_connect(connect_fd, "127.0.0.1", "root", "123456", "blog_system", 3306, NULL, 0) == NULL) { printf("連接失敗! %s\n", mysql_error(connect_fd)); return NULL; } //3.設(shè)置字符編碼集 mysql_set_character_set(connect_fd, "utf8"); return connect_fd; } static void MySQLRelease(MYSQL* mysql) { //釋放句柄并斷開連接 mysql_close(mysql); }博客表操作的實(shí)現(xiàn)
接下來的實(shí)現(xiàn)操作,我們需要借助一個(gè)庫,這個(gè)庫是Json庫,
大概了解一下Json
上面哪個(gè)鏈接可以大概了解Json,json 出自 JavaScript, 是一種非常方便的鍵值對數(shù)據(jù)組織格式, 目前被業(yè)界廣泛使用.
C++ 中可以使用 jsoncpp 這個(gè)庫來解析和構(gòu)造 json 數(shù)據(jù)。但是我們并不用里面提到的CJson的庫,我們是用Linux下yum源中的Json庫,可以通過下面這個(gè)命令進(jìn)行下載
以下的操作相關(guān)參數(shù)都同一使用Json的方式
Json::Value jsoncpp中最核心的類,Json::Value 就表示一個(gè)具體的對象,例如我們之前設(shè)計(jì)的API
為什么我們要使用Json這個(gè)庫呢?
其實(shí)最大的好處就是方便我們以后進(jìn)行功能上的擴(kuò)展
Json可以跨語言編程
實(shí)現(xiàn)插入博客
我們需要把博客對象傳進(jìn)去,因?yàn)橐恍┨厣庾址脑?#xff0c;我們先進(jìn)行轉(zhuǎn)義,然后進(jìn)行申請空間,這里使用智能指針來幫助我們管理內(nèi)存,我們就不必在考慮其中的釋放問題。最后拼裝sql語句并進(jìn)行返回值校驗(yàn)
智能指針原理
實(shí)現(xiàn)查詢所有博客
因?yàn)槭谦@取所有博客內(nèi)容,我們需要一個(gè)返回的結(jié)果,blogs作為輸出型參數(shù),除此之外我們還可以按照標(biāo)簽來篩選,初始給標(biāo)簽id默認(rèn)為空,如果用戶提供標(biāo)簽則進(jìn)行篩選,沒有提供則不進(jìn)行篩選,然后執(zhí)行sql語句,并判斷是否成功,然后我們還需要對結(jié)果集合進(jìn)行遍歷打印
bool SelectAll(Json::Value* blogs, const std::string& tag_id = "") { //查找不需要太長的sql,固定長度就行了 char sql[1024 * 4] = {0}; // 可以根據(jù) tag_id 來篩選結(jié)果 if (tag_id == "") { //此時(shí)不需要按照標(biāo)簽來進(jìn)行篩選 sprintf(sql, "select blog_id, title, tag_id, create_time from blog_table"); } else { //此時(shí)我們就要按標(biāo)簽進(jìn)行篩選了 sprintf(sql, "select blog_id, title, tag_id, create_time from blog_table where tag_id = '%s'", tag_id.c_str()); } int ret = mysql_query(mysql_, sql); if (ret != 0) { printf("執(zhí)行 查找 失敗! %s\n", mysql_error(mysql_)); return false; } MYSQL_RES* result = mysql_store_result(mysql_); if (result == NULL) { printf("獲取結(jié)果失敗! %s\n", mysql_error(mysql_)); return false; } int rows = mysql_num_rows(result); //把結(jié)果集合寫到blogs參數(shù)中,返回給調(diào)用者 for (int i = 0; i < rows; ++i) { MYSQL_ROW row = mysql_fetch_row(result); Json::Value blog; //row[]中的下標(biāo)和上面的select語句中寫的列順序是相關(guān)的 blog["blog_id"] = atoi(row[0]); blog["title"] = row[1]; blog["tag_id"] = atoi(row[2]); blog["create_time"] = row[3]; // 遍歷結(jié)果依次加入到 dishes 中 blogs->append(blog); } printf("執(zhí)行查找成功\n"); //mysql查詢的結(jié)果集合需要記得釋放 mysql_free_result(result); return 0;}實(shí)現(xiàn)查詢單個(gè)博客
我們在查看單個(gè)博客時(shí),blog同樣是輸出型參數(shù),根據(jù)當(dāng)前的blog_id在數(shù)據(jù)庫中找到具體的內(nèi)容,博客內(nèi)容通過blog參數(shù)返回給調(diào)用者。這回我們只需要拼接一條sql語句即可,然后再去遍歷結(jié)果集合就可以。
bool SelectOne(int32_t blog_id, Json::Value* blog) {char sql[1024 * 4] = {0};sprintf(sql, "select * from blog_table where blog_id = %d", blog_id);int ret = mysql_query(mysql_, sql);if (ret != 0) {printf("執(zhí)行 sql 失敗! %s\n", mysql_error(mysql_));return false;}MYSQL_RES* result = mysql_store_result(mysql_);if (result == NULL) {printf("獲取結(jié)果失敗! %s\n", mysql_error(mysql_));return false;}int rows = mysql_num_rows(result);if (rows != 1) {printf("查找結(jié)果不為 1 條. rows = %d!\n", rows);return false;}MYSQL_ROW row = mysql_fetch_row(result);(*blog)["blog_id"] = atoi(row[0]);(*blog)["title"] = row[1];(*blog)["content"] = row[2];(*blog)["tag_id"] = atoi(row[3]);(*blog)["create_time"] = row[4];return true;}實(shí)現(xiàn)更新博客
因?yàn)橐虏┛?#xff0c;涉及到有關(guān)正文的操作,所以需要先轉(zhuǎn)義,然后申請空間再由智能指針管理
bool Update(const Json::Value& blog) { //此處還需要轉(zhuǎn)義, const std::string& content = blog["content"].asString(); std::unique_ptr<char> content_escape(new char[content.size() * 2 + 1]); mysql_real_escape_string(mysql_, content_escape.get(), content.c_str(), content.size()); //插入的博客內(nèi)容會(huì)有點(diǎn)長,我們可以盡量把緩沖區(qū)變大點(diǎn) std::unique_ptr<char> sql(new char[content.size() * 2 + 4096]); //拼接sql語句 sprintf(sql.get(), "update blog_table set title='%s', content='%s',tag_id=%d where blog_id=%d", blog["title"].asCString(), content_escape.get(), blog["tag_id"].asInt(), blog["blog_id"].asInt()); int ret = mysql_query(mysql_, sql.get()); if (ret != 0) { printf("執(zhí)行更新博客 失敗! sql=%s, %s\n", sql.get(), mysql_error(mysql_)); return false; } printf("執(zhí)行博客成功\n"); return true; }實(shí)現(xiàn)刪除博客
bool Delete(int blog_id) {char sql[1024 * 4] = {0};sprintf(sql, "delete from blog_table where blog_id=%d", blog_id);int ret = mysql_query(mysql_, sql);if (ret != 0) {printf("執(zhí)行刪除博客失敗! sql=%s, %s\n", sql, mysql_error(mysql_));return false;}printf("刪除博客成功\n");return true; }對博客表操作進(jìn)行單元測試
void TestBlogTable(){ //方便我們進(jìn)行格式化結(jié)果,打印出來的結(jié)果更好看一些 Json::StyledWriter writer; MYSQL* mysql = blog_system::MySQLInit(); blog_system::BlogTable blog_table(mysql); bool ret = false; Json::Value blog; /* blog["title"] = "第一篇博客"; blog["content"] = "我要好好學(xué)習(xí)"; blog["tag_id"] = 1; blog["create_time"] = "2019/-/-"; bool ret = blog_table.Insert(blog); printf("Insert:%d\n",ret); */ //測試查找 /*Json::Value blogs; ret = blog_table.SelectAll(&blogs); printf("select ALl %d\n",ret); printf("%s\n",writer.write(blogs).c_str()); */ //測試查找單個(gè)博客 /*ret = blog_table.SelectOne(1,&blog); printf("select one %d\n",ret); printf("blog:%s\n",writer.write(blog).c_str());//序列化,方便我們看輸出 */ //測試修改博客/* blog["blog_id"] = 1;blog["title"] = "第一篇項(xiàng)目博客";blog["content"] = "1.博客表\n 博客'就是總結(jié)與學(xué)習(xí)',幫助我們記事。";ret = blog_table.Update(blog);printf("Update %d\n",ret);*///測試刪除博客ret = blog_table.Delete(1);printf("Delete %d\n",ret);blog_system::MySQLRelease(mysql); }實(shí)現(xiàn)標(biāo)簽表的操作
實(shí)現(xiàn)新增標(biāo)簽
這塊我們還是跟博客表的操作是一樣的,都是拼裝sql語句,然后執(zhí)行,判斷是否執(zhí)行成功,打印提示。
bool Insert(const Json::Value& tag) { char sql[1024 * 4] = {0}; // 此處 dish_ids 需要先轉(zhuǎn)成字符串(本來是一個(gè)對象, // 形如 [1, 2, 3]. 如果不轉(zhuǎn), 是無法 asCString) sprintf(sql,"insert into tag_table values(null, '%s')",tag["tag_name"].asCString()); int ret = mysql_query(mysql_, sql); if (ret != 0) { printf("插入標(biāo)簽失敗! sql=%s, %s\n", sql, mysql_error(mysql_)); return false; } printf("插入標(biāo)簽成功\n"); return true; }實(shí)現(xiàn)刪除標(biāo)簽
bool Delete(int32_t tag_id) { char sql[1024 * 4] = {0}; sprintf(sql, "delete from tag_table where tag_id = %d", tag_id); int ret = mysql_query(mysql_, sql); if (ret != 0) { printf("插入標(biāo)簽失敗! sql=%s, %s\n", sql, mysql_error(mysql_)); return false; } printf("插入標(biāo)簽成功\n"); return 0; }實(shí)現(xiàn)查看所有標(biāo)簽
bool SelectAll( Json::Value* tags) { char sql[1024 * 4] = {0}; sprintf(sql, "select * from tag_table"); int ret = mysql_query(mysql_, sql); if (ret != 0) { printf("查找失敗! %s\n", mysql_error(mysql_)); return false; } MYSQL_RES* result = mysql_store_result(mysql_); if (result == NULL) { printf("獲取結(jié)果失敗! %s\n", mysql_error(mysql_)); return false; } int rows = mysql_num_rows(result); for (int i = 0; i < rows; ++i) { MYSQL_ROW row = mysql_fetch_row(result); Json::Value tag; tag["tag_id"] = atoi(row[0]); tag["tag_name"] = row[1]; tags->append(tag); } printf("查找標(biāo)簽成功!共找到 %d 個(gè)\n",rows); return true; }對標(biāo)簽操作進(jìn)行單元測試
void TestTagTable(){ MYSQL* mysql = blog_system::MySQLInit(); blog_system::TagTable tag_table(mysql); Json::Value tags; Json::StyledWriter writer; /*tag["tag_name"] = "項(xiàng)目"; bool ret = tag_table.Insert(tag); printf("insert %d\n",ret); */ //測試查找 /* bool ret = tag_table.SelectAll(&tags); printf("select all %d\n",ret); printf("tags:%s\n",writer.write(tags).c_str()); */ //測試刪除 bool ret = tag_table.Delete(1); printf("Delete %d\n",ret); blog_system::MySQLRelease(mysql); }總結(jié)
以上是生活随笔為你收集整理的私人博客定制----封装数据库接口的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 麻烦发个85红眼纯刷图加点,详细点,谢谢
- 下一篇: 成都大熊猫繁育基地购票须知