前言

本文是HBase实战——陌陌海量存储案例——HBase表结构设计的最后一部分, 编写数据生成器、数据服务查询数据。

4.7 编写数据生成器

4.7.1 测试工具类ExcelReader读取测试数据集
  1. 在cn.itcast.momo_chat.tool包中创建一个名为MoMoMsgGen类
  2. 在main方法中,读取资料中的测试数据集.xlsx
    Map<String, List<String>> resultMap = ExcelReader.readXlsx("D:\\课程研发\\39.HBaseV8.0\\4.资料\\数据集\\测试数据集.xlsx", "陌陌数据");
4.7.2 随机生成一条数据

编写getOneMsg方法,调用ExcelReader工具类,随机生成一条陌陌消息数据
实现步骤:

1.构建Msg实体类对象
2.调用ExcelReader中的randomColumn随机生成一个列的数据
3.注意时间使用系统当前时间

private static Msg getOneMsg(Map<String, List<String>> resultMap) {
    Msg msg = new Msg();
    long timestamp = new Date().getTime();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    msg.setMsg_time(sdf.format(timestamp));
    msg.setSender_nickyname(ExcelReader.randomColumn(resultMap, "sender_nickyname"));
    msg.setSender_account(ExcelReader.randomColumn(resultMap, "sender_account"));
    msg.setSender_sex(ExcelReader.randomColumn(resultMap, "sender_sex"));
    msg.setSender_ip(ExcelReader.randomColumn(resultMap, "sender_ip"));
    msg.setSender_os(ExcelReader.randomColumn(resultMap, "sender_os"));
    msg.setSender_phone_type(ExcelReader.randomColumn(resultMap, "sender_phone_type"));
    msg.setSender_network(ExcelReader.randomColumn(resultMap, "sender_network"));
    msg.setSender_gps(ExcelReader.randomColumn(resultMap, "sender_gps"));
    msg.setReceiver_nickyname(ExcelReader.randomColumn(resultMap, "receiver_nickyname"));
    msg.setReceiver_ip(ExcelReader.randomColumn(resultMap, "receiver_ip"));
    msg.setReceiver_account(ExcelReader.randomColumn(resultMap, "receiver_account"));
    msg.setReceiver_os(ExcelReader.randomColumn(resultMap, "receiver_os"));
    msg.setReceiver_phone_type(ExcelReader.randomColumn(resultMap, "receiver_phone_type"));
    msg.setReceiver_network(ExcelReader.randomColumn(resultMap, "receiver_network"));
    msg.setReceiver_gps(ExcelReader.randomColumn(resultMap, "receiver_gps"));
    msg.setReceiver_sex(ExcelReader.randomColumn(resultMap, "receiver_sex"));
    msg.setMsg_type(ExcelReader.randomColumn(resultMap, "msg_type"));
    msg.setDistance(ExcelReader.randomColumn(resultMap, "distance"));
    msg.setMessage(ExcelReader.randomColumn(resultMap, "message"));

    return msg;
}
4.7.3 构建ROWKEY

前面我们分析得到:
ROWKEY = MD5Hash_发件人账号_收件人账号_消息时间戳

  1. 其中MD5Hash的计算方式为:发送人账号 + “” + 收件人账号 + “” + 消息时间戳
  2. 使用MD5Hash.getMD5AsHex方法生成MD5值
  3. 取MD5值的前8位,避免过长
  4. 最后把发件人账号、收件人账号、消息时间戳和MD5拼接起来

实现步骤:

1.创建getRowkey方法,接收Msg实体对象,并根据该实体对象生成byte[]的rowkey
2.使用StringBuilder将发件人账号、收件人账号、消息时间戳使用下划线(_)拼接起来
3.使用Bytes.toBytes将拼接出来的字符串转换为byte[]数组
4.使用MD5Hash.getMD5AsHex生成MD5值,并取其前8位
5.再将MD5值和之前拼接好的发件人账号、收件人账号、消息时间戳,再使用下划线拼接,转换为Bytes数组

参考代码:

private static byte[] getRowkey(Msg msg) throws ParseException {
    // 3. 构建ROWKEY
    // 发件人ID1反转
    StringBuilder stringBuilder = new StringBuilder(msg.getSender_account());
    stringBuilder.append("_");
    stringBuilder.append(msg.getReceiver_account());
    stringBuilder.append("_");
    // 转换为时间戳
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    stringBuilder.append(sdf.parse(msg.getMsg_time()).getTime());

    byte[] orginkey = Bytes.toBytes(stringBuilder.toString());
    // 为了避免ROWKEY过长,取前八位
    String md5AsHex = MD5Hash.getMD5AsHex(orginkey).substring(0, 8);

    return Bytes.toBytes(md5AsHex + "_" + stringBuilder.toString());
}
4.7.4 数据写入HBase

实现步骤:

1.获取Hbase连接
2.获取HBase表MOMO_CHAT:MSG
3.初始化操作Hbase所需的变量(列蔟、列名)
4.构建put请求
5.挨个添加陌陌消息的所有列
6.发起put请求

构建Hbase连接

  1. 获取Hbase连接
Configuration configuration = HBaseConfiguration.create();
Connection connection = ConnectionFactory.createConnection(configuration);
  1. 获取HBase表
String TABLE_NAME = "MOMO_CHAT:MSG";
Table momoChatlTable = connection.getTable(TableName.valueOf(TABLE_NAME));
  1. 初始化操作Hbase所需的变量(列蔟、列名)
String cf_name = "C1";
String col_msg_time = "msg_time";
String col_sender_nickyname = "sender_nickyname";
String col_sender_account = "sender_account";
String col_sender_sex = "sender_sex";
String col_sender_ip = "sender_ip";
String col_sender_os = "sender_os";
String col_sender_phone_type = "sender_phone_type";
String col_sender_network = "sender_network";
String col_sender_gps = "sender_gps";
String col_receiver_nickyname = "receiver_nickyname";
String col_receiver_ip = "receiver_ip";
String col_receiver_account = "receiver_account";
String col_receiver_os = "receiver_os";
String col_receiver_phone_type = "receiver_phone_type";
String col_receiver_network = "receiver_network";
String col_receiver_gps = "receiver_gps";
String col_receiver_sex = "receiver_sex";
String col_msg_type = "msg_type";
String col_distance = "distance";
String col_message = "message";

发起put请求添加数据

  1. 构建put请求
  2. 挨个添加陌陌消息的所有列
  3. 发起put请求
    参考代码:
Msg msg = getOneMsg(resultMap);
Put put = new Put(getRowkey(msg));

put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_msg_time), Bytes.toBytes(msg.getMsg_time()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_nickyname), Bytes.toBytes(msg.getSender_nickyname()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_account), Bytes.toBytes(msg.getSender_account()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_sex), Bytes.toBytes(msg.getSender_sex()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_ip), Bytes.toBytes(msg.getSender_ip()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_os), Bytes.toBytes(msg.getSender_os()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_phone_type), Bytes.toBytes(msg.getSender_phone_type()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_network), Bytes.toBytes(msg.getSender_network()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_gps), Bytes.toBytes(msg.getSender_gps()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_nickyname), Bytes.toBytes(msg.getReceiver_nickyname()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_ip), Bytes.toBytes(msg.getReceiver_ip()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_account), Bytes.toBytes(msg.getReceiver_account()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_os), Bytes.toBytes(msg.getReceiver_os()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_phone_type), Bytes.toBytes(msg.getReceiver_phone_type()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_network), Bytes.toBytes(msg.getReceiver_network()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_gps), Bytes.toBytes(msg.getReceiver_gps()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_sex), Bytes.toBytes(msg.getReceiver_sex()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_msg_type), Bytes.toBytes(msg.getMsg_type()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_distance), Bytes.toBytes(msg.getDistance()));
put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_message), Bytes.toBytes(msg.getMessage()));

// 5. 执行put请求
momoChatlTable.put(put);
4.7.5 生成10W条数据

1.使用一个while循环,生成10W条数据
2.注意遍历的时候打印下数据生成的进度

完整代码:

/**
 * 陌陌数据生成器
 */
public class Gen {

    public static void main(String[] args) throws Exception {
        Map<String, List<String>> resultMap = ExcelReader.readXlsx("D:\\课程研发\\39.HBaseV8.0\\4.资料\\数据集\\测试数据集.xlsx", "陌陌数据");

        // 1. 获取HBase连接
        Configuration configuration = HBaseConfiguration.create();

        Connection connection = ConnectionFactory.createConnection(configuration);

        // 2. 获取HTable
        String TABLE_NAME = "MOMO_CHAT:MSG";
        Table momoChatlTable = connection.getTable(TableName.valueOf(TABLE_NAME));

        String cf_name = "C1";
        String col_msg_time = "msg_time";
        String col_sender_nickyname = "sender_nickyname";
        String col_sender_account = "sender_account";
        String col_sender_sex = "sender_sex";
        String col_sender_ip = "sender_ip";
        String col_sender_os = "sender_os";
        String col_sender_phone_type = "sender_phone_type";
        String col_sender_network = "sender_network";
        String col_sender_gps = "sender_gps";
        String col_receiver_nickyname = "receiver_nickyname";
        String col_receiver_ip = "receiver_ip";
        String col_receiver_account = "receiver_account";
        String col_receiver_os = "receiver_os";
        String col_receiver_phone_type = "receiver_phone_type";
        String col_receiver_network = "receiver_network";
        String col_receiver_gps = "receiver_gps";
        String col_receiver_sex = "receiver_sex";
        String col_msg_type = "msg_type";
        String col_distance = "distance";
        String col_message = "message";

        int i = 0;
        int max = 100000;
        while(i < max) {
            Msg msg = getOneMsg(resultMap);
            Put put = new Put(getRowkey(msg));

            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_msg_time), Bytes.toBytes(msg.getMsg_time()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_nickyname), Bytes.toBytes(msg.getSender_nickyname()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_account), Bytes.toBytes(msg.getSender_account()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_sex), Bytes.toBytes(msg.getSender_sex()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_ip), Bytes.toBytes(msg.getSender_ip()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_os), Bytes.toBytes(msg.getSender_os()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_phone_type), Bytes.toBytes(msg.getSender_phone_type()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_network), Bytes.toBytes(msg.getSender_network()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_gps), Bytes.toBytes(msg.getSender_gps()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_nickyname), Bytes.toBytes(msg.getReceiver_nickyname()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_ip), Bytes.toBytes(msg.getReceiver_ip()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_account), Bytes.toBytes(msg.getReceiver_account()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_os), Bytes.toBytes(msg.getReceiver_os()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_phone_type), Bytes.toBytes(msg.getReceiver_phone_type()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_network), Bytes.toBytes(msg.getReceiver_network()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_gps), Bytes.toBytes(msg.getReceiver_gps()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_sex), Bytes.toBytes(msg.getReceiver_sex()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_msg_type), Bytes.toBytes(msg.getMsg_type()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_distance), Bytes.toBytes(msg.getDistance()));
            put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_message), Bytes.toBytes(msg.getMessage()));

            // 5. 执行put请求
            momoChatlTable.put(put);
            System.out.println(i + " / " + max);
            ++i;
        }

        // 6. 关闭连接
        momoChatlTable.close();
        momoChatlTable.close();

    }

    private static byte[] getRowkey(Msg msg) throws ParseException {
        // 3. 构建ROWKEY
        // 发件人ID1反转
        StringBuilder stringBuilder = new StringBuilder(msg.getSender_account());
        stringBuilder.append("_");
        stringBuilder.append(msg.getReceiver_account());
        stringBuilder.append("_");
        // 转换为时间戳
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        stringBuilder.append(sdf.parse(msg.getMsg_time()).getTime());

        byte[] orginkey = Bytes.toBytes(stringBuilder.toString());
        // 为了避免ROWKEY过长,取前八位
        String md5AsHex = MD5Hash.getMD5AsHex(orginkey).substring(0, 8);

        return Bytes.toBytes(md5AsHex + "_" + stringBuilder.toString());
    }

    private static Msg getOneMsg(Map<String, List<String>> resultMap) {
        Msg msg = new Msg();
        long timestamp = new Date().getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        msg.setMsg_time(sdf.format(timestamp));
        msg.setSender_nickyname(ExcelReader.randomColumn(resultMap, "sender_nickyname"));
        msg.setSender_account(ExcelReader.randomColumn(resultMap, "sender_account"));
        msg.setSender_sex(ExcelReader.randomColumn(resultMap, "sender_sex"));
        msg.setSender_ip(ExcelReader.randomColumn(resultMap, "sender_ip"));
        msg.setSender_os(ExcelReader.randomColumn(resultMap, "sender_os"));
        msg.setSender_phone_type(ExcelReader.randomColumn(resultMap, "sender_phone_type"));
        msg.setSender_network(ExcelReader.randomColumn(resultMap, "sender_network"));
        msg.setSender_gps(ExcelReader.randomColumn(resultMap, "sender_gps"));
        msg.setReceiver_nickyname(ExcelReader.randomColumn(resultMap, "receiver_nickyname"));
        msg.setReceiver_ip(ExcelReader.randomColumn(resultMap, "receiver_ip"));
        msg.setReceiver_account(ExcelReader.randomColumn(resultMap, "receiver_account"));
        msg.setReceiver_os(ExcelReader.randomColumn(resultMap, "receiver_os"));
        msg.setReceiver_phone_type(ExcelReader.randomColumn(resultMap, "receiver_phone_type"));
        msg.setReceiver_network(ExcelReader.randomColumn(resultMap, "receiver_network"));
        msg.setReceiver_gps(ExcelReader.randomColumn(resultMap, "receiver_gps"));
        msg.setReceiver_sex(ExcelReader.randomColumn(resultMap, "receiver_sex"));
        msg.setMsg_type(ExcelReader.randomColumn(resultMap, "msg_type"));
        msg.setDistance(ExcelReader.randomColumn(resultMap, "distance"));
        msg.setMessage(ExcelReader.randomColumn(resultMap, "message"));

        return msg;
    }
}

4.8 编写数据服务查询数据

4.8.1 需求

数据存储到HBase之后,用户可能会在某一时间按照日期来查询聊天记录。例如:用户点击某一个日期,那就需要将当天用户和另外一个用户的打招呼聊天记录查询出来。也就是需要按照以下几个字段来进行查询。

  • 日期
  • 发件人
  • 收件人
4.8.2 创建接口与实现类
  1. 在cn.itcast.momo_chat.service 包下创建ChatMessageService接口,该接口有一个方法为:
    List<Msg> getMessage(String date, String sender, String receiver) throws Exception void close();
  • getMessage表示从Hbase中的消息记录根据日期、发送者账号、接受者账号查询数据,并返回一个List集合
  • close表示关闭打开的相关资源
  1. 在cn.itcast.momo_chat.service.impl包下创建HBaseNativeChatMessageService实现类,并实现getMessage方法

参考代码:

ChatMessageService接口
/**
 * 陌陌消息服务
 */
public interface ChatMessageService {
    List<Msg> getMessage(String date, String sender, String receiver) throws Exception;
    void close();
}
HbaseNativeChatMessageService实现类
/**
 * 使用HBase原生API实现数据服务
 */
public class HbaseNativeChatMessageService implements ChatMessageService {
    @Override
    public List<Msg> getMessage(String date, String sender, String receiver) throws Exception {
        return null;
    }
@Override
public void close() {
    
}
}
4.8.3 构建实现类所需对象并初始化

要使用该对象操作Hbase,我们需要提前准备以下内容:

1.Hbase连接
2.日期格式化器

添加几个字段,并在构造器中初始化它们。

构造器实现:

1.构建HBase Connection
2.构建日期格式化器

参考代码:

// Hbase连接
private Connection connection;
// 日期格式化器
private SimpleDateFormat simpleDateFormat;
4.8.4 实现close方法

在close方法中关闭连接池、表、连接。

@Override
public void close() {
    try {
        connection.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
4.8.5 实现getMessage方法

要根据日期、发件人、收件人查询消息,我们需要使用scan+filter来进行扫描。我们需要使用多个Filter组合起来进行查询。
实现步骤:

1.构建scan对象
2.构建用于查询时间的范围,例如:2020-10-05 00:00:00 – 2020-10-05 23:59:59
3.构建查询日期的两个Filter,大于等于、小于等于,此处过滤单个列使用SingleColumnValueFilter即可。
4.构建发件人Filter
5.构建收件人Filter
6.使用FilterList组合所有Filter
7.设置scan对象filter
8.获取HTable对象,并调用getScanner执行
9.获取迭代器,迭代每一行,同时迭代每一个单元格

参考实现:

  1. 构建scan对象
    Scan scan = new Scan();
  2. 构建用于查询时间的范围,例如:2020-10-05 00:00:00 – 2020-10-05 23:59:59
// 构建查询时间范围
String startDate = date + " 00:00:00";
String endDate = date + " 23:59:59";
  1. 构建查询日期的两个Filter,大于等于、小于等于,此处过滤单个列使用SingleColumnValueFilter即可。
// 构建日期查询
SingleColumnValueFilter startDateFilter = new SingleColumnValueFilter(Bytes.toBytes("C1")
        , Bytes.toBytes("msg_time")
        , CompareOperator.GREATER_OR_EQUAL
        , new BinaryComparator(Bytes.toBytes(startDate + "")));

SingleColumnValueFilter endDateFilter = new SingleColumnValueFilter(Bytes.toBytes("C1")
        , Bytes.toBytes("msg_time")
        , CompareOperator.LESS_OR_EQUAL
        , new BinaryComparator(Bytes.toBytes(endDate + "")));
  1. 构建发件人Filter
SingleColumnValueFilter senderFilter = new SingleColumnValueFilter(Bytes.toBytes("C1")
        , Bytes.toBytes("sender_account")
        , CompareOperator.EQUAL
        , new BinaryComparator(Bytes.toBytes(sender)));
  1. 构建收件人Filter
SingleColumnValueFilter receiverFilter = new SingleColumnValueFilter(Bytes.toBytes("C1")
                , Bytes.toBytes("receiver_account")
                , CompareOperator.EQUAL
                , new BinaryComparator(Bytes.toBytes(receiver)));
  1. 使用FilterList组合所有Filter
Filter filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL
        , startDateFilter
        , endDateFilter
        , senderFilter
        , receiverFilter);
  1. 设置scan对象filter
  2. 获取HTable对象,并调用getScanner执行
scan.setFilter(filterList);
ResultScanner scanner = tableMsg.getScanner(scan);
  1. 获取迭代器,迭代每一行,同时迭代每一个单元格
Iterator<Result> iter = scanner.iterator();
List<Msg> msgList = new ArrayList<>();

while(iter.hasNext()) {
    Result result = iter.next();
    Msg msg = new Msg();
    // 遍历所有列
    while(result.advance()) {
        Cell cell = result.current();
        String columnName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength());

        if(columnName.equalsIgnoreCase("msg_time")){
            msg.setMsg_time(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("sender_nickyname")){
            msg.setSender_nickyname(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("sender_account")){
            msg.setSender_account(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("sender_sex")){
            msg.setSender_sex(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("sender_ip")){
            msg.setSender_ip(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("sender_os")){
            msg.setSender_os(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("sender_phone_type")){
            msg.setSender_phone_type(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("sender_network")){
            msg.setSender_network(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("sender_gps")){
            msg.setSender_gps(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("receiver_nickyname")){
            msg.setReceiver_nickyname(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("receiver_ip")){
            msg.setReceiver_ip(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("receiver_account")){
            msg.setReceiver_account(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("receiver_os")){
            msg.setReceiver_os(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("receiver_phone_type")){
            msg.setReceiver_phone_type(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("receiver_network")){
            msg.setReceiver_network(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("receiver_gps")){
            msg.setReceiver_gps(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("receiver_sex")){
            msg.setReceiver_sex(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("msg_type")){
            msg.setMsg_type(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("distance")){
            msg.setDistance(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
        if(columnName.equalsIgnoreCase("message")){
            msg.setMessage(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }

        msgList.add(msg);
    }
}
4.8.6 测试

调用查询方法,检查是否能够根据指定的条件查询出数据

参考代码:

public static void main(String[] args) throws Exception{
    HBaseNativeChatMessageService hbaseNativeChatMessageService = new HBaseNativeChatMessageService ();
    List<Msg> message = hbaseNativeChatMessageService.getMessage("2020-08-24", "13504113666", "18182767005");

    for (Msg msg : message) {
        System.out.println(msg);
    }

    hbaseNativeChatMessageService.close();
}
4.8.7 完整代码
/**
 * 使用HBase原生API实现数据服务
 */
public class HBaseNativeChatMessageService implements ChatMessageService {
    private Connection connection;
    private SimpleDateFormat sdf;
    private ExecutorService executorServiceMsg;
    private Table tableMsg;

    public HBaseNativeChatMessageService() {
        try {
            Configuration cfg = HBaseConfiguration.create();
            connection = ConnectionFactory.createConnection(cfg);
            sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            executorServiceMsg = Executors.newFixedThreadPool(5);
            tableMsg = connection.getTable(TableName.valueOf("MOMO_CHAT:MSG"), executorServiceMsg);
        } catch (IOException e) {
            System.out.println("**获取HBase连接失败**");
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据日期、发件人、收件人查询消息
     * @param date
     * @param sender
     * @param receiver
     * @return
     */
    @Override
    public List<Msg> getMessage(String date, String sender, String receiver) throws Exception {
        if(connection == null) throw new RuntimeException("未初始化HBase连接!");

        // 构建scan对象
        Scan scan = new Scan();
        // 构建Start ROWKEY
        String startDate = date + " 00:00:00";
        String endDate = date + " 23:59:59";

        // 构建Filter
        // 构建日期查询
        SingleColumnValueFilter startDateFilter = new SingleColumnValueFilter(Bytes.toBytes("C1")
                , Bytes.toBytes("msg_time")
                , CompareOperator.GREATER_OR_EQUAL
                , new BinaryComparator(Bytes.toBytes(startDate + "")));

        SingleColumnValueFilter endDateFilter = new SingleColumnValueFilter(Bytes.toBytes("C1")
                , Bytes.toBytes("msg_time")
                , CompareOperator.LESS_OR_EQUAL
                , new BinaryComparator(Bytes.toBytes(endDate + "")));

        SingleColumnValueFilter senderFilter = new SingleColumnValueFilter(Bytes.toBytes("C1")
                , Bytes.toBytes("sender_account")
                , CompareOperator.EQUAL
                , new BinaryComparator(Bytes.toBytes(sender)));

        SingleColumnValueFilter receiverFilter = new SingleColumnValueFilter(Bytes.toBytes("C1")
                , Bytes.toBytes("receiver_account")
                , CompareOperator.EQUAL
                , new BinaryComparator(Bytes.toBytes(receiver)));


        Filter filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL
                , startDateFilter
                , endDateFilter
                , senderFilter
                , receiverFilter);
        scan.setFilter(filterList);
        ResultScanner scanner = tableMsg.getScanner(scan);
        Iterator<Result> iter = scanner.iterator();
        List<Msg> msgList = new ArrayList<>();

        while(iter.hasNext()) {
            Result result = iter.next();
            Msg msg = new Msg();
            // 遍历所有列
            while(result.advance()) {
                Cell cell = result.current();
                String columnName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength());

                if(columnName.equalsIgnoreCase("msg_time")){
                    msg.setMsg_time(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("sender_nickyname")){
                    msg.setSender_nickyname(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("sender_account")){
                    msg.setSender_account(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("sender_sex")){
                    msg.setSender_sex(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("sender_ip")){
                    msg.setSender_ip(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("sender_os")){
                    msg.setSender_os(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("sender_phone_type")){
                    msg.setSender_phone_type(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("sender_network")){
                    msg.setSender_network(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("sender_gps")){
                    msg.setSender_gps(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("receiver_nickyname")){
                    msg.setReceiver_nickyname(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("receiver_ip")){
                    msg.setReceiver_ip(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("receiver_account")){
                    msg.setReceiver_account(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("receiver_os")){
                    msg.setReceiver_os(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("receiver_phone_type")){
                    msg.setReceiver_phone_type(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("receiver_network")){
                    msg.setReceiver_network(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("receiver_gps")){
                    msg.setReceiver_gps(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("receiver_sex")){
                    msg.setReceiver_sex(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("msg_type")){
                    msg.setMsg_type(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("distance")){
                    msg.setDistance(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
                if(columnName.equalsIgnoreCase("message")){
                    msg.setMessage(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }

                msgList.add(msg);
            }
        }

        return msgList;
    }

    public void close() {
        try {
            connection.close();
            tableMsg.close();
            executorServiceMsg.shutdown();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception{
        HBaseNativeChatMessageService hbaseNativeChatMessageService = new HBaseNativeChatMessageService();
        List<Msg> message = hbaseNativeChatMessageService.getMessage("2020-08-24", "13504113666", "18182767005");

        for (Msg msg : message) {
            System.out.println(msg);
        }

        hbaseNativeChatMessageService.close();
    }
}