对Mysql zookeeper redis常用c语言api进行对象封装

Mysql

需要安装mysql和mysql的开发包,ubuntu下安装开发包的命令是
sudo apt-get install libmysqlclient-dev

Mysql.h

#ifndef DB_H 
#define DB_H 
#include <mysql/mysql.h>   
#include <string>

class MySQL {
public:
    MySQL() ; 

    ~MySQL() ; 

    bool connect() ; 

    bool update(std::string sql) ; 

    MYSQL_RES* query(std::string sql) ; 

    MYSQL* getConnection() ; 

private:
    MYSQL* _conn ; 

} ; 



#endif 

Mysql.cpp

#include "db.h"
#include <muduo/base/Logging.h>
#include <string> 
#include <iostream>
static std::string server = "127.0.0.1" ; 
static std::string user = "root" ;
static std::string password = "123456" ; 
static std::string dbname = "chat" ; 
MySQL::MySQL(){
    _conn = mysql_init(nullptr) ; 
}

MySQL::~MySQL() {
    if(_conn != nullptr ) {
        mysql_close(_conn) ; 
    }
}

bool MySQL::connect() {
    MYSQL* p = mysql_real_connect(_conn  , server.c_str() , user.c_str() 
    , password.c_str() , dbname.c_str() , 3306 , nullptr , 0 ) ;
    if(p != nullptr ) {
        // mysql_query(_conn , "set names gbk") ; 
        LOG_INFO << "connection mysql database sucess!" ;     // 这里实现的是一个简易的宏日志系统,不影响代码逻辑
    } else {
        LOG_INFO << __FILE__ << ":" << __LINE__ << ":" << "连接失败,请稍后重试" ; 
        std::cerr << mysql_error(_conn) << std::endl ; 
    }
    return p ; 
}

bool MySQL::update(std::string sql) {
    if(mysql_query(_conn , sql.c_str() ) ) {
        LOG_INFO << __FILE__ << ":" << __LINE__ << ":" << sql << "更新失败" ; 
        return false ; 
    }
    return true ; 
}

MYSQL_RES* MySQL::query(std::string sql) {
    if(mysql_query(_conn , sql.c_str())) {
            LOG_INFO << __FILE__ << ":" << __LINE__ << ":" << sql << "查询失败" ; 
        return nullptr ; 
    }
    return mysql_use_result(_conn) ; 
}

MYSQL* MySQL::getConnection(){
    return _conn ; 
}

Zookeeper

Zookeepr.h

在使用的时候一定要 -lzookeeper_mt 链接zookeeper的动态库

#pragma once 

#include <semaphore.h>
#include <zookeeper/zookeeper.h>
#include <string> 

class ZkClient {
public :
    ZkClient() ; 
    ~ZkClient() ; 
    void Start() ; 
    void Create(const char* path , const char * data , int datalen , int state = 0 ) ; 
    std::string GetData(const char* path ) ; 
    
private:

    // zk的客户端的句柄
    zhandle_t* m_zhandle ; 

} ; 

Zookeeper.cpp

#include "rpczookeeperutil.h"
#include "rpcapplication.h"
#include "rpcserverlog.h" 

#include <semaphore>

// 当服务端向客户端发送成功的消息的时候,这个函数会被回调
void watcher(zhandle_t *zh, int type, int state, const char *path,void *watcherCtx) {
    if(type == ZOO_SESSION_EVENT ) {
        if(state == ZOO_CONNECTED_STATE ) {
            sem_t* sem = (sem_t*)zoo_get_context(zh) ; 
            sem_post(sem) ; 
        }
    }
}

ZkClient::ZkClient(): m_zhandle(nullptr) {

} 
ZkClient::~ZkClient(){
    if(m_zhandle != nullptr ) {
        zookeeper_close(m_zhandle) ; 
    }
} 

// 客户端异步连接 zkServer服务器  
void ZkClient::Start() {
    std::pair<std::string , int> info = RpcApplication::GetInstance().GetZookeeperInfo() ; 
    std::string host = info.first , port = std::to_string(info.second) ; 
    std::string connstr = host + ":" + port ; 

    /*
    如果链接的是zookeeper_mt 多线程版本的库
    在调用zookeeper_init的时候是异步的,有多个线程:
    API调用线程,就是当前线程
    在函数内部通过调用pthread_create API 接口创建另外两个线程: 网络I/O线程(使用poll) , watcher 回调线程 
    
    */

    m_zhandle = zookeeper_init(connstr.c_str() , watcher , 30000 , nullptr , nullptr , 0) ; 
    if(m_zhandle == nullptr ) {
        LOG_INFO("connect to zookeeper server:%s failed..." , ERROR , connstr.c_str() ) ; 
        exit(EXIT_FAILURE) ; 
    }
    sem_t sem ;   // 用于判断是否连接成功
    sem_init(&sem , 0 , 0 ) ; 
    zoo_set_context(m_zhandle , &sem) ;  

    sem_wait(&sem) ; // 一直阻塞,直到watcher 成功被调用,表示连接成功

    LOG_INFO("zookeeper_init sucess!" , INFO) ;  

} 


// 创建节点并给节点赋值
void ZkClient::Create(const char* path , const char * data , int datalen , int state  ) {
    char path_buffer[1024] ; 
    int bufferlen = sizeof(path_buffer) ; 
    int flag ; 

    flag = zoo_exists(m_zhandle , path , 0 , nullptr ) ;  // 判断当前节点是否存在

    if(ZNONODE == flag ) {
        flag = zoo_create(m_zhandle , path , data , datalen , &ZOO_OPEN_ACL_UNSAFE , state , path_buffer , bufferlen ) ; 
        if(flag == ZOK) {
            LOG_INFO("znode create sucess.... path:%s" , INFO , path) ; 
        }else {
            LOG_INFO("flag: %d znode create error.... path: %s" , ERROR , flag , path ) ; 
            exit(EXIT_FAILURE) ; 
        }
    }

}

// 获取节点上的数据
std::string ZkClient::GetData(const char* path ) {
    char buffer[1024] ; 
    int bufferlen = sizeof(buffer) ; 
    int flag = zoo_get(m_zhandle , path , 0 , buffer , &bufferlen , nullptr ) ; 
    if(flag != ZOK) {
        LOG_INFO("get znode error.... path: %s" , ERROR , path ) ; 
        exit(EXIT_FAILURE) ; 
    }

    return buffer ; 
}

Redis

git clone https://github.com/redis/hiredis 从github上下载hiredis客户端,进行源码
编译安装
cd hiredis
make
sudo make install
sudo ldconfig /usr/local/lib
在使用的时候需要 -lhiredis 链接动态库文件
这里的封装的只是对redis上的数据进行简单的增删改查,并不涉及复杂的操作

Redis.h

#pragma once 
#include <hiredis/hiredis.h>
#include <thread>
#include <functional>
#include <string> 
#include <iostream>
class Redis {

public:
    Redis() ; 
    ~Redis() ; 
 
    void Connect() ; 
    void RegisterRpcAddress(std::string service , std::string method , std::string address ) ; 
    std::string GetAddress(std::string service , std::string method) ; 
    std::string RedisCommand(std::string command , std::string key , std::string value ) ;  

private:
    redisContext* conn ; 
} ; 

Redis.cpp

#include "rpcredisutil.h"
#include <iostream>
#include "rpcapplication.h"

Redis::Redis(): conn(nullptr) {} 

Redis::~Redis() {
    if(conn != nullptr ) {
        redisFree(conn) ; 
    }
}

void Redis::Connect() {
    std::pair<std::string , int> redisInfo = RpcApplication::GetInstance().GetRedisInfo() ; 
    std::string ip = redisInfo.first ; 
    int port = redisInfo.second ; 
    conn = redisConnect( ip.c_str() , port ) ; 
    if (conn->err)
    {
        std::cout << __FILE__  << __LINE__ << "init redis failed..." << std::endl ; 
        redisFree(conn);                
        exit(EXIT_FAILURE) ; 
    }
}

void Redis::RegisterRpcAddress(std::string service , std::string method , std::string address ) {
    redisReply * reply = (redisReply* ) redisCommand(conn, "hset %s %s %s"
        , service.c_str() , method.c_str() , address.c_str()
    ); 
    if(reply->type == REDIS_REPLY_ERROR) {
        std::cout << __FILE__  << __LINE__ << reply->str << std::endl ; 
        freeReplyObject(reply) ; 
        exit(EXIT_FAILURE) ; 
    }
    freeReplyObject(reply) ; 
} 

std::string Redis::GetAddress(std::string service , std::string method) {
    redisReply * reply = (redisReply* ) redisCommand(conn, "hget %s %s"
        , service.c_str() , method.c_str() 
    ); 
    if(reply->type == REDIS_REPLY_ERROR) {
        std::cout << __FILE__  << __LINE__ << reply->str << std::endl ; 
        freeReplyObject(reply) ; 
        exit(EXIT_FAILURE) ; 
    }
    std::string addr = reply->str ; 
    freeReplyObject(reply) ; 
    return addr ;  // 获取到指定的ip:port
}


std::string Redis::RedisCommand(std::string command , std::string key , std::string value ) {
    redisReply * reply ; 
    
    if(value == "") {
        reply =(redisReply* ) redisCommand(conn , "%s %s" , 
        command.c_str() , key.c_str() ) ;   
    }else {
        reply =(redisReply* ) redisCommand(conn , "%s %s %s" , 
        command.c_str() , key.c_str() , value.c_str() 
        );  
    }
    
    if(reply->type == REDIS_REPLY_ERROR) {
        std::cout << __FILE__  << __LINE__ << reply->str << std::endl ; 
        freeReplyObject(reply) ; 
        exit(EXIT_FAILURE) ; 
    }
    std::string answer = reply->str ; 
    freeReplyObject(reply) ; 
    return answer ; 
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值