HBase相关API整理-Put

本文深入解析HBase 2.1.0版本的API使用,重点介绍如何利用Put方法进行数据插入,包括单条和批量插入操作,并探讨了Put操作的原子性和检查写特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

    之前曾经发表过博文,整理了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();
	}

 

<think>好的,用户想要查找关于HBase Java API的编程实践和使用指南,包括示例代码。首先,我需要回顾之前的引用内容,看看有哪些相关的信息可以整合。 引用[1]提到将HBase Java API的操作封装成工具类,提高代码的可维护性。引用[2]和[3]提供了编程示例,对应HBase Shell的命令,如create、put、get等。引用[4]则涉及环境启动步骤。用户需要具体的实践指导和代码示例,所以应该结合这些引用内容,整理出步骤化的教程。 接下来,我需要确定用户可能的背景。他们可能已经安装了Hadoop和HBase,但需要确认环境配置是否正确。然后,用户可能需要从创建表、插入数据到查询等基本操作,以及如何封装工具类。此外,用户可能还关心代码结构和最佳实践,比如如何解耦工具类和业务逻辑,这点引用[1]已经提到。 需要确保示例代码符合Java API的使用方法,比如正确使用Configuration对象、Connection的管理,以及各个类如Admin、Table的正确用法。同时,要提醒用户异常处理和资源关闭,避免连接泄漏。 可能还需要注意版本兼容性,但引用中没有提到具体版本,所以保持通用。最后,用户可能需要进一步的问题,比如性能优化或高级功能,所以相关问题的部分需要涵盖这些方面。</think>### HBase Java API编程实践指南 #### 一、环境准备(前置条件) 1. 启动HDFS和HBase服务(需配置环境变量) ```shell # 根据引用[4]的操作指引 cd /usr/local/hadoop ./sbin/start-dfs.sh cd /usr/local/hbase ./bin/start-hbase.sh ``` 2. Maven依赖配置(核心依赖项) ```xml <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-client</artifactId> <version>2.4.9</version> </dependency> ``` #### 二、工具类封装实践(引用[1]最佳实践) ```java public class HBaseJavaAPIUtils { private static Connection connection; // 初始化连接池 static { Configuration config = HBaseConfiguration.create(); config.set("hbase.zookeeper.quorum", "node1,node2,node3"); try { connection = ConnectionFactory.createConnection(config); } catch (IOException e) { e.printStackTrace(); } } // 创建表方法 public static void createTable(String tableName, String... colFamilies) throws IOException { try (Admin admin = connection.getAdmin()) { TableDescriptorBuilder tableDesc = TableDescriptorBuilder.newBuilder(TableName.valueOf(tableName)); for (String cf : colFamilies) { ColumnFamilyDescriptorBuilder colDesc = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(cf)); tableDesc.setColumnFamily(colDesc.build()); } admin.createTable(tableDesc.build()); } } // 其他方法(put/get/scan等)按相同模式封装 } ``` #### 三、基础操作示例(对应Shell命令实现) 1. **创建表**(对应`create`命令) ```java public class HBaseDemo { public static void main(String[] args) throws IOException { HBaseJavaAPIUtils.createTable("Student", "Info", "Grades"); } } ``` 2. **插入数据**(对应`put`命令) ```java public static void putData(String tableName, String rowKey, String colFamily, String qualifier, String value) throws IOException { try (Table table = connection.getTable(TableName.valueOf(tableName))) { Put put = new Put(Bytes.toBytes(rowKey)); put.addColumn(Bytes.toBytes(colFamily), Bytes.toBytes(qualifier), Bytes.toBytes(value)); table.put(put); } } ``` 3. **查询数据**(对应`get`命令) ```java public static Result getData(String tableName, String rowKey) throws IOException { try (Table table = connection.getTable(TableName.valueOf(tableName))) { Get get = new Get(Bytes.toBytes(rowKey)); return table.get(get); } } ``` #### 四、工程化实践要点 1. **连接管理**:使用单例模式维护Connection对象(创建成本高) 2. **资源释放**:所有`Table`和`Admin`对象必须放在try-with-resources语句中 3. **字节转换**:统一使用`Bytes.toBytes()`进行数据类型转换 4. **异常处理**:建议封装自定义异常体系(如HBaseOpsException) #### 五、调试与验证(引用[3]方法) 1. 在Eclipse/IntelliJ中通过`Run As > Java Application`执行程序 2. 使用HBase Shell验证操作结果: ```shell hbase> list hbase> scan 'Student' ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VogtZhao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值