学习Hadoop第二十九课(利用Java对HBase表进行增、删、改、查操作)

        上节课我们一起学习了利用Java来创建一张HBase表,这节课我们一起学习怎样用Java来调用HBase接口并对数据表进行增、删、改(没有update,但是可覆盖)、查操作。

        当然,在插入数据前请确保Hadoop集群、Zookeeper集群、HBase集群正常工作。大家如果还没搭建集群,请参考前几节的博客学习。找博客的方法也很简单,大家只需要点击我9月、10月份的博客列表便可以看到我这两个月所写的所有关于Hadoop的博客进行学习,因为地址很多我就不一一粘出来了。

     

         接下来我们新建一个类来进行相关操作,我给类起的名字是HBaseTable,我们首先来向表中插入一行数据,插入数据的方法名是testPut,代码如下。

package com.myhbase;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.Before;
import org.junit.Test;
public class HBaseTable {
 private Configuration conf=null;
 /**
  * 得到HBase的配置对象,把它抽离出来成为一个方法,后面谁用到conf对象了,直接使用就可以了。
  * 配置Client连向谁,我们的Client连向的是zookeeper,因此我们配置的是zookeeper的信息,
  * 这些信息存在hbase-site.xml当中。我们会觉得不可思议,建HBase表,竟然Client连的既不是
  * HMaster也不是HRegionServer,而是zookeeper,其实Client连zookeeper
     * zookeeper只是负责协调,真正执行建表语句的还是HMaster,只不过zookeeper帮我们去找到
  * HMaster并告诉它应该做什么了而已。
  */
    @Before
    public void init(){
     conf=HBaseConfiguration.create();
     conf.set("hbase.zookeeper.quorum","itcast04:2181,itcast05:2181,itcast06:2181");
    }
   
    /**
     * 插入数据
     * @throws IOException
     */
    @Test
    public void testPut() throws IOException{
     //要想向表中插入数据,我们当然要先得到这张表了,通过下面这句代码可以获取我们要操作的表
     HTable table=new HTable(conf, "peoples");
     //我们使用table的input方法时发现它需要传入一个Put类型的参数,因此我们首先需要获取一个Put对象
     //下面这句代码创建的是一个Row key的名字叫"rk0001"的Put对象
     Put put=new Put(Bytes.toBytes("rk0001"));
     //有了Put对象,我们还需要给对象设置一些属性值(就是我们操作HBase表时插入一行数据的时候给某列
     //赋值),put.add有三个参数,第一个参数的意思是列族的名字,第二个参数的意思是列的名字,第三个
     //参数是列的值。我们向info列族插入三列,分别是name、age、money。
     put.add(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("zhansan"));
     put.add(Bytes.toBytes("info"),Bytes.toBytes("age"),Bytes.toBytes("20"));
     put.add(Bytes.toBytes("info"),Bytes.toBytes("money"),Bytes.toBytes(800000));
     //将我们创建的put(相当于Row key)添加到表中,意思是向表中插入了一行数据。
     table.put(put);
     //table操作完之后记得关闭,否则会消耗资源
     table.close();
    }
}
     执行完插入操作之后我们到itcast01上看看我们刚才插入的一行数据是否插入成功。如下图所示,我们使用./hbase shell命令进入shell视图,然后使用list命令来查看当前所有的表,发现石油peoples表的,然后使用命令scan 'peoples'来查看这张表所有的数据,发现确实已经有我们刚才插入的三列内容了!说明我们的插入操作成功。大家有没有发现,我们的money这列的值value=\x00\x0C5\x00与其它两列的值明显不一样,这是因为我们在赋值的时候,给money赋的是数值型数据,给其它两列赋的是字符串类型数据。它们的存储方式是不一样的

     刚才我们插入了一行数据,现在我们来测试一下一次性插入一百万条数据的性能如何,方法的代码如下。
    @Test
    public void testPutAll() throws IOException{
     //要想向表中插入数据,我们当然要先得到这张表了,通过下面这句代码可以获取我们要操作的表
     HTable table=new HTable(conf, "peoples");
     //我们插入一行数据的时候需要向表中添加一个put对象,现在我们要一次性插入很多行数据,因此需要
     //用到列表了。我们一次插入一万条数据,因此我们把List的初始大小定为10000.
     List<Put> puts=new ArrayList<Put>(10000);
     for(int i=1;i<=1000000;i++){
      //创建一个Row key
      Put put =new Put(Bytes.toBytes("rk"+i));
      //我们只向info列族插入一列money,为了看着清晰我们把money当成字符串插入
      put.add(Bytes.toBytes("info"), Bytes.toBytes("money"), Bytes.toBytes(""+i));
      puts.add(put);
      //为了减轻服务器的压力,我们不一次性插入一百万条数据,而是分批插入数据,达到一万条就插入一次
      if(i%10000==0){
       table.put(puts);
       puts=new ArrayList<Put>(10000);
      }
     }
     //之所以这样做是为了防止数据总数不是10000的整数倍的情况,不是整数倍的话就会导致最后几个数据无法插入
     //因此我们单独处理处理一下最后剩下的puts内容。
     table.put(puts);
     //用完table记得关闭
     table.close();
    }

    插入完一百万数据所消耗的时间是一分多钟,如下图所示,这还是在一台设备上操作的,不是真正的集群,将来在真正的集群上操作的话,那将是几秒钟的事情。

     接着我们来获取某一行的某一列的值,代码如下

    @Test
    public void testGet() throws IOException{
     //要想向表中插入数据,我们当然要先得到这张表了,通过下面这句代码可以获取我们要操作的表
     HTable table=new HTable(conf, "peoples");
     //获取第99999行的数据
     Get get = new Get(Bytes.toBytes("rk99999"));
     //得到Result对象
     Result result=table.get(get);
     //我们查看info列族money这一列的值
     String r=Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("money")));
     System.out.println(r);
     table.close();
    }

    执行完之后,我们看看控制台输出的信息,发现确实输出了我们要查的第99999行的money这一列的值。

log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
99999

    接着我们再来使用一下scan功能即一次性查找多行的值。代码如下

    @Test
    public void testScan() throws IOException{
     //要想向表中插入数据,我们当然要先得到这张表了,通过下面这句代码可以获取我们要操作的表
     HTable table=new HTable(conf, "peoples");
     //浏览rk从29990到rk300000,一会大家看看是不是跟你想象的结果一样。
     Scan scan=new Scan(Bytes.toBytes("rk29990"),Bytes.toBytes("rk300000"));
     ResultScanner scanner=table.getScanner(scan);
     for(Result result:scanner){
      String r=Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("money")));
      System.out.println(r);
     }
     table.close();
    }

    执行上面的方法后我们到控制台查看结果,如下所示,发现我们查询到的结果并非如我们想象的那样,它实际上是按字典顺序进行查询的。而且它查询的区域包括前面,不包括后面,因此我们看不到rk300000这一行的值。

log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
29990
299900
299901
299902
299903
299904
299905
299906
299907
299908
299909
29991
299910
299911
299912
299913
299914
299915
299916
299917
299918
299919
29992
299920
299921
299922
299923
299924
299925
299926
299927
299928
299929
29993
299930
299931
299932
299933
299934
299935
299936
299937
299938
299939
29994
299940
299941
299942
299943
299944
299945
299946
299947
299948
299949
29995
299950
299951
299952
299953
299954
299955
299956
299957
299958
299959
29996
299960
299961
299962
299963
299964
299965
299966
299967
299968
299969
29997
299970
299971
299972
299973
299974
299975
299976
299977
299978
299979
29998
299980
299981
299982
299983
299984
299985
299986
299987
299988
299989
29999
299990
299991
299992
299993
299994
299995
299996
299997
299998
299999
3
30
300
3000
30000

     最后我们再来学习删除操作,删除的代码如下。

    @Test
    public void testDelete() throws IOException{
     //要想向表中插入数据,我们当然要先得到这张表了,通过下面这句代码可以获取我们要操作的表
     HTable table=new HTable(conf, "peoples");
     //指定要删除哪一行的数据
     Delete delete=new Delete(Bytes.toBytes("rk99999"));
     //执行删除
     table.delete(delete);
     //删除完关闭table
     table.close();
    }

    那么,删除完之后我们怎么知道是否真的删除了呢?其实我们可以再执行以下testGet方法,查找rk99999这一行的数据,看还能不能查到,我们发现查到的是null,说明我们已经删除了rk99999这一行的数据。

log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

null

    关于HBase表的操作,没有update方法。想要改变某列的值我们就再次插入这列的值,我们覆盖原来的值就行了。

    好了,本小节课我们便一起学习完了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值