• Hbase java API与过滤器


    一、Hbase java API:

    1、创建一张表
    2、删除一张表
    3、向一张表中添加一条数据
    4、向一张表中同时添加一批数据
    5、获取一条数据
    6、获取一批数据
    7、创建预分region表

    代码实现:

    1. import org.apache.hadoop.conf.Configuration;
    2. import org.apache.hadoop.hbase.*;
    3. import org.apache.hadoop.hbase.client.*;
    4. import org.apache.hadoop.hbase.util.Bytes;
    5. import org.junit.After;
    6. import org.junit.Before;
    7. import org.junit.Test;
    8. import java.io.BufferedReader;
    9. import java.io.FileReader;
    10. import java.io.IOException;
    11. import java.util.*;
    12. /*
    13. java操作数据的步骤:
    14. 1、注册驱动
    15. 2、创建数据库连接对象
    16. 3、创建数据库操作对象
    17. 4、进行增删改查
    18. 5、如果时查询的话,可以对查询的结果进行分析
    19. 6、释放资源
    20. hbase基础中要做的需求:
    21. 1、如何创建一张表
    22. 2、如何删除一张表
    23. 3、如何向一张表中添加一条数据
    24. 4、如何向一张表中同时添加一批数据
    25. 5、如何获取一条数据
    26. 6、如果获取一批数据
    27. 7、如何创建预分region表
    28. */
    29. public class HBaseAPI {
    30. private Connection conn;
    31. private Admin admin;
    32. /**
    33. * 在所有Test方法执行之前执行
    34. */
    35. @Before
    36. public void getConnection() {
    37. try {
    38. //1、获取hbase集群的配置文件对象
    39. //0.90.0之前旧版本的写法:
    40. // HBaseConfiguration conf = new HBaseConfiguration();
    41. //新版本的写法:调用静态方法public static Configuration create()
    42. Configuration conf = HBaseConfiguration.create();
    43. Properties prop = new Properties();
    44. prop.load(new BufferedReader(new FileReader("src/main/resources/hbase.properties")));
    45. String zk = (String)prop.get("hbase.zookeeper.quorum");
    46. //2、因为hbase的数据都有一条元数据,而元数据也存储在一张表中,这张元数据表也有元数据,存储在zookeeper中
    47. //配置文件要设置你自己的zookeeper集群
    48. conf.set("hbase.zookeeper.quorum",zk); //前提时windows中配置了hosts映射
    49. //3、获取数据库的连接对象
    50. conn = ConnectionFactory.createConnection(conf);
    51. //4、获取数据库操作对象
    52. // HBaseAdmin hBaseAdmin = new HBaseAdmin(conn);
    53. //新版本的做法
    54. admin = conn.getAdmin(); //使用连接对象获取数据库操作对象
    55. System.out.println("数据库连接对象获取成功!!" + conn);
    56. System.out.println("数据库操作对象获取成功!!" + admin);
    57. System.out.println("==========================================");
    58. } catch (Exception e) {
    59. e.printStackTrace();
    60. }
    61. }
    62. /**
    63. * 需求1: 1、如何创建一张表
    64. * create 'students','info' 必须要有表名和列簇的名
    65. */
    66. @Test
    67. public void createOneTable() {
    68. try {
    69. //先将表名封装成一个TableName的对象
    70. TableName tn = TableName.valueOf("students2");
    71. //HTableDescriptor类已经在2.0.0版本之后就过时了,并且在3.0.0之后完全被删除
    72. //新版本不能使用这个类
    73. // HTableDescriptor students = new HTableDescriptor(tn);
    74. //新版本使用 TableDescriptorBuilder 类来创建并获取表描述器对象
    75. //public static TableDescriptorBuilder newBuilder(final TableName name)
    76. TableDescriptorBuilder students = TableDescriptorBuilder.newBuilder(tn);
    77. //旧版本创建列簇描述器对象
    78. // HColumnDescriptor info = new HColumnDescriptor("info");
    79. //新版本中ColumnFamilyDescriptorBuilder.of(String).
    80. ColumnFamilyDescriptor info = ColumnFamilyDescriptorBuilder.of("info");
    81. //将列簇与表进行关联
    82. //旧版本中表描述器调用addColumnFamily方法将列簇描述器添加到表中
    83. // students.addColumnFamily(info);
    84. //新版本中使用setColumnFamily
    85. students.setColumnFamily(info);
    86. //调用方法,创建表
    87. // createTable(TableDescriptor desc)
    88. // TableDescriptorBuilder
    89. admin.createTable(students.build());
    90. System.out.println(tn + "表创建成功!!!");
    91. } catch (Exception e) {
    92. System.out.println("表创建失败!!");
    93. e.printStackTrace();
    94. }
    95. }
    96. /**
    97. * 需求:2、如何删除一张表
    98. * disable 'students'
    99. * drop 'students'
    100. */
    101. @Test
    102. public void dropOneTable() {
    103. try {
    104. //先将表名封装成一个TableName的对象
    105. TableName tn = TableName.valueOf("tb_split2");
    106. //判断表是否存在
    107. if (admin.tableExists(tn)) {
    108. //先禁用表
    109. admin.disableTable(tn);
    110. //使用admin对象调用方法删除表
    111. //void deleteTable(TableName tableName)
    112. admin.deleteTable(tn);
    113. System.out.println(tn + "表成功被删除");
    114. } else {
    115. System.out.println(tn + "表不存在!!");
    116. }
    117. } catch (Exception e) {
    118. e.printStackTrace();
    119. }
    120. }
    121. /**
    122. * 需求:3、如何向一张表中添加一条数据
    123. * put 'students','1001','info:name','小虎'
    124. */
    125. @Test
    126. public void putOneDataToTable() {
    127. try {
    128. //先将表名封装成一个TableName的对象
    129. TableName tn = TableName.valueOf("students");
    130. //判断表是否存在
    131. if (admin.tableExists(tn)) {
    132. //获取表对象
    133. Table students = conn.getTable(tn);
    134. //创建Put对象
    135. // Put put = new Put("1001".getBytes());//行键的字节数组形式
    136. // //对put对象进行设置,添加列簇,列名和列值
    137. // put.addColumn("info".getBytes(),"name".getBytes(),"小虎".getBytes());
    138. //hbase自带的一个工具类Bytes,可以将字符串转字节数组
    139. Put put = new Put(Bytes.toBytes("1001"));//行键的字节数组形式
    140. //对put对象进行设置,添加列簇,列名和列值 以前的写法
    141. // put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("name"),Bytes.toBytes("小虎"));
    142. //public Put add(Cell cell) 新版本另外一种设置put对象的方式
    143. //Cell 是一个接口,无法被实例化,使用实现类KeyValue来创建对象
    144. //KeyValue(final byte [] row, final byte [] family, final byte [] qualifier, final byte [] value)
    145. put.add(new KeyValue(Bytes.toBytes("1001"),
    146. Bytes.toBytes("info"),
    147. Bytes.toBytes("age"),
    148. Bytes.toBytes(18)));
    149. //void put(Put put)
    150. //需要先将我们添加的列数据封装成一个Put对象
    151. students.put(put);
    152. } else {
    153. System.out.println(tn + "表不存在!!");
    154. }
    155. } catch (Exception e) {
    156. e.printStackTrace();
    157. }
    158. }
    159. /**
    160. * 需求:4、如何向一张表中同时添加一批数据
    161. */
    162. @Test
    163. public void putMoreDataToTable() {
    164. BufferedReader br = null;
    165. try {
    166. //先将表名封装成一个TableName的对象
    167. TableName tn = TableName.valueOf("students2");
    168. //创建字符输入缓冲流
    169. br = new BufferedReader(new FileReader("data/students.csv"));
    170. String[] colNameArray = {"", "name", "age", "gender", "clazz"};
    171. //判断表是否存在
    172. if (admin.tableExists(tn)) {
    173. //获取表对象
    174. Table students = conn.getTable(tn);
    175. //循环读取数据
    176. String line = null;
    177. while ((line = br.readLine()) != null) {
    178. String[] info = line.split(",");
    179. byte[] rowKey = Bytes.toBytes(info[0]);
    180. //创建这一行的Put对象
    181. Put put = new Put(rowKey);
    182. //第一列作为行键唯一标识,从第二列开始,每一列都要被封装成Put对象
    183. for (int i = 1; i < info.length; i++) {
    184. byte[] colName = Bytes.toBytes(info[i]);
    185. put.addColumn(Bytes.toBytes("info"), Bytes.toBytes(colNameArray[i]), Bytes.toBytes(info[i]));
    186. //添加该列数据
    187. students.put(put);
    188. }
    189. }
    190. System.out.println("学生表数据添加完毕!!!!");
    191. } else {
    192. System.out.println(tn + "表不存在!!");
    193. }
    194. } catch (Exception e) {
    195. e.printStackTrace();
    196. } finally {
    197. if (br != null) {
    198. try {
    199. br.close();
    200. } catch (IOException e) {
    201. e.printStackTrace();
    202. }
    203. }
    204. }
    205. }
    206. /**
    207. * 需求:5、如何获取一条数据
    208. * get 'students','1500101000'
    209. */
    210. @Test
    211. public void getOneData() {
    212. try {
    213. //将表名封装TableName对象
    214. TableName sd = TableName.valueOf("students");
    215. //获取表的对象
    216. Table students = conn.getTable(sd);
    217. //传入行键的字节数组的形式
    218. Get get = new Get(Bytes.toBytes("1500101000"));
    219. //default Result get(Get get)
    220. Result result = students.get(get);
    221. // System.out.println(result);
    222. /**
    223. * Result类中的常用方法:
    224. * getRow() : 获取行键的字节数组形式
    225. * getValue(byte [] family, byte [] qualifier): 根据列簇和列名,获取列值的字节数组形式
    226. * List listCells():获取所有单元格,单元格中存储了行键,列簇,列名,版本号(时间戳),列值
    227. */
    228. String id = Bytes.toString(result.getRow());
    229. //在已经知道列名的前提之下获取对应的列值
    230. // String name = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("name")));
    231. // String age = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("age")));
    232. // String gender = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("gender")));
    233. // String clazz = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("clazz")));
    234. // System.out.println("学号:"+id+",姓名:"+name+",年龄:"+age+",性别:"+gender+",班级:"+clazz);
    235. //当不清楚列名的时候该如何获取呢?
    236. //获取一行中的所有单元格组合的集合
    237. List cells = result.listCells(); //获取的结果值的顺序是hbase中存储排序后的顺序
    238. //遍历集合得到每个单元格,获取每个列值
    239. /**
    240. * hbase中除了提供一个Bytes工具类给我们使用以外,还提供了另外的一个工具类:CellUtil
    241. * 该工具类主要的操作对象是Cell类的对象
    242. */
    243. //遍历方式1:普通for循环遍历
    244. //遍历方式2:增强for循环遍历
    245. // for (Cell cell : cells) {
    246. // String colName = Bytes.toString(CellUtil.cloneQualifier(cell));
    247. // String colValue = Bytes.toString(CellUtil.cloneValue(cell));
    248. // System.out.println(colName + ":" + colValue);
    249. // }
    250. //遍历方式3:forEach + lambda表达式
    251. // cells.forEach(e -> {
    252. // String colName = Bytes.toString(CellUtil.cloneQualifier(e));
    253. // String colValue = Bytes.toString(CellUtil.cloneValue(e));
    254. // System.out.println(colName + ":" + colValue);
    255. // });
    256. //遍历方式4:jdk1.8新特性遍历,转流处理
    257. cells.stream().map(e -> {
    258. String colName = Bytes.toString(CellUtil.cloneQualifier(e));
    259. String colValue = Bytes.toString(CellUtil.cloneValue(e));
    260. // System.out.println(colName + ":" + colValue);
    261. return colName + ":" + colValue;
    262. }).forEach(System.out::println);
    263. } catch (Exception e) {
    264. e.printStackTrace();
    265. }
    266. }
    267. /**
    268. * 6、如果获取一批数据 第一种方式
    269. */
    270. @Test
    271. public void getMoreData() {
    272. try {
    273. //将表名封装TableName对象
    274. TableName sd = TableName.valueOf("students");
    275. //获取表的对象
    276. Table students = conn.getTable(sd);
    277. //创建List集合,存储多个Get对象
    278. //1500100001 ~ 1500101000
    279. ArrayList gets = new ArrayList<>();
    280. for (int i = 1500100001; i <= 1500101000; i++) {
    281. gets.add(new Get(Bytes.toBytes(String.valueOf(i))));
    282. }
    283. //default Result[] get(List gets)
    284. Result[] results = students.get(gets);
    285. //1、先遍历results得到每一个result(每一行)
    286. //2、遍历每一个result中的每一列
    287. for (Result result : results) {
    288. List cells = result.listCells();
    289. if (cells != null) {
    290. cells.stream().map(cell -> {
    291. String colName = Bytes.toString(CellUtil.cloneQualifier(cell));
    292. String colValue = Bytes.toString(CellUtil.cloneValue(cell));
    293. // System.out.println(colName + ":" + colValue);
    294. return colName + ":" + colValue;
    295. }).forEach(System.out::println);
    296. System.out.println("-----------------");
    297. } else {
    298. System.out.println("是空");
    299. }
    300. }
    301. } catch (Exception e) {
    302. e.printStackTrace();
    303. }
    304. }
    305. /**
    306. * 7、如果获取一批数据 第二种方式
    307. * scan 'students' 默认情况下获取表所有数据
    308. * scan 'students',LIMIT=>3
    309. */
    310. @Test
    311. public void ScanData() {
    312. try {
    313. TableName sd = TableName.valueOf("students");
    314. Table students = conn.getTable(sd);
    315. //创建Scan对象
    316. Scan scan = new Scan(); //查询表中的所有行
    317. //设置开始行和结束行
    318. //旧版本写法
    319. // scan.setStartRow(Bytes.toBytes("1500100001"));
    320. // scan.setStopRow(Bytes.toBytes("1500100004"));
    321. //新版本写法
    322. // scan.withStartRow(Bytes.toBytes("1500100001"));
    323. // scan.withStopRow(Bytes.toBytes("1500100004"), true);
    324. //设置取前几行
    325. scan.setLimit(10);
    326. //default ResultScanner getScanner(Scan scan)
    327. ResultScanner resultScanner = students.getScanner(scan);
    328. //通过观察源码发现,可以先获取迭代器对象
    329. Iterator iterator = resultScanner.iterator();
    330. while (iterator.hasNext()) {
    331. Result result = iterator.next();
    332. //不知道列名的时候遍历
    333. // List cells = result.listCells();
    334. // cells.stream().map(cell->{
    335. // String colName = Bytes.toString(CellUtil.cloneQualifier(cell));
    336. // String colValue = Bytes.toString(CellUtil.cloneValue(cell));
    337. // return colName + ":" + colValue;
    338. // }).forEach(System.out::println);
    339. //知道列簇列名的时候遍历
    340. // String id = Bytes.toString(result.getRow());
    341. //在已经知道列名的前提之下获取对应的列值
    342. // String name = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("name")));
    343. // String age = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("age")));
    344. // String gender = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("gender")));
    345. // String clazz = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("clazz")));
    346. // System.out.println("学号:" + id + ",姓名:" + name + ",年龄:" + age + ",性别:" + gender + ",班级:" + clazz);
    347. printResult(result);
    348. System.out.println("-----------------");
    349. }
    350. } catch (Exception e) {
    351. e.printStackTrace();
    352. }
    353. }
    354. /**
    355. * 需求:7、如何创建预分region表
    356. * 将来对于某一个RegionServer而言,可能会接收大量的并发请求,超出了该RegionServer承受的压力,有可能会导致该子节点崩溃
    357. * 如果大量的并发请求查询的数据是多种多种多样的,只不过巧合的是都在一个RegionServer上管理
    358. * 解决的思路:分散查询的数据到不同的RegionServer上,这样请求也会随着被分散到不同的RegionServer上,就达到了减轻某一个RegionServer压力过大情况,解决了单点故障的问题
    359. */
    360. @Test
    361. public void createPreviewTable(){
    362. try {
    363. //先将表名封装成TableName对象
    364. TableName tb = TableName.valueOf("tb_split2");
    365. //创建表描述器对象
    366. TableDescriptorBuilder tbSplit2 = TableDescriptorBuilder.newBuilder(tb);
    367. //创建列簇描述器对象
    368. ColumnFamilyDescriptor info = ColumnFamilyDescriptorBuilder.of("info");
    369. //将列簇添加到表中
    370. tbSplit2.setColumnFamily(info);
    371. //创建分割键的二维数组
    372. byte[][] splitKeys = {
    373. Bytes.toBytes("f"),
    374. Bytes.toBytes("k"),
    375. Bytes.toBytes("p")
    376. };
    377. //调用方法创建表
    378. // admin.createTable(tbSplit2.build());
    379. //调用另外一个方法,传入表描述器的同时,传入分割点,创建预分region表
    380. //void createTable(TableDescriptor desc, byte[][] splitKeys)
    381. admin.createTable(tbSplit2.build(),splitKeys);
    382. System.out.println("预分region表创建成功!!!");
    383. }catch (Exception e){
    384. e.printStackTrace();
    385. }
    386. }
    387. public void printResult(Result result) {
    388. String id = Bytes.toString(result.getRow());
    389. //在已经知道列名的前提之下获取对应的列值
    390. String name = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("name")));
    391. String age = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("age")));
    392. String gender = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("gender")));
    393. String clazz = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("clazz")));
    394. System.out.println("学号:" + id + ",姓名:" + name + ",年龄:" + age + ",性别:" + gender + ",班级:" + clazz);
    395. // System.out.println("-----------------");
    396. }
    397. /**
    398. * 释放Before创建的资源,在每个Test之后执行
    399. */
    400. @After
    401. public void closeSource() {
    402. try {
    403. if (admin != null) {
    404. admin.close();
    405. }
    406. if (conn != null) {
    407. conn.close();
    408. }
    409. } catch (Exception e) {
    410. e.printStackTrace();
    411. }
    412. }
    413. }

    我们可以将上述的API实现方式封装为一个工具类HBaseUtil,方便我们后续使用:

    1. import com.shujia.bean.MyCell;
    2. import com.shujia.bean.NotFoundFilterNameException;
    3. import com.shujia.bean.NotFountComparatorException;
    4. import jdk.nashorn.internal.codegen.types.BooleanType;
    5. import org.apache.hadoop.conf.Configuration;
    6. import org.apache.hadoop.hbase.*;
    7. import org.apache.hadoop.hbase.client.*;
    8. import org.apache.hadoop.hbase.filter.*;
    9. import org.apache.hadoop.hbase.regionserver.BloomType;
    10. import org.apache.hadoop.hbase.util.Bytes;
    11. import org.junit.After;
    12. import org.junit.Test;
    13. import java.io.BufferedReader;
    14. import java.io.FileReader;
    15. import java.io.IOException;
    16. import java.util.*;
    17. public class HBaseUtil {
    18. public static Connection CONNECTION;
    19. public static Admin ADMIN;
    20. private HBaseUtil() {
    21. }
    22. /**
    23. * 获取数据库连接对象和数据库操作对象
    24. */
    25. static {
    26. try {
    27. //1、获取hbase集群的配置文件对象
    28. //0.90.0之前旧版本的写法:
    29. // HBaseConfiguration conf = new HBaseConfiguration();
    30. //新版本的写法:调用静态方法public static Configuration create()
    31. Configuration conf = HBaseConfiguration.create();
    32. //2、因为hbase的数据都有一条元数据,而元数据也存储在一张表中,这张元数据表也有元数据,存储在zookeeper中
    33. //配置文件要设置你自己的zookeeper集群
    34. // conf.set("hbase.zookeeper.quorum", "master:2181,node1:2181,node2:2181"); //前提时windows中配置了hosts映射
    35. Properties prop = new Properties();
    36. prop.load(new BufferedReader(new FileReader("E:\\projects\\IDEAProjects\\bigdata29\\hbase\\src\\main\\resources\\hbase.properties")));
    37. String zk = (String) prop.get("hbase.zookeeper.quorum");
    38. //2、因为hbase的数据都有一条元数据,而元数据也存储在一张表中,这张元数据表也有元数据,存储在zookeeper中
    39. //配置文件要设置你自己的zookeeper集群
    40. conf.set("hbase.zookeeper.quorum", zk); //前提时windows中配置了hosts映射
    41. //3、获取数据库的连接对象
    42. CONNECTION = ConnectionFactory.createConnection(conf);
    43. //4、获取数据库操作对象
    44. // HBaseAdmin hBaseAdmin = new HBaseAdmin(conn);
    45. //新版本的做法
    46. ADMIN = CONNECTION.getAdmin(); //使用连接对象获取数据库操作对象
    47. } catch (Exception e) {
    48. e.printStackTrace();
    49. }
    50. }
    51. public static void createOneTable(String tableName, String columnFamily) {
    52. try {
    53. //先将表名封装成一个TableName的对象
    54. TableName tn = TableName.valueOf(tableName);
    55. if (!ADMIN.tableExists(tn)) {
    56. TableDescriptorBuilder students = TableDescriptorBuilder.newBuilder(tn);
    57. // ColumnFamilyDescriptor info = ColumnFamilyDescriptorBuilder.of(columnFamily);
    58. //使用另外一种方式创建列簇并设置布隆过滤器
    59. ColumnFamilyDescriptor columnFamilyDescriptor = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(columnFamily))
    60. .setBloomFilterType(BloomType.ROW).build();
    61. students.setColumnFamily(columnFamilyDescriptor);
    62. ADMIN.createTable(students.build());
    63. System.out.println(tn + "表创建成功!!!");
    64. } else {
    65. System.out.println(tn + "表已经存在!");
    66. }
    67. } catch (Exception e) {
    68. System.out.println("表创建失败!!");
    69. e.printStackTrace();
    70. }
    71. }
    72. /**
    73. * 需求:2、如何删除一张表
    74. * disable 'students'
    75. * drop 'students'
    76. */
    77. public static void dropOneTable(String tableName) {
    78. try {
    79. //先将表名封装成一个TableName的对象
    80. TableName tn = TableName.valueOf(tableName);
    81. //判断表是否存在
    82. if (ADMIN.tableExists(tn)) {
    83. //先禁用表
    84. ADMIN.disableTable(tn);
    85. ADMIN.deleteTable(tn);
    86. System.out.println(tn + "表成功被删除");
    87. } else {
    88. System.out.println(tn + "表不存在!!");
    89. }
    90. } catch (Exception e) {
    91. e.printStackTrace();
    92. }
    93. }
    94. /**
    95. * 需求:3、如何向一张表中添加一条数据
    96. * put 'students','1001','info:name','小虎'
    97. */
    98. public static void putOneDataToTable(String tableName, String rowKey, String columnFamily, String colName, String colValue) {
    99. try {
    100. //先将表名封装成一个TableName的对象
    101. TableName tn = TableName.valueOf(tableName);
    102. //判断表是否存在
    103. if (ADMIN.tableExists(tn)) {
    104. //获取表对象
    105. Table students = CONNECTION.getTable(tn);
    106. //hbase自带的一个工具类Bytes,可以将字符串转字节数组
    107. Put put = new Put(Bytes.toBytes(rowKey));//行键的字节数组形式
    108. put.add(new KeyValue(Bytes.toBytes(rowKey),
    109. Bytes.toBytes(columnFamily),
    110. Bytes.toBytes(colName),
    111. Bytes.toBytes(colValue)));
    112. //void put(Put put)
    113. //需要先将我们添加的列数据封装成一个Put对象
    114. students.put(put);
    115. } else {
    116. System.out.println(tn + "表不存在!!");
    117. }
    118. } catch (Exception e) {
    119. e.printStackTrace();
    120. }
    121. }
    122. /**
    123. * 需求:5、如何获取一条数据
    124. * get 'students','1500101000'
    125. */
    126. public static List getOneData(String tableName, String rowKey) throws Exception {
    127. //将表名封装TableName对象
    128. TableName sd = TableName.valueOf(tableName);
    129. //获取表的对象
    130. Table students = CONNECTION.getTable(sd);
    131. //传入行键的字节数组的形式
    132. Get get = new Get(Bytes.toBytes(rowKey));
    133. Result result = students.get(get);
    134. //创建List集合List MyCell:行键,列簇,列名,列值,
    135. ArrayList myCells = new ArrayList<>();
    136. byte[] rk = result.getRow();
    137. //当不清楚列名的时候该如何获取呢?
    138. //获取一行中的所有单元格组合的集合
    139. List cells = result.listCells(); //获取的结果值的顺序是hbase中存储排序后的顺序
    140. //遍历集合得到每个单元格,获取每个列值
    141. for (Cell cell : cells) {
    142. byte[] family = CellUtil.cloneFamily(cell);
    143. byte[] qualifier = CellUtil.cloneQualifier(cell);
    144. byte[] value = CellUtil.cloneValue(cell);
    145. myCells.add(new MyCell(rk, family, qualifier, value));
    146. }
    147. return myCells;
    148. }
    149. /**
    150. * 7、如果获取一批数据 第二种方式
    151. * scan 'students' 默认情况下获取表所有数据
    152. * scan 'students',LIMIT=>3
    153. */
    154. public static void scanData(String tableName) {
    155. try {
    156. TableName sd = TableName.valueOf(tableName);
    157. Table students = CONNECTION.getTable(sd);
    158. //创建Scan对象
    159. Scan scan = new Scan(); //查询表中的所有行
    160. //default ResultScanner getScanner(Scan scan)
    161. ResultScanner resultScanner = students.getScanner(scan);
    162. //通过观察源码发现,可以先获取迭代器对象
    163. for (Result result : resultScanner) {
    164. printResult(result);
    165. }
    166. } catch (Exception e) {
    167. e.printStackTrace();
    168. }
    169. }
    170. public static void scanData(String tableName, String startRow, String endRow, boolean include) {
    171. try {
    172. TableName sd = TableName.valueOf(tableName);
    173. Table students = CONNECTION.getTable(sd);
    174. //创建Scan对象
    175. Scan scan = new Scan(); //查询表中的所有行
    176. //设置开始行和结束行
    177. if (include) {
    178. scan.withStartRow(Bytes.toBytes(startRow));
    179. scan.withStopRow(Bytes.toBytes(endRow), true);
    180. } else {
    181. scan.withStartRow(Bytes.toBytes(startRow));
    182. scan.withStopRow(Bytes.toBytes(endRow));
    183. }
    184. //default ResultScanner getScanner(Scan scan)
    185. ResultScanner resultScanner = students.getScanner(scan);
    186. //通过观察源码发现,可以先获取迭代器对象
    187. for (Result result : resultScanner) {
    188. printResult(result);
    189. }
    190. } catch (Exception e) {
    191. e.printStackTrace();
    192. }
    193. }
    194. public static void scanData(String tableName, int limit) {
    195. try {
    196. TableName sd = TableName.valueOf(tableName);
    197. Table students = CONNECTION.getTable(sd);
    198. //创建Scan对象
    199. Scan scan = new Scan(); //查询表中的所有行
    200. scan.setLimit(limit);
    201. //default ResultScanner getScanner(Scan scan)
    202. ResultScanner resultScanner = students.getScanner(scan);
    203. //通过观察源码发现,可以先获取迭代器对象
    204. for (Result result : resultScanner) {
    205. printResult(result);
    206. }
    207. } catch (Exception e) {
    208. e.printStackTrace();
    209. }
    210. }
    211. public static ResultScanner scanDataReturn(String tableName, int limit) throws Exception{
    212. TableName sd = TableName.valueOf(tableName);
    213. Table students = CONNECTION.getTable(sd);
    214. //创建Scan对象
    215. Scan scan = new Scan(); //查询表中的所有行
    216. scan.setLimit(limit);
    217. //default ResultScanner getScanner(Scan scan)
    218. return students.getScanner(scan);
    219. }
    220. /**
    221. * 需求:7、如何创建预分region表
    222. * 将来对于某一个RegionServer而言,可能会接收大量的并发请求,超出了该RegionServer承受的压力,有可能会导致该子节点崩溃
    223. * 如果大量的并发请求查询的数据是多种多种多样的,只不过巧合的是都在一个RegionServer上管理
    224. * 解决的思路:分散查询的数据到不同的RegionServer上,这样请求也会随着被分散到不同的RegionServer上,就达到了减轻某一个RegionServer压力过大情况,解决了单点故障的问题
    225. */
    226. public static void createPreviewTable(String tableName, String columnFamily, byte[][] splitKeys) {
    227. try {
    228. //先将表名封装成TableName对象
    229. TableName tb = TableName.valueOf(tableName);
    230. //创建表描述器对象
    231. TableDescriptorBuilder tbSplit2 = TableDescriptorBuilder.newBuilder(tb);
    232. //创建列簇描述器对象
    233. ColumnFamilyDescriptor info = ColumnFamilyDescriptorBuilder.of(columnFamily);
    234. //将列簇添加到表中
    235. tbSplit2.setColumnFamily(info);
    236. //调用方法创建表
    237. // admin.createTable(tbSplit2.build());
    238. //调用另外一个方法,传入表描述器的同时,传入分割点,创建预分region表
    239. //void createTable(TableDescriptor desc, byte[][] splitKeys)
    240. ADMIN.createTable(tbSplit2.build(), splitKeys);
    241. System.out.println(tableName + "预分region表创建成功!!!");
    242. } catch (Exception e) {
    243. e.printStackTrace();
    244. }
    245. }
    246. /**
    247. * 编写一个方法专门做比较过滤器的
    248. *

    249. * 需要考虑的参数:表名 过滤器 操作符 比较器 值
    250. */
    251. public static void scanDataWithCompareFilter(String tableName, String filterType, CompareOperator compareOperator,
    252. String comparatorType, String value) {
    253. try {
    254. /**
    255. * CompareFilter 是一个抽象类,无法被实例化
    256. * 但是,我们通过观察源码,可以得到一些信息,创建比较过滤器对象的时候,至少需要传入两种参数:操作符,比较器
    257. */
    258. //获取表对象
    259. TableName st = TableName.valueOf(tableName);
    260. Table students = CONNECTION.getTable(st);
    261. Scan scan = new Scan();
    262. ByteArrayComparable byteArrayComparable = null;
    263. switch (comparatorType) {
    264. case "BinaryComparator":
    265. byteArrayComparable = new BinaryComparator(Bytes.toBytes(value));
    266. break;
    267. case "BinaryPrefixComparator":
    268. byteArrayComparable = new BinaryPrefixComparator(Bytes.toBytes(value));
    269. break;
    270. case "SubstringComparator":
    271. byteArrayComparable = new SubstringComparator(value);
    272. break;
    273. default:
    274. throw new NotFountComparatorException("没有匹配的比较器!使用ComparableName获取");
    275. }
    276. //--------------------------------------------------------------------------------
    277. CompareFilter compareFilter = null;
    278. switch (filterType) {
    279. case "RowFilter":
    280. compareFilter = new RowFilter(compareOperator, byteArrayComparable);
    281. break;
    282. case "FamilyFilter":
    283. compareFilter = new FamilyFilter(compareOperator, byteArrayComparable);
    284. break;
    285. case "QualifierFilter":
    286. compareFilter = new QualifierFilter(compareOperator, byteArrayComparable);
    287. break;
    288. case "ValueFilter":
    289. compareFilter = new ValueFilter(compareOperator, byteArrayComparable);
    290. break;
    291. default:
    292. throw new NotFoundFilterNameException("没有匹配的比较过滤器!使用FilterName获取");
    293. }
    294. //--------------------------------------------------------------------------------
    295. //设置过滤器
    296. //public Scan setFilter(Filter filter)
    297. scan.setFilter(compareFilter);
    298. ResultScanner resultScanner = students.getScanner(scan);
    299. for (Result result : resultScanner) {
    300. HBaseUtil.printResult(result);
    301. }
    302. } catch (Exception e) {
    303. e.printStackTrace();
    304. }
    305. }
    306. public static void printResult(Result result) {
    307. List cells = result.listCells();
    308. StringBuffer sb = new StringBuffer();
    309. String rk = Bytes.toString(result.getRow());
    310. sb.append(rk).append(",");
    311. for (int i = 0; i < cells.size(); i++) {
    312. String fa = Bytes.toString(CellUtil.cloneFamily(cells.get(i)));
    313. String qName = Bytes.toString(CellUtil.cloneQualifier(cells.get(i)));
    314. String colName = Bytes.toString(CellUtil.cloneValue(cells.get(i)));
    315. if (i == cells.size() - 1) {
    316. sb.append(fa).append(":").append(qName).append("-").append(colName); // 1001,info:name-xiaohu,info:age-18
    317. } else {
    318. sb.append(fa).append(":").append(qName).append("-").append(colName).append(",");
    319. }
    320. }
    321. System.out.println(sb);
    322. }
    323. /**
    324. * 释放Before创建的资源,在每个Test之后执行
    325. */
    326. public static void closeSource() {
    327. try {
    328. if (ADMIN != null) {
    329. ADMIN.close();
    330. }
    331. if (CONNECTION != null) {
    332. CONNECTION.close();
    333. }
    334. } catch (Exception e) {
    335. e.printStackTrace();
    336. }
    337. }
    338. }

     

    二、过滤器

    比较过滤器:

    1、行键过滤器:RowFilter
    2、列簇过滤器:FamilyFilter
    3、列名过滤器:QualifierFilter
    4、列值过滤器:ValueFilter 

    专用过滤器:

    5、单列值过滤器:SingleColumnValueFilter

    SingleColumnValueFilter会返回满足条件的cell所在行的所有cell的值(即会返回一行数据)

    6、列值排除过滤器:SingleColumnValueExcludeFilter

    与SingleColumnValueFilter相反,会排除掉指定的列,其他的列全部返回

    7、rowkey前缀过滤器:PrefixFilter
    8、分页过滤器PageFilter
    9、包装过滤器:

    (1)SkipFilter过滤器:SkipFilter包装一个过滤器,当被包装的过滤器遇到一个需要过滤的 KeyValue 实例时,则拓展过滤整行数据。

    (2)WhileMatchFilter过滤器:WhileMatchFilter 包装一个过滤器,当被包装的过滤器遇到一个需要过滤的 KeyValue 实例时,WhileMatchFilter 则结束本次扫描,返回已经扫描到的结果。

    10、多过滤器综合查询:

    以上都是讲解单个过滤器的作用,当需要多个过滤器共同作用于一次查询的时候,就需要使用 FilterListFilterList 支持通过构造器或者 addFilter 方法传入多个过滤器。

    代码实现: 

    1. import com.shujia.bean.ComparableName;
    2. import com.shujia.bean.FilterName;
    3. import com.shujia.utils.HBaseUtil;
    4. import org.apache.hadoop.conf.Configuration;
    5. import org.apache.hadoop.hbase.CompareOperator;
    6. import org.apache.hadoop.hbase.HBaseConfiguration;
    7. import org.apache.hadoop.hbase.TableName;
    8. import org.apache.hadoop.hbase.client.*;
    9. import org.apache.hadoop.hbase.filter.*;
    10. import org.apache.hadoop.hbase.util.Bytes;
    11. import org.junit.After;
    12. import org.junit.Before;
    13. import org.junit.Test;
    14. import java.io.BufferedReader;
    15. import java.io.FileReader;
    16. import java.util.ArrayList;
    17. import java.util.Iterator;
    18. import java.util.Properties;
    19. public class HBaseFilter {
    20. private Connection conn;
    21. private Admin admin;
    22. /**
    23. * 在所有Test方法执行之前执行
    24. */
    25. @Before
    26. public void getConnection() {
    27. conn = HBaseUtil.CONNECTION;
    28. admin = HBaseUtil.ADMIN;
    29. }
    30. /**
    31. *行键过滤器RowFilter:
    32. *需求:通过RowFilter与BinaryComparator(二进制内容比较器)过滤比rowKey 1500100010小的所有值出来
    33. * 配合等值比较器BinaryComparator
    34. */
    35. @Test
    36. public void scanDataWithRowFilterAndBinaryComparator() {
    37. try {
    38. /**
    39. * CompareFilter 是一个抽象类,无法被实例化
    40. * 但是,我们通过观察源码,可以得到一些信息,创建比较过滤器对象的时候,至少需要传入两种参数:操作符,比较器
    41. */
    42. //获取表对象
    43. TableName st = TableName.valueOf("students");
    44. Table students = conn.getTable(st);
    45. Scan scan = new Scan();
    46. //创建一个BinaryComparator比较器对象
    47. BinaryComparator binaryComparator = new BinaryComparator(Bytes.toBytes("1500100010"));
    48. //创建一个行键过滤器对象
    49. //旧版本创建方式:public RowFilter(final CompareOp rowCompareOp,final ByteArrayComparable rowComparator)
    50. // RowFilter rowFilter = new RowFilter(CompareFilter.CompareOp.LESS, binaryComparator);
    51. //新版本创建方式:public RowFilter(final CompareOperator op,final ByteArrayComparable rowComparator)
    52. RowFilter rowFilter = new RowFilter(CompareOperator.LESS, binaryComparator);
    53. //设置过滤器
    54. //public Scan setFilter(Filter filter)
    55. scan.setFilter(rowFilter);
    56. ResultScanner resultScanner = students.getScanner(scan);
    57. for (Result result : resultScanner) {
    58. HBaseUtil.printResult(result);
    59. }
    60. } catch (Exception e) {
    61. e.printStackTrace();
    62. }
    63. }
    64. /**
    65. * 列簇过滤器:FamilyFilter
    66. * 需求:过滤出列簇名中包含“a”的列簇中所有数据配合包含比较器SubstringComparator
    67. */
    68. @Test
    69. public void scanDataWithFamilyFilterAndSubstringComparator() {
    70. try {
    71. /**
    72. * CompareFilter 是一个抽象类,无法被实例化
    73. * 但是,我们通过观察源码,可以得到一些信息,创建比较过滤器对象的时候,至少需要传入两种参数:操作符,比较器
    74. */
    75. //获取表对象
    76. TableName st = TableName.valueOf("users");
    77. Table students = conn.getTable(st);
    78. Scan scan = new Scan();
    79. //创建一个包含比较器
    80. SubstringComparator substringComparator = new SubstringComparator("f");
    81. //创建列簇过滤器
    82. //public FamilyFilter(final CompareOperator op, final ByteArrayComparable familyComparator)
    83. FamilyFilter familyFilter = new FamilyFilter(CompareOperator.EQUAL, substringComparator);
    84. //设置过滤器
    85. //public Scan setFilter(Filter filter)
    86. scan.setFilter(familyFilter);
    87. ResultScanner resultScanner = students.getScanner(scan);
    88. for (Result result : resultScanner) {
    89. HBaseUtil.printResult(result);
    90. }
    91. } catch (Exception e) {
    92. e.printStackTrace();
    93. }
    94. }
    95. /**
    96. * 列名过滤器:QualifierFilter
    97. * 通过QualifierFilter与SubstringComparator(包含比较器)查询列名包含 m 的列的值
    98. */
    99. @Test
    100. public void scanDataWithQualifierFilterAndSubstringComparator() {
    101. try {
    102. /**
    103. * CompareFilter 是一个抽象类,无法被实例化
    104. * 但是,我们通过观察源码,可以得到一些信息,创建比较过滤器对象的时候,至少需要传入两种参数:操作符,比较器
    105. */
    106. //获取表对象
    107. TableName st = TableName.valueOf("users");
    108. Table students = conn.getTable(st);
    109. Scan scan = new Scan();
    110. //创建一个包含比较器
    111. SubstringComparator substringComparator = new SubstringComparator("m");
    112. //创建列名过滤器
    113. //public QualifierFilter(final CompareOperator op, final ByteArrayComparable qualifierComparator)
    114. QualifierFilter qualifierFilter = new QualifierFilter(CompareOperator.EQUAL, substringComparator);
    115. //设置过滤器
    116. //public Scan setFilter(Filter filter)
    117. scan.setFilter(qualifierFilter);
    118. ResultScanner resultScanner = students.getScanner(scan);
    119. for (Result result : resultScanner) {
    120. HBaseUtil.printResult(result);
    121. }
    122. } catch (Exception e) {
    123. e.printStackTrace();
    124. }
    125. }
    126. /**
    127. * 列值过滤器(属于比较过滤器)
    128. * 通过ValueFilter与BinaryPrefixComparator(二进制前缀比较器)过滤出所有的cell中值以 "从" 开头的学生
    129. * 注意:列值过滤器只能过滤出当前符合条件的列,至于与该列属于同一行的其他列并不会返回
    130. */
    131. @Test
    132. public void scanDataWithValueFilterAndBinaryPrefixComparator() {
    133. try {
    134. /**
    135. * CompareFilter 是一个抽象类,无法被实例化
    136. * 但是,我们通过观察源码,可以得到一些信息,创建比较过滤器对象的时候,至少需要传入两种参数:操作符,比较器
    137. */
    138. //获取表对象
    139. TableName st = TableName.valueOf("students");
    140. Table students = conn.getTable(st);
    141. Scan scan = new Scan();
    142. //创建二进制前缀比较器
    143. BinaryPrefixComparator binaryPrefixComparator = new BinaryPrefixComparator(Bytes.toBytes("从"));
    144. //创建列值过滤器对象
    145. //public ValueFilter(final CompareOperator valueCompareOp, final ByteArrayComparable valueComparator)
    146. ValueFilter valueFilter = new ValueFilter(CompareOperator.EQUAL, binaryPrefixComparator);
    147. //设置过滤器
    148. //public Scan setFilter(Filter filter)
    149. scan.setFilter(valueFilter);
    150. ResultScanner resultScanner = students.getScanner(scan);
    151. for (Result result : resultScanner) {
    152. HBaseUtil.printResult(result);
    153. }
    154. } catch (Exception e) {
    155. e.printStackTrace();
    156. }
    157. }
    158. /**
    159. * 单列值过滤器(专用过滤器)
    160. * 需求:通过SingleColumnValueFilter与BinaryPrefixComparator过滤出所有的cell中值以 "从" 开头的学生
    161. */
    162. @Test
    163. public void scanDataWithSingleColumnValueFilterAndBinaryPrefixComparator() {
    164. try {
    165. /**
    166. * CompareFilter 是一个抽象类,无法被实例化
    167. * 但是,我们通过观察源码,可以得到一些信息,创建比较过滤器对象的时候,至少需要传入两种参数:操作符,比较器
    168. */
    169. //获取表对象
    170. TableName st = TableName.valueOf("students");
    171. Table students = conn.getTable(st);
    172. Scan scan = new Scan();
    173. //创建二进制前缀比较器
    174. BinaryPrefixComparator binaryPrefixComparator = new BinaryPrefixComparator(Bytes.toBytes("从"));
    175. //创建单列值过滤器
    176. //public SingleColumnValueFilter(final byte [] family, final byte [] qualifier,
    177. // final CompareOperator op,
    178. // final org.apache.hadoop.hbase.filter.ByteArrayComparable comparator)
    179. SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter(Bytes.toBytes("info"), Bytes.toBytes("name"),
    180. CompareOperator.EQUAL, binaryPrefixComparator);
    181. //设置过滤器
    182. //public Scan setFilter(Filter filter)
    183. scan.setFilter(singleColumnValueFilter);
    184. ResultScanner resultScanner = students.getScanner(scan);
    185. for (Result result : resultScanner) {
    186. HBaseUtil.printResult(result);
    187. }
    188. } catch (Exception e) {
    189. e.printStackTrace();
    190. }
    191. }
    192. /**
    193. * 列值排除过滤器
    194. * SingleColumnValueExcludeFilter
    195. * 通过SingleColumnValueExcludeFilter与BinaryComparator查询文科一班所有学生信息,最终不返回clazz列
    196. */
    197. @Test
    198. public void scanDataWithSingleColumnValueExcludeFilterAndBinaryComparator() {
    199. try {
    200. /**
    201. * CompareFilter 是一个抽象类,无法被实例化
    202. * 但是,我们通过观察源码,可以得到一些信息,创建比较过滤器对象的时候,至少需要传入两种参数:操作符,比较器
    203. */
    204. //获取表对象
    205. TableName st = TableName.valueOf("students");
    206. Table students = conn.getTable(st);
    207. Scan scan = new Scan();
    208. //创建二进制内容比较器
    209. BinaryComparator binaryComparator = new BinaryComparator(Bytes.toBytes("文科一班"));
    210. //创建列值排除过滤器
    211. //public SingleColumnValueExcludeFilter(byte[] family, byte[] qualifier,
    212. // CompareOperator op, ByteArrayComparable comparator)
    213. SingleColumnValueExcludeFilter singleColumnValueExcludeFilter = new SingleColumnValueExcludeFilter(Bytes.toBytes("info"), Bytes.toBytes("clazz"),
    214. CompareOperator.EQUAL, binaryComparator);
    215. //设置过滤器
    216. //public Scan setFilter(Filter filter)
    217. scan.setFilter(singleColumnValueExcludeFilter);
    218. ResultScanner resultScanner = students.getScanner(scan);
    219. for (Result result : resultScanner) {
    220. HBaseUtil.printResult(result);
    221. }
    222. } catch (Exception e) {
    223. e.printStackTrace();
    224. }
    225. }
    226. /**
    227. * 行键前缀过滤器 PrefixFilter
    228. * 通过PrefixFilter查询以15001001开头的所有前缀的rowkey
    229. */
    230. @Test
    231. public void scanDataWithPrefixFilter() {
    232. try {
    233. /**
    234. * CompareFilter 是一个抽象类,无法被实例化
    235. * 但是,我们通过观察源码,可以得到一些信息,创建比较过滤器对象的时候,至少需要传入两种参数:操作符,比较器
    236. */
    237. //获取表对象
    238. TableName st = TableName.valueOf("students");
    239. Table students = conn.getTable(st);
    240. Scan scan = new Scan();
    241. //PrefixFilter(final byte [] prefix)
    242. PrefixFilter prefixFilter = new PrefixFilter(Bytes.toBytes("150010093"));
    243. //设置过滤器
    244. //public Scan setFilter(Filter filter)
    245. scan.setFilter(prefixFilter);
    246. ResultScanner resultScanner = students.getScanner(scan);
    247. for (Result result : resultScanner) {
    248. HBaseUtil.printResult(result);
    249. }
    250. } catch (Exception e) {
    251. e.printStackTrace();
    252. }
    253. }
    254. /**
    255. * 分页过滤器
    256. * PageFilter
    257. * 通过PageFilter查询三页的数据,每页10条
    258. */
    259. @Test
    260. public void scanDataWithPageFilter() {
    261. try {
    262. /**
    263. * CompareFilter 是一个抽象类,无法被实例化
    264. * 但是,我们通过观察源码,可以得到一些信息,创建比较过滤器对象的时候,至少需要传入两种参数:操作符,比较器
    265. */
    266. //获取表对象
    267. TableName st = TableName.valueOf("students");
    268. Table students = conn.getTable(st);
    269. //设置几个变量
    270. //设置要查询的页数
    271. int pageNum = 5;
    272. //设置每一页要查询的条数
    273. int pageNumData = 10;
    274. //设置开始行
    275. String startRowKey = "";
    276. //创建分页过滤器对象
    277. PageFilter pageFilter = new PageFilter(pageNumData);
    278. //创建Scan的对象
    279. Scan scan = new Scan();
    280. scan.setFilter(pageFilter);
    281. for (int i = 1; i <= pageNum; i++) {
    282. System.out.println("====================当前是第 " + i + " 页=========================");
    283. //查询10条数据
    284. ResultScanner resultScanner = students.getScanner(scan);
    285. //获取该页的最后一行的行键
    286. for (Result result : resultScanner) {
    287. startRowKey = Bytes.toString(result.getRow()) + 0;
    288. //设置下一行的开始
    289. scan.withStartRow(Bytes.toBytes(startRowKey));
    290. HBaseUtil.printResult(result);
    291. }
    292. }
    293. } catch (Exception e) {
    294. e.printStackTrace();
    295. }
    296. }
    297. /**
    298. * 包装过滤器之SkipFilter过滤器
    299. *
    300. * 1500100071,祖昌勋,22,男,理科四班
    301. */
    302. @Test
    303. public void scanDataWithSkipFilter(){
    304. try {
    305. /**
    306. * CompareFilter 是一个抽象类,无法被实例化
    307. * 但是,我们通过观察源码,可以得到一些信息,创建比较过滤器对象的时候,至少需要传入两种参数:操作符,比较器
    308. */
    309. //获取表对象
    310. TableName st = TableName.valueOf("students");
    311. Table students = conn.getTable(st);
    312. Scan scan = new Scan();
    313. ValueFilter valueFilter = new ValueFilter(CompareOperator.NOT_EQUAL, new SubstringComparator("理科"));
    314. //创建跳过过滤器
    315. //SkipFilter(Filter filter)
    316. SkipFilter skipFilter = new SkipFilter(valueFilter);
    317. scan.setFilter(skipFilter);
    318. ResultScanner resultScanner = students.getScanner(scan);
    319. for (Result result : resultScanner) {
    320. HBaseUtil.printResult(result);
    321. }
    322. } catch (Exception e) {
    323. e.printStackTrace();
    324. }
    325. }
    326. /**
    327. * 包装过滤器之WhileMatchFilter过滤器
    328. *
    329. * 1500100071,祖昌勋,22,男,理科四班
    330. */
    331. @Test
    332. public void scanDataWithWhileMatchFilter(){
    333. try {
    334. /**
    335. * CompareFilter 是一个抽象类,无法被实例化
    336. * 但是,我们通过观察源码,可以得到一些信息,创建比较过滤器对象的时候,至少需要传入两种参数:操作符,比较器
    337. */
    338. //获取表对象
    339. TableName st = TableName.valueOf("students");
    340. Table students = conn.getTable(st);
    341. Scan scan = new Scan();
    342. ValueFilter valueFilter = new ValueFilter(CompareOperator.NOT_EQUAL, new SubstringComparator("祖昌勋"));
    343. //创建跳过过滤器
    344. //SkipFilter(Filter filter)
    345. WhileMatchFilter whileMatchFilter = new WhileMatchFilter(valueFilter);
    346. scan.setFilter(whileMatchFilter);
    347. ResultScanner resultScanner = students.getScanner(scan);
    348. for (Result result : resultScanner) {
    349. HBaseUtil.printResult(result);
    350. }
    351. } catch (Exception e) {
    352. e.printStackTrace();
    353. }
    354. }
    355. /**
    356. * 组合过滤器
    357. * 需求:通过运用4种比较器过滤出姓于,年纪大于22岁,性别为女,且是理科的学生。
    358. */
    359. @Test
    360. public void scanDataWithGroupFilter(){
    361. try {
    362. /**
    363. * CompareFilter 是一个抽象类,无法被实例化
    364. * 但是,我们通过观察源码,可以得到一些信息,创建比较过滤器对象的时候,至少需要传入两种参数:操作符,比较器
    365. */
    366. //获取表对象
    367. TableName st = TableName.valueOf("students");
    368. Table students = conn.getTable(st);
    369. Scan scan = new Scan();
    370. //创建单列值过滤器
    371. //过滤出姓于的
    372. SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter(Bytes.toBytes("info"), Bytes.toBytes("name"),
    373. CompareOperator.EQUAL, new BinaryPrefixComparator(Bytes.toBytes("于")));
    374. //年纪大于22岁
    375. SingleColumnValueFilter singleColumnValueFilter1 = new SingleColumnValueFilter(Bytes.toBytes("info"), Bytes.toBytes("age"),
    376. CompareOperator.GREATER, new BinaryComparator(Bytes.toBytes("22")));
    377. //性别为女
    378. SingleColumnValueFilter singleColumnValueFilter2 = new SingleColumnValueFilter(Bytes.toBytes("info"), Bytes.toBytes("gender"),
    379. CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("女")));
    380. //理科
    381. SingleColumnValueFilter singleColumnValueFilter3 = new SingleColumnValueFilter(Bytes.toBytes("info"), Bytes.toBytes("clazz"),
    382. CompareOperator.EQUAL, new SubstringComparator("理科"));
    383. //如何以每次添加一个过滤器作为条件的话,后一次添加的过滤器逻辑会将前一次覆盖
    384. // scan.setFilter(singleColumnValueFilter);
    385. // scan.setFilter(singleColumnValueFilter1);
    386. // scan.setFilter(singleColumnValueFilter2);
    387. // scan.setFilter(singleColumnValueFilter3);
    388. //通过观察源码发现,虽然setFilter这个方法只能传Filter的子类对象
    389. //但是我们发现了该抽象类的一个子类FilterList表示多个过滤器集合的意思
    390. //所以我们可以先创建FilterList对象,将多个过滤器封装成List集合添加到FilterList对象中,最终将FilterList对象再添加到scan中
    391. //先将上面4个过滤器添加到List集合中
    392. ArrayList filters = new ArrayList<>();
    393. filters.add(singleColumnValueFilter);
    394. filters.add(singleColumnValueFilter1);
    395. filters.add(singleColumnValueFilter2);
    396. filters.add(singleColumnValueFilter3);
    397. //创建FilterList对象
    398. FilterList filterList = new FilterList();
    399. //public void addFilter(List filters)
    400. filterList.addFilter(filters);
    401. scan.setFilter(filterList);
    402. ResultScanner resultScanner = students.getScanner(scan);
    403. for (Result result : resultScanner) {
    404. HBaseUtil.printResult(result);
    405. }
    406. } catch (Exception e) {
    407. e.printStackTrace();
    408. }
    409. }
    410. @Test
    411. public void testHBaseUtil() {
    412. //需求:通过RowFilter与BinaryComparator过滤比rowKey 1500100010小的所有值出来
    413. // HBaseUtil.scanDataWithCompareFilter("students", FilterName.ROWKEY,
    414. // CompareOperator.LESS,ComparableName.BINARY,"1500100010");
    415. //需求:过滤出列簇名中包含“a”的列簇中所有数据配合包含比较器SubstringComparator
    416. // HBaseUtil.scanDataWithCompareFilter("users",FilterName.FAMILY,
    417. // CompareOperator.EQUAL,ComparableName.SUBSTRING,"a");
    418. //需求:通过QualifierFilter与SubstringComparator查询列名包含 m 的列的值
    419. // HBaseUtil.scanDataWithCompareFilter("users",FilterName.QUALIFIER,
    420. // CompareOperator.EQUAL,ComparableName.SUBSTRING,"m");
    421. //需求:通过ValueFilter与BinaryPrefixComparator过滤出所有的cell中值以 "从" 开头的学生
    422. HBaseUtil.scanDataWithCompareFilter("students", FilterName.VALUE,
    423. CompareOperator.EQUAL, ComparableName.BINARY_PREFIX, "从");
    424. }
    425. /**
    426. * 释放Before创建的资源,在每个Test之后执行
    427. */
    428. @After
    429. public void closeSource() {
    430. HBaseUtil.closeSource();
    431. }
    432. }

  • 相关阅读:
    庆国庆,拟物地图
    Linux-文件压缩解压
    智能家居界面:移动、pad端、电脑端、HMI端都有,比较多。
    操作系统 线程死锁
    Linux 软链接 与 硬链接 的区别
    document.getElementByclassName()方法
    Python基础 --(1)Python概述
    vue学习-08全局事件总线与消息订阅与发布
    VMware虚拟机的安装教程
    自动化测试框架实战详解
  • 原文地址:https://blog.csdn.net/weixin_52134189/article/details/138167504