扫描操作的使用跟get()方法非常相似。同样,和其他函数类似,这里也提供了Scan类。但是由于扫描的工作方式类似于迭代器,所以用户无需调用scan()方法创建实例,只需调用HTable的getScanner()方法,此方法在返回真正的扫描器(scanner)实例的同时,用户也可以使用它迭代获取数据。可用方法如下:
ResultScanner getScanner(Scan scan) throws IOException
ResultScanner getScanner(byte[] family) throws IOException
ResultScanner getScanner(byte[] family,byte[] qualifier) throws IOException
后两个为了方便用户,隐式地帮用户创建了一个Scan实例,逻辑中最后调用getScanner(Scan scan)方法。
Scan类拥有以下构造器:
Scan()
Scan(byte[] startRow,Filter filter)
Scan(byte[] startRow)
Scan(byte[] startRow,byte[] stopRow)
这与Get类不同点是显而易见的:用户可以选择性地提供startRow参数,来定义扫描读取HBase表的起始行键,即行键不是必须指定的。同时可选stopRow参数来限定读取到何处停止。
起始行包括在内,而终止行时不包括在内。一般用区间表示法表示为[startRow,stopRow)。
扫描操作有一个特点:用户提供的参数不必精确匹配这两行。扫描会匹配相等或大于给定的起始行的行键。如果没有显式地指定起始行,它会从表的起始位置开始获取数据。
当遇到了与设置的终止行相同或大于终止行的行键时,扫描也会停止。如果没有指定终止行键,会扫描到表尾。
另一个可选参数叫做过滤器(filter),可直接指向Filter实例。尽管Scan实例通常由空白构造器构造,但其所有可选参数都有对应的getter方法和setter方法。
创建Scan实例后,用户可能还要给它增加更多限制条件。这种情况下,用户任然可以使用空白参数的扫描,它可以读取整个表格,包括所有列族以及它们的所有列。可以用多种方法限制要读取的数据:
Scan addFamily(byte[] family)
Scan addColumn(byte[] family,byte[] qualifier)
这里有很多与Get类相似的功能:可以使用addFamily()方法限制返回数据的列族,或者通过addColumn()方法限制返回的列。
如果用户只需要数据的子集,那么限制扫描的范围就能发挥HBase的优势。因为HBase中的数据是按列族存储的,如果扫描不读取某个列族,那么整个列族文件就都不会被读取,这就是列式存储架构的优势。
Scan setTimeRange(long minStamp,long maxStamp) throws IOExcepiton
Scan setTimeStamp(long timestamp)
Scan setMaxVersions()
Scan setMaxVersions(int maxVersions)
用户可以通过setTimestamp()设置详细的时间戳,或者通过setTimeRange()设置时间范围,进一步对结果进行限制。还可以使用setMaxVersions()方法,让扫描只返回每一列的一些特定版本,或者全部的版本
Scan setStartRow(byte[] startRow)
Scan setStopRow(byte[] stopRow)
Scan setFilter(Filter filter)
boolean hasFilter()
还可以使用setStartRow()、setStopRow()以及setFilter(),进一步限定返回的数据。这3个方法中的参数可以与构造器中的一样。Scan类的其他方法如下
方法 | 描述 |
---|---|
getStartRow()/getStopRow() | 查询当前设定的值 |
getTimeRange() | 检索Get实例指定的时间范围或相关时间戳,注意,当需要指定单个时间戳时,API会在内部通过setTimeStamp()将TimeRange实例的起止时间戳设为传入值,所以Get类中此时已经没有getTimeStamp()方法了 |
getMaxVersions() | 返回当前配置下应该从表中获取的每列的版本数 |
getFilter() | 可以使用特定的过滤器实例,通过多种规则来筛选列和单元格。使用这个方法,用户可以设定或查看Scan实例的过滤器成员。 |
setCacheBlocks()/getCacheBlocks() | 每个HBase的region服务器都有一个块缓存,可以有效地保存最近访问过的数据,并以此来加速之后相邻信息的读取。不过在某些情况下,例如通过全表扫描,最好能避免这种机制带来的扰动。这个方法能够控制版本次读取的块缓存机制是否起效 |
numFamilies() | 快捷地获取FamilyMap大小的方法,包括用addFamily()和addColumn()方法添加的列族和列 |
hasFamilies() | 检查是否添加过列族和列 |
getFamilies/setFamilyMap()/getFamilyMap() | 这些方法能够让用户直接访问addFamily()和addColumn()添加的列族和列。FamilyMap中键是列族的名称,键对应的值是特定列族下列限定符的列表。getFamilies()方法返回一个只包含列族名的数组 |
一旦设置好了Scan实例,就可以调用Htable的getScanner()方法,获得用于检索数据的ResultScanner实例。