使用QT编写C++工程(通过Thrift)访问/操作/读写Hbase

34 篇文章 0 订阅

背景:
现项目需要使用c++连接hbase,但是网上资料参差不齐,没有完整的连接项目。通过自己整理与查阅资料,现整理步骤如下(windows环境):

1、下载thrift,并配置环境变量

在这里插入图片描述

2、用Thrift 生成访问Hbase所需的C++文件

注意:使用thrift连接hbase有两种方式,分别对应thrift与thrift2(.thrift文件在hbase源码文件夹中,路径如下图)

在这里插入图片描述
在这里插入图片描述
将.thrift文件放置到文件夹,进入cmd输入命令: thrift --gen cpp XXX.thrift 就会形成如下c文件
在这里插入图片描述
注意:获取连接hbase的c文件另一种方式是编译hbase源码,c文件所在路径如下图
在这里插入图片描述

3、新建QT或者其它c++项目,在工作区间导入编译好的thrift,boost。

①工程目录(QT)
在这里插入图片描述
②工程工作区间
在这里插入图片描述
划横线的部分是事先编译好的boost与thrift,随便下载源文件百度一下编译过程,本文不赘述。

4、编写连接demo

#include <QCoreApplication>
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>

#include "Hbase.h"


using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;

using namespace apache::hadoop::hbase::thrift;


namespace {

typedef std::vector<std::string> StrVec;
typedef std::map<std::string,std::string> StrMap;
typedef std::vector<ColumnDescriptor> ColVec;
typedef std::map<std::string,ColumnDescriptor> ColMap;
typedef std::vector<TCell> CellVec;
typedef std::map<std::string,TCell> CellMap;


static void
printRow(const std::vector<TRowResult> &rowResult)
{
  for (size_t i = 0; i < rowResult.size(); i++) {
    std::cout << "row: " << rowResult[i].row << ", cols: ";
    for (CellMap::const_iterator it = rowResult[i].columns.begin();
         it != rowResult[i].columns.end(); ++it) {
      std::cout << it->first << " => " << it->second.value << "; ";
    }
    std::cout << std::endl;
  }
}

static void
printVersions(const std::string &row, const CellVec &versions)
{
  std::cout << "row: " << row << ", values: ";
  for (CellVec::const_iterator it = versions.begin(); it != versions.end(); ++it) {
    std::cout << (*it).value << "; ";
  }
  std::cout << std::endl;
}

}

int
main(int argc, char** argv)
{
//  if (argc < 3) {
//    std::cerr << "Invalid arguments!\n" << "Usage: DemoClient host port" << std::endl;
//    return -1;
//  }

  QCoreApplication a(argc, argv);

  bool isFramed = false;
//  std::shared_ptr<TTransport> socket(new TSocket(argv[1], boost::lexical_cast<int>(argv[2])));
  //连接IP,端口号
  std::shared_ptr<TTransport> socket(new TSocket("XXX.XXX.XXX.XXX", 9090));
  std::shared_ptr<TTransport> transport;

  if (isFramed) {
    transport.reset(new TFramedTransport(socket));
  } else {
    transport.reset(new TBufferedTransport(socket));
  }
  std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));

  const std::map<Text, Text>  dummyAttributes; // see HBASE-6806 HBASE-4658
  HbaseClient client(protocol);
  try {
    transport->open();

    std::string t("C002");
//-------------------------------------------------------------------------------------
    //
    // Scan all tables, look for the demo table and delete it.
    //
//    std::cout << "scanning tables..." << std::endl;
//    StrVec tables;
//    client.getTableNames(tables);
//    for (StrVec::const_iterator it = tables.begin(); it != tables.end(); ++it) {
//      std::cout << "  found: " << *it << std::endl;
//      if (t == *it) {
//        if (client.isTableEnabled(*it)) {
//          std::cout << "    disabling table: " << *it << std::endl;
//          client.disableTable(*it);
//        }
//        std::cout << "    deleting table: " << *it << std::endl;
//        client.deleteTable(*it);
//      }
//    }
//-------------------------------------------------------------------------------------
    //
    // Create the demo table with two column families, entry: and unused:
    //
    ColVec columns;
    columns.push_back(ColumnDescriptor());
    columns.back().name = "entry:";
    columns.back().maxVersions = 10;//版本保留
    columns.push_back(ColumnDescriptor());
    columns.back().name = "unused:";

    std::cout << "creating table: " << t << std::endl;
    try {
      client.createTable(t, columns);
    } catch (const AlreadyExists &ae) {
      std::cerr << "WARN: " << ae.message << std::endl;
    }
//    // 获取表格列族
      ColMap columnMap;
//    client.getColumnDescriptors(columnMap, t);
//    std::cout << "column families in " << t << ": " << std::endl;
//    for (ColMap::const_iterator it = columnMap.begin(); it != columnMap.end(); ++it) {
//      std::cout << "  column: " << it->second.name << ", maxVer: " << it->second.maxVersions << std::endl;
//    }

//    //
//    // Test UTF-8 handling
//    //
//    std::string invalid("foo-\xfc\xa1\xa1\xa1\xa1\xa1");
//    std::string valid("foo-\xE7\x94\x9F\xE3\x83\x93\xE3\x83\xBC\xE3\x83\xAB");

//    // non-utf8 is fine for data
      std::vector<Mutation> mutations;
//    mutations.push_back(Mutation());
//    mutations.back().column = "entry:foo";
//    mutations.back().value = invalid;
//    client.mutateRow(t, "foo", mutations, dummyAttributes);

//    // try empty strings
//    mutations.clear();
//    mutations.push_back(Mutation());
//    mutations.back().column = "entry:";
//    mutations.back().value = "";
//    client.mutateRow(t, "", mutations, dummyAttributes);

//    // this row name is valid utf8
//    mutations.clear();
//    mutations.push_back(Mutation());
//    mutations.back().column = "entry:foo";
//    mutations.back().value = valid;
//    client.mutateRow(t, valid, mutations, dummyAttributes);

//    // non-utf8 is now allowed in row names because HBase stores values as binary
//    mutations.clear();
//    mutations.push_back(Mutation());
//    mutations.back().column = "entry:foo";
//    mutations.back().value = invalid;
//    client.mutateRow(t, invalid, mutations, dummyAttributes);

//    // Run a scanner on the rows we just created
      StrVec columnNames;
      columnNames.push_back("entry:");
//    //扫描表格每行的值
//    std::cout << "Starting scanner..." << std::endl;
      int scanner = client.scannerOpen(t, "", columnNames, dummyAttributes);
//    try {
//      while (true) {
//        std::vector<TRowResult> value;
//        client.scannerGet(value, scanner);
//        if (value.size() == 0)
//          break;
//        printRow(value);
//      }
//    } catch (const IOError &ioe) {
//      std::cerr << "FATAL: Scanner raised IOError" << std::endl;
//    }
//    //关闭扫描
//    client.scannerClose(scanner);
//    std::cout << "Scanner finished" << std::endl;
//-------------------------------------------------------------------------------------

//     Run some operations on a bunch of rows.

    for (int i = 100; i >= 0; --i) {
      // format row keys as "00000" to "00100"
      char buf[32];
      sprintf(buf, "%05d", i);
      std::string row(buf);
      std::vector<TRowResult> rowResult;

      mutations.clear();
      mutations.push_back(Mutation());
      mutations.back().column = "unused:";
      mutations.back().value = "DELETE_ME";
      client.mutateRow(t, row, mutations, dummyAttributes);
      client.getRow(rowResult, t, row, dummyAttributes);
      printRow(rowResult);
      //删除行
      //client.deleteAllRow(t, row, dummyAttributes);

      mutations.clear();
      mutations.push_back(Mutation());
      mutations.back().column = "entry:num";
      mutations.back().value = "0";
      mutations.push_back(Mutation());
      mutations.back().column = "entry:foo";
      mutations.back().value = "FOO";
      client.mutateRow(t, row, mutations, dummyAttributes);
      client.getRow(rowResult, t, row, dummyAttributes);
      printRow(rowResult);

      // sleep to force later timestamp
      //poll(0, 0, 50);

      mutations.clear();
      mutations.push_back(Mutation());
      mutations.back().column = "entry:foo";
      mutations.back().isDelete = true;
      mutations.push_back(Mutation());
      mutations.back().column = "entry:num";
      mutations.back().value = "-1";
      client.mutateRow(t, row, mutations, dummyAttributes);
      client.getRow(rowResult, t, row, dummyAttributes);
      printRow(rowResult);

      mutations.clear();
      mutations.push_back(Mutation());
      mutations.back().column = "entry:num";
      mutations.back().value = boost::lexical_cast<std::string>(i);
      mutations.push_back(Mutation());
      mutations.back().column = "entry:sqr";
      mutations.back().value = boost::lexical_cast<std::string>(i*i);
      client.mutateRow(t, row, mutations, dummyAttributes);
      client.getRow(rowResult, t, row, dummyAttributes);
      printRow(rowResult);

      mutations.clear();
      mutations.push_back(Mutation());
      mutations.back().column = "entry:num";
      mutations.back().value = "-999";
      mutations.push_back(Mutation());
      mutations.back().column = "entry:sqr";
      mutations.back().isDelete = true;
      client.mutateRowTs(t, row, mutations, 1, dummyAttributes); // shouldn't override latest
      client.getRow(rowResult, t, row, dummyAttributes);
      printRow(rowResult);

      CellVec versions;
      client.getVer(versions, t, row, "entry:num", 10, dummyAttributes);
      printVersions(row, versions);
      assert(versions.size());
      std::cout << std::endl;

      try {
        std::vector<TCell> value;
        client.get(value, t, row, "entry:foo", dummyAttributes);
        if (value.size()) {
          std::cerr << "FATAL: shouldn't get here!" << std::endl;
          return -1;
        }
      } catch (const IOError &ioe) {
        // blank
      }
    }

    // scan all rows/columns

    columnNames.clear();
    client.getColumnDescriptors(columnMap, t);
    std::cout << "The number of columns: " << columnMap.size() << std::endl;
    for (ColMap::const_iterator it = columnMap.begin(); it != columnMap.end(); ++it) {
      std::cout << " column with name: " + it->second.name << std::endl;
      columnNames.push_back(it->second.name);
    }
    std::cout << std::endl;

    std::cout << "Starting scanner..." << std::endl;
    scanner = client.scannerOpenWithStop(t, "00020", "00040", columnNames, dummyAttributes);
    try {
      while (true) {
        std::vector<TRowResult> value;
        client.scannerGet(value, scanner);
        if (value.size() == 0)
          break;
        printRow(value);
      }
    } catch (const IOError &ioe) {
      std::cerr << "FATAL: Scanner raised IOError" << std::endl;
    }

    client.scannerClose(scanner);
    std::cout << "Scanner finished" << std::endl;

    transport->close();
  } catch (const TException &tx) {
    std::cerr << "ERROR: " << tx.what() << std::endl;
  }

  return a.exec();

}


5、运行项目,查看操作结果。

项目运行
在这里插入图片描述
hbase数据库查看
在这里插入图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值