前言
之前曾经发表过博文,整理了Hbase2.1.0之后的相关API。这里在对某些操作进行详细整理。
Jar包引入
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NavigableMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Row;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.util.Bytes;
Put方法
连接Hbase并获取相关的表
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "bigdate01:2181,bigdate02:2181,bigdate03:2181");
Connection conn = ConnectionFactory.createConnection(conf);
TableName tableName = TableName.valueOf(Bytes.toBytes("testtable"));
HTable table =(HTable) conn.getTable(tableName);
插入操作:
Put put=new Put(Bytes.toBytes("row-1"));
// 列族 列名 列
put.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("name"), Bytes.toBytes("张三"));
Put put1=new Put(Bytes.toBytes("row-1"));
// 列族 列 时间戳 列值
put1.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("age"), System.currentTimeMillis(),Bytes.toBytes(18) );
Put put2=new Put(Bytes.toBytes("row-1"));
ByteBuffer qualifier=ByteBuffer.allocate(20);
qualifier.put(Bytes.toBytes("address"));
ByteBuffer value=ByteBuffer.allocate(20);
value.put(Bytes.toBytes("石家庄"));
// 列族 列(字节流) 时间戳 列值(字节流)
put2.addColumn(Bytes.toBytes("colfam1"), qualifier, System.currentTimeMillis(), value);
判断当前插入数据是否存在当前表中,随着参数的逐步细化,获得的信息也就越详细,找到匹配的列时返回true
put.has(Bytes.toBytes("colfam"), Bytes.toBytes("name"));//
put.has(Bytes.toBytes("colfam"),Bytes.toBytes("name"), Bytes.toBytes("张三"));
put.has(Bytes.toBytes("colfam"), Bytes.toBytes("name"), 120000);
put.has(Bytes.toBytes("colfam"), Bytes.toBytes("name"), 120000, Bytes.toBytes("张三"));
批量插入数据
Put put=new Put(Bytes.toBytes("row-1"));
// 列族 列名
put.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("name"),
// 列
Bytes.toBytes("张三"));
Put put1=new Put(Bytes.toBytes("row-1"));
// 列族 列
put1.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("age"),
//时间戳 列值
System.currentTimeMillis(),Bytes.toBytes(18) );
Put put2=new Put(Bytes.toBytes("row-1"));
ByteBuffer qualifier=ByteBuffer.allocate(20);
qualifier.put(Bytes.toBytes("address"));
ByteBuffer value=ByteBuffer.allocate(20);
value.put(Bytes.toBytes("石家庄"));
//将Put对象插入到list集合中,实现Put数据的批量插入
List<Put> list=new ArrayList<Put>();
list.add(put);
list.add(put1);
list.add(put2);
table.put(list);
当向不存在的数据中插入数据时,会引起异常:
org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException
Put的原子操作
/**
* put操作本身具有一种原子性操作:检查写
* 这种带检查的操作,能保证put操作的原子性。
* 如果检查通过,就执行put操作,否则彻底放弃修改
* 应用场景:账户结余 状态转换 数据处理,这些场景的共同点是:在读取数据的同时需要处理数据。先比较原值,再做修改
* 有一种特别的检查是通过checkAndPut()调用来完成的,即只有在另外一个值的情况下,才执行这个修改。
* 要执行这种操作只需要将参数的值
* 设置为null即可,只要指定的列不存在,就可以成功执行修改操作
* 这个方法的返回值是一个布尔类型,表示put操作执行成功还是失败,对应的值分别是true和false。
* @throws Exception
*/
public static void putAtom() throws Exception {
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "bigdate01:2181,bigdate02:2181,bigdate03:2181");
Connection conn = ConnectionFactory.createConnection(conf);
TableName tableName = TableName.valueOf(Bytes.toBytes("testtable"));
Table table = conn.getTable(tableName);
/**
* 按照这个例子进行讲解:
* checkAndPut()方法会检查put操作中设置行键 列族 列名 列值是否与checkAndPut中的内容是否一致,如果一致,则执行修改操作,修改成功后并返回结果为true
* res1中执行的方法中,value值设置为空,这是对新增数据的检查。数据插入前,行键 列族都存在,所以检查会通过,res1=true
*
* res2中执行的方法中,和res1中类似,由于res1中已经执行了put操作,再次执行put操作,检查时,操作的列已经存在值,所以检查不通过,无法执行插入操作,res2
* =fasle
*
* res3中执行的方法中,put中设置的值与检查值一直,所以put执行成功,res3=true
*
* res4执行不会有执行结果,会抛出异常Exception in thread "main" org.apache.hadoop.hbase.DoNotRetryIOException: org.apache.hadoop.hbase.DoNotRetryIOException: Action's getRow must match
* 原因在于设置的行键不同
*/
Put put1=new Put(Bytes.toBytes("row-1"));
put1.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("lib"),Bytes.toBytes("apache.hadoop.hbase.admin"));
boolean res1 = table.checkAndPut(Bytes.toBytes("row-1"), Bytes.toBytes("colfam1"),Bytes.toBytes("lib"),null, put1);
System.out.println("res1="+res1);
boolean res2=table.checkAndPut(Bytes.toBytes("row-1"), Bytes.toBytes("colfam1"),Bytes.toBytes("lib"),null, put1);
System.out.println("res2="+res2);
Put put2=new Put(Bytes.toBytes("row-1"));
put2.addColumn(Bytes.toBytes("colfam1"),Bytes.toBytes("name"),Bytes.toBytes("Vogt"));
boolean res3 = table.checkAndPut(Bytes.toBytes("row-1"),Bytes.toBytes("colfam1"), Bytes.toBytes("name"),Bytes.toBytes("张三"), put2);
System.out.println("res3="+res3);
Put put3=new Put(Bytes.toBytes("row-2"));
put3.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("name"), Bytes.toBytes("沙滩"));
boolean res4=table.checkAndPut(Bytes.toBytes("row-1"), Bytes.toBytes("colfam1"),Bytes.toBytes("name"), Bytes.toBytes("张三"), put3);
System.out.println("res4="+res4);
table.close();
conn.close();
}