This topic provides concrete examples that describe how to process data through the OBKV-HBase client.
Preparations
Before you try the following examples, make sure that the following conditions are met:
You have deployed an OceanBase Cloud instance.
You have created a MySQL-compatible tenant.
You have created a database.
You have created an OBKV-HBase data table.
In this example, the table group name is
htable1. Each table corresponds to one column family. You can create tables as needed. The following statements show how to create the tables.CREATE TABLEGROUP htable1; CREATE TABLE htable1$family1 ( `K` varbinary(1024) NOT NULL, `Q` varbinary(256) NOT NULL, `T` bigint(20) NOT NULL, `V` varbinary(1024) DEFAULT NULL, PRIMARY KEY (`K`, `Q`, `T`) ) TABLEGROUP = htable1 PARTITION BY KEY(`K`) PARTITIONS 3; CREATE TABLE htable1$family2 ( `K` varbinary(1024) NOT NULL, `Q` varbinary(256) NOT NULL, `T` bigint(20) NOT NULL, `V` varbinary(1024) DEFAULT NULL, PRIMARY KEY (`K`, `Q`, `T`) ) TABLEGROUP = htable1 PARTITION BY KEY(`K`) PARTITIONS 3; CREATE TABLE htable1$family3 ( `K` varbinary(1024) NOT NULL, `Q` varbinary(256) NOT NULL, `T` bigint(20) NOT NULL, `V` varbinary(1024) DEFAULT NULL, PRIMARY KEY (`K`, `Q`, `T`) ) TABLEGROUP = htable1 PARTITION BY KEY(`K`) PARTITIONS 3;The examples in this topic use OHTable to connect to an OBKV-HBase instance and process data. Make sure that you have deployed and configured the OBKV-HBase client and connected to the instance through OHTable. For details, see Connect to an instance by using the OBKV-HBase client.
Considerations
- The execution results in the code examples depend on the sequence of the operations below. To reproduce the results, execute the operations in order.
- To observe database results more intuitively, the examples use the MySQL client to connect to OBKV-HBase and query table status through SQL.
Notice
The put, delete, get, and scan interfaces of OBKV-HBase support multiple column families.
Put
Notice
To optimize HBase put performance, use a new version of the client together with ODP. ODP version requirement: >= 4.3.0. HBase client version requirement: >= 1.4.0 or >= 2.4.0.
Function description:
The put operation lets you specify multiple columns in one row and supports multiple column families. Writes across multiple column families are atomic.
When no version (timestamp) is specified, the version of each column written in this operation is the timestamp obtained by the server at execution time. Columns written across multiple column families share the same version.
Function prototype:
- void put(Put put)
- void put(List
puts)
Parameters:
put: a Put object used to insert a single record.puts: a collection of Put objects used to insert multiple records in batch.
Example:
Put put = new Put("testKey0".getBytes());
put.add("family1".getBytes(), "column1".getBytes(), "value1-1".getBytes());
put.add("family1".getBytes(), "column2".getBytes(), "value1-2".getBytes());
put.add("family2".getBytes(), "column3".getBytes(), "value2-3".getBytes());
put.add("family3".getBytes(), "column4".getBytes(), "value3-4".getBytes());
hTable.put(put);
MySQL [test]> SELECT * FROM htable1$family1;
+----------+---------+----------------+---------+
| K | Q | T | V |
+----------+---------+----------------+---------+
| testKey0 | column1 | -1730184389941 | value1-1|
| testKey0 | column2 | -1730184389941 | value1-2|
+----------+---------+----------------+---------+
2 rows in set
MySQL [test]> SELECT * FROM htable1$family2;
+----------+---------+----------------+---------+
| K | Q | T | V |
+----------+---------+----------------+---------+
| testKey0 | column3 | -1730184389941 | value2-3|
+----------+---------+----------------+---------+
1 row in set
MySQL [test]> SELECT * FROM htable1$family3;
+----------+---------+----------------+---------+
| K | Q | T | V |
+----------+---------+----------------+---------+
| testKey0 | column4 | -1730184389941 | value3-4|
+----------+---------+----------------+---------+
1 row in set
Get
Function description:
- You can call this function to obtain the data of the specified row.
Function prototype:
- Result get(final Get get)
- Result[] get(List
gets)
Parameters:
get: a Get object. Use theaddColumnoraddFamilyfunction to specify the operation target. In a single-row get operation, you can combine and operate on multiple column families as needed. Return values are sorted by the K column and then the Q column in lexicographic order.addColumn:- Specifies a particular column to retrieve.
- Requires both the column family and column qualifier.
- Applies when you need to retrieve the value of a specific column.
- Returns only the value of the specified column.
addFamily:- Specifies an entire column family to retrieve.
- Requires only the column family name.
- Applies when you need to retrieve all columns in a column family.
- Returns the values of all columns in that column family.
gets: a list of Get objects.
Example:
// Obtain one family.
int maxVersion = 1;
Get get = new Get("testKey0".getBytes());
get.addColumn("family1".getBytes(), "column1".getBytes());
get.addFamily("family2".getBytes());
Result result = hTable.get(get);
for (Cell cell : result.rawCells()) {
System.out.println(new String(CellUtil.cloneRow(cell)) + " "
+ new String(CellUtil.cloneFamily(cell)) + " "
+ new String(CellUtil.cloneQualifier(cell)) + " "
+ new String(CellUtil.cloneValue(cell)));
}
## Output:
## testKey0 family1 column1 value1-1
## testKey0 family2 column3 value2-3
## The preceding Get operation is equivalent to the following SQL queries
MySQL [test]> SELECT * FROM htable1$family1 WHERE k = "testKey0" AND Q = 'column1';
+----------+---------+----------------+---------+
| K | Q | T | V |
+----------+---------+----------------+---------+
| testKey0 | column1 | -1730184389941 | value1-1|
+----------+---------+----------------+---------+
1 row in set
MySQL [test]> SELECT * FROM htable1$family2 WHERE k = "testKey0";
+----------+---------+----------------+---------+
| K | Q | T | V |
+----------+---------+----------------+---------+
| testKey0 | column3 | -1730184389941 | value2-3|
+----------+---------+----------------+---------+
1 row in set
Scan
Function description:
- You can call this function to scan a table based on the specified conditions (
scan/family/qualifier).
Function prototype:
- ResultScanner getScanner(byte[] family, byte[] qualifier)
- ResultScanner getScanner(final byte[] family)
- ResultScanner getScanner(final Scan scan)
Parameters:
family: the target column family to filter.qualifier: the target column name to filter.scan: a Scan object. UseaddFamily,addColumn, or similar methods to set the operation target.addColumn:- Specifies a particular column to retrieve.
- Requires both the column family and column qualifier.
- Applies when you need to retrieve the value of a specific column.
- Returns only the value of the specified column.
addFamily:- Specifies an entire column family to retrieve.
- Requires only the column family name.
- Applies when you need to retrieve all columns in a column family.
- Returns the values of all columns in that column family.
Example:
Scan scan = new Scan("testKey0".getBytes());
scan.addColumn("family1".getBytes(), "column1".getBytes());
scan.addFamily("family2".getBytes());
scan.setStartRow("testKey0".getBytes());
ResultScanner scanner = hTable.getScanner(scan);
for (Result r : scanner) {
for (Cell cell : r.rawCells()) {
System.out.println(new String(CellUtil.cloneRow(cell)) + " "
+ new String(CellUtil.cloneFamily(cell)) + " "
+ new String(CellUtil.cloneQualifier(cell)) + " "
+ new String(CellUtil.cloneValue(cell)));
}
}
## Output:
## testKey0 family1 column1 value1-1
## testKey0 family2 column3 value2-3
## The preceding Scan operation is equivalent to the following SQL queries
MySQL [test]> SELECT *
-> FROM htable1$family2
-> WHERE K >= "testKey0"
-> UNION
-> SELECT *
-> FROM htable1$family1
-> WHERE K >= "testKey0" AND Q = "column1";
+----------+---------+----------------+---------+
| K | Q | T | V |
+----------+---------+----------------+---------+
| testKey0 | column1 | -1730184389941 | value1-1|
| testKey0 | column3 | -1730184389941 | value2-3|
+----------+---------+----------------+---------+
2 rows in set
OBKV-HBase supports Reverse Scan, which lets you scan table data in reverse row key order (from largest to smallest), unlike a regular forward scan (from smallest to largest).
Notice
Starting from V4.4.1, Reverse Scan supports secondary partitioning and can be combined with any key/range `K_PREFIX` partition key for combined queries.
The following example shows a forward scan:
-- Forward scan
String startKey = "testKey";
String endKey = "testKey9";
String family = "family";
String column = "column";
int maxVersion = 1;
Scan scan = new Scan();
scan.addColumn(family.getBytes(), column.getBytes());
scan.setMaxVersions(maxVersion);
scan.setStartRow(startKey.getBytes());
scan.setStopRow(endKey.getBytes());
ResultScanner scanner = hTable.getScanner(scan);
for (Result r : scanner) {
for (KeyValue kv : r.list()) {
System.out.printf("Scan Demo: Rowkey: %s, Column Family: %s, Column Qualifier: %s, Value: %s, Timestamp: %d%n",
Bytes.toString(r.getRow()),
Bytes.toString(kv.getFamily()),
Bytes.toString(kv.getQualifier()),
Bytes.toString(kv.getValue()),
kv.getTimestamp());
}
}
The result is as follows:
+----------+--------+----------------+----------+
| K | Q | T | V |
+----------+--------+----------------+----------+
| testKey0 | column | -1715961561057 | putValue |
| testKey1 | column | -1715961561132 | putValue |
| testKey2 | column1 | -1715961561132 | putValue |
| testKey2 | column2 | -1715961561132 | putValue |
+----------+--------+----------------+----------+
4 rows in set
The following example shows a reverse scan:
-- Reverse scan
String startKey = "testKey9";
String endKey = "testKey";
String family = "family";
String column = "column";
int maxVersion = 1;
Scan scan = new Scan();
scan.addColumn(family.getBytes(), column.getBytes());
scan.setMaxVersions(maxVersion);
scan.setStartRow(startKey.getBytes());
scan.setStopRow(endKey.getBytes());
// Enable reverse scan
scan.setReversed(true);
ResultScanner scanner = hTable.getScanner(scan);
for (Result r : scanner) {
for (KeyValue kv : r.list()) {
System.out.printf("Scan Demo: Rowkey: %s, Column Family: %s, Column Qualifier: %s, Value: %s, Timestamp: %d%n",
Bytes.toString(r.getRow()),
Bytes.toString(kv.getFamily()),
Bytes.toString(kv.getQualifier()),
Bytes.toString(kv.getValue()),
kv.getTimestamp());
}
}
The result is as follows:
+----------+--------+----------------+----------+
| K | Q | T | V |
+----------+--------+----------------+----------+
| testKey2 | column1 | -1715961561132 | putValue |
| testKey2 | column2 | -1715961561132 | putValue |
| testKey1 | column | -1715961561132 | putValue |
| testKey0 | column | -1715961561057 | putValue |
+----------+--------+----------------+----------+
4 rows in set
Increment Column Value
Function description:
- You can call this function to increment a single column in the specified row. If the function is successfully executed, the new value of the column is returned. The cell of the column must be of the long type, which is used to store a 64-bit integer.
Function prototype:
- long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier, long amount, boolean writeToWAL)
Parameters:
row: the row key.family: the target column family, which is specified when the table is created.qualifier: the name of the target column.amount: the increment step, which can be negative.writeToWAL: specifies whether to pre-write logs. This parameter is not required in OBKV-HBase.
Example:
// Increment a single column by 1.
String column = "incrementColumn";
String key = "incrementKey";
String family = "family";
long increment_value = 1L;
long ret = hTable.incrementColumnValue(
key.getBytes(),
family.getBytes(),
column.getBytes(),
increment_value);
System.out.printf("Increment Column Demo: ret: %b%n", ret);
MySQL [test]> select *,hex(v) from htable1$family where k = "incrementKey";
+--------------+-----------------+----------------+----------+------------------+
| K | Q | T | V | hex(v) |
+--------------+-----------------+----------------+----------+------------------+
| incrementKey | incrementColumn | -1715961669857 | | 0000000000000001 |
+--------------+-----------------+----------------+----------+------------------+
Remarks:
- If you use the MySQL client to view an HBase table, you may notice that no value is displayed in the V column of a cell. In this case, use
hex(v)to display the value. - If the Increment Column Value function fails to query a cell that meets the conditions from the database, it generates a cell whose default value is
0and then performs the increment.
Increment
Function description:
- You can call this function to increment one or more columns in the specified row. The cell of the column or columns must be of the long type, which is used to store a 64-bit integer.
Function prototype:
- Result increment(Increment increment)
Parameters:
increment: an Increment object whose attributes are specified by using theaddColumnfunction.
Example:
// Increment a single column by 1.
String column = "incrementColumn";
String key = "incrementKey";
String family = "family";
long increment_value = 1L;
Increment increment = new Increment(key.getBytes());
increment.addColumn(family.getBytes(), column.getBytes(), increment_value);
Result r = hTable.increment(increment);
for (KeyValue kv : r.list()) {
System.out.printf("Increment Demo: Rowkey: %s, Value:%s%n",
Bytes.toString(r.getRow()),
Bytes.toLong(kv.getValue()));
}
MySQL [test]> select *,hex(v) from htable1$family where k = "incrementKey";
+--------------+-----------------+----------------+----------+------------------+
| K | Q | T | V | hex(v) |
+--------------+-----------------+----------------+----------+------------------+
| incrementKey | incrementColumn | -1715961734681 | | 0000000000000002 |
| incrementKey | incrementColumn | -1715961669857 | | 0000000000000001 |
+--------------+-----------------+----------------+----------+------------------+
Remarks:
- Calling the Increment function on a cell multiple times generates cells of multiple versions. HBase does not support update semantics. A modification to a cell becomes a new version, and you can specify a version when querying.
Append
Function description:
- You can call this function to append data to one or more columns of a character type, such as byte or string, in the specified row.
Function prototype:
- Result append(Append append)
Parameters:
append: an Append object whose attributes are specified by using theaddfunction.
Example:
String column = "appendColumn";
String key = "appendKey";
String family = "family";
Append append = new Append(key.getBytes());
append.add(family.getBytes(), column.getBytes(), toBytes("_append"));
Result r = hTable.append(append);
for (KeyValue kv : r.list()) {
System.out.printf("Appand Demo: Rowkey: %s, Append Value:%s%n",
Bytes.toString(r.getRow()),
Bytes.toString(kv.getValue()));
}
MySQL [test]> select * from htable1$family where k = "appendKey";
+-----------+--------------+----------------+---------+
| K | Q | T | V |
+-----------+--------------+----------------+---------+
| appendKey | appendColumn | -1715961265748 | _append |
+-----------+--------------+----------------+---------+
Remarks:
- If the Append function fails to query a cell that meets the conditions from the database, it inserts a corresponding cell whose default value is an empty string and then appends data to that cell.
Delete
Function description:
- You can call this function to delete the specified cells or rows.
Function prototype:
- void delete(Delete delete)
- void delete(List
deletes)
Parameters:
delete: a Delete object that specifies the row to delete. Use thedeleteColumn,deleteColumns, ordeleteFamilyfunction to configure it. In a single-row delete operation, you can combine and operate on multiple column families as needed.deleteColumn:- Deletes a single column at a specific version.
- Requires the column family, column qualifier, and timestamp.
- Applies when you need to delete data of a specific version.
deleteColumns:- Deletes all versions of a column.
- Requires only the column family and column qualifier.
- Applies when you need to delete all historical data of a column.
deleteFamily:- Deletes all columns and all versions of data in the specified column family.
- Requires only the column family name.
- Applies when you need to clear all data in a column family.
Example:
// Delete all columns in family1 and column3 in family2.
// A subsequent Get can retrieve only values other than those columns in family1 and family2.
Delete delete = new Delete(toBytes("testKey0"));
delete.deleteFamily("family1".getBytes());
delete.deleteColumns("family2".getBytes(), "column3".getBytes());
hTable.delete(delete);
// Delete all columns for testKey0. A subsequent Get returns no results.
Delete delete = new Delete(toBytes("testKey0"));
hTable.delete(delete);
Exists
Function description:
- You can call this function to determine whether the column family or column specified in a Get object exists. If it exists,
trueis returned. Otherwise,falseis returned.
Function prototype:
- boolean exists(Get get)
Parameters:
get: a Get object, which is specified by using theaddFamilyoraddColumnfunction.
Example:
String key = "testKey2";
String family = "family";
Get get = new Get(key.getBytes());
get.addFamily(family.getBytes());
boolean ret = hTable.exists(get);
System.out.printf("Exist Demo: ret: %b%n", ret);
MySQL [test]> select * from htable1$family where k = "testKey2";
+----------+--------+----------------+----------+
| K | Q | T | V |
+----------+--------+----------------+----------+
| testKey2 | column | -1715961561132 | putValue |
+----------+--------+----------------+----------+
Remarks:
- The semantics of Exists are equivalent to those of Get.
Check And Put
Function description:
- You can call this function to check and replace the data of the specified column. It returns
trueif the condition is met and the replacement succeeds, and returnsfalseotherwise.
Function prototype:
- boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, byte[] value, Put put)
Parameters:
row: the target row key.family: the target column family.qualifier: the name of the target column.value: the value of the target column.put: the new column value.
Example:
String key = "testKey2";
String family = "family";
String column = "column";
String value = "putValue";
String new_value = "value_new";
Put put = new Put(key.getBytes());
put.add(family.getBytes(), column.getBytes(), new_value.getBytes());
boolean ret = hTable.checkAndPut(
key.getBytes(),
family.getBytes(),
column.getBytes(),
value.getBytes(),
put);
System.out.printf("CheckAndPut Demo: ret: %b%n", ret);
MySQL [test]> select * from htable1$family where k = "testKey2";
+----------+--------+----------------+-----------+
| K | Q | T | V |
+----------+--------+----------------+-----------+
| testKey2 | column | -1715961408587 | value_new |
| testKey2 | column | -1715961035471 | putValue |
+----------+--------+----------------+-----------+
Remarks:
- The cell whose primary key is
testKey2and value isputValueis modified to generate a cell of a new version whose value isvalue_new.
Check And Delete
Function description:
- You can call this function to delete a column when a match condition is met. It returns
trueif the condition is met and the deletion succeeds, and returnsfalseotherwise.
Function prototype:
- boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, byte[] value, Delete delete)
Parameters:
row: the target row key for matching.family: the target column family, which is specified when the table is created.qualifier: the target column name for matching.value: the target column value for matching.delete: the column to delete.
Example:
String key = "testKey2";
String family = "family";
String column = "column";
String value = "value_new";
Delete delete = new Delete(key.getBytes());
delete.deleteColumn(family.getBytes(), column.getBytes());
boolean ret = hTable.checkAndDelete(
key.getBytes(),
family.getBytes(),
column.getBytes(),
value.getBytes(),
delete);
System.out.printf("CheckAndDelete Demo: ret: %b%n", ret);
MySQL [test]> select * from htable1$family where k = "testKey2";
+----------+--------+----------------+----------+
| K | Q | T | V |
+----------+--------+----------------+----------+
| testKey2 | column | -1715961035471 | putValue |
+----------+--------+----------------+----------+
Remarks:
- The cell whose primary key is
testKey2and value isvalue_newis deleted. That cell no longer exists in the database.
Get Configuration
Function description:
- You can call this function to return the config handle of an operation instance. It can be used to change attributes for an operation.
Function prototype:
- Configuration getConfiguration()
Parameters:
- None
Example:
hTable.getConfiguration().set("rpc.execute.timeout", "1500");
