All Products
Search
Document Center

ApsaraDB for HBase:Use the ApsaraDB for HBase Java API to access an ApsaraDB for HBase Performance-enhanced Edition instance

Last Updated:Mar 28, 2026

Use the HBase Java API to connect to an ApsaraDB for HBase Performance-enhanced Edition instance and run DDL and DML operations against it.

How it works

The HBase Java client uses three core objects. Understanding their roles and threading behavior prevents the most common connection errors:

ObjectWeightThread-safeResponsibility
ConnectionHeavyweightYes — share across all threadsManages the connection to the cluster. Create once per application; close on shutdown.
AdminLightweightDDL operations: create, disable, truncate, and delete tables. Create as needed and close when done.
TableLightweightNo — each thread needs its own instanceDML operations: put, get, delete, and scan. Create per thread and close when done.

Because Connection is expensive to create, you share one instance. Because Table is not thread-safe, you never share instances across threads — get a new one from the connection for each thread.

Prerequisites

Before you begin, ensure that you have:

Connect to your instance

Step 1: Get the client connection configuration

  1. Log on to the ApsaraDB for HBase console.

  2. On the Clusters page, find the instance and click its ID.

    Instances

  3. In the left-side navigation pane of the instance details page, click Database Connection.

  4. Click Generate Configuration Items. In the Client Connection Configuration dialog box, click the Java Configuration tab and copy the Java code.

    Java Configuration

Step 2: Initialize the client

Paste the copied Java configuration code into your project to create a Configuration object:

// Create a Configuration object.
Configuration conf = HBaseConfiguration.create();

// Set the endpoint. Use the public endpoint for Internet connections,
// or the VPC-facing endpoint for internal network connections.
// Find both endpoints on the Database Connection page in the console.
conf.set("hbase.zookeeper.quorum", "ld-xxxx-proxy-hbaseue.hbaseue.xxx.rds.aliyuncs.com:30020");

// Set the username and password. The defaults are both "root".
conf.set("hbase.client.username", "root");
conf.set("hbase.client.password", "root");

// Required only if you use the alihbase-connector dependency.
// Not needed if you use the alihbase-client dependency.
//conf.set("hbase.client.connection.impl", AliHBaseUEClusterConnection.class.getName());

Step 3: Create a connection

Create a single Connection for the entire lifecycle of your application. It is thread-safe and can be shared across all threads.

// Connection is a heavyweight object — create it once and reuse it.
// Close it after all operations are complete to prevent connection leaks.
Connection connection = ConnectionFactory.createConnection(conf);
Tip: Wrap the connection in a try-finally block to make sure it is always closed, even if an exception occurs.

Run DDL and DML operations

DDL operations

Use Admin for table management. Admin is lightweight — create it as needed and close it when done.

try (Admin admin = connection.getAdmin()) {
    // Create a table with one column family.
    // In production, pre-split the table based on your data distribution.
    HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("tablename"));
    htd.addFamily(new HColumnDescriptor(Bytes.toBytes("family")));
    admin.createTable(htd);

    // Disable a table.
    admin.disableTable(TableName.valueOf("tablename"));

    // Truncate a table (preserves the table structure).
    admin.truncateTable(TableName.valueOf("tablename"), true);

    // Delete a table.
    admin.deleteTable(TableName.valueOf("tablename"));
}

DML operations

Use Table for data operations. Table is not thread-safe — each thread must get its own instance from the connection.

// Table is lightweight and not thread-safe. Get a new instance per thread;
// never share a Table instance across threads.
try (Table table = connection.getTable(TableName.valueOf("tablename"))) {
    // Insert a row.
    Put put = new Put(Bytes.toBytes("row"));
    put.addColumn(Bytes.toBytes("family"), Bytes.toBytes("qualifier"), Bytes.toBytes("value"));
    table.put(put);

    // Read a single row.
    Get get = new Get(Bytes.toBytes("row"));
    Result res = table.get(get);

    // Delete a row.
    Delete delete = new Delete(Bytes.toBytes("row"));
    table.delete(delete);

    // Scan a range of rows — cursor-like access over a key range.
    Scan scan = new Scan(Bytes.toBytes("startRow"), Bytes.toBytes("endRow"));
    ResultScanner scanner = table.getScanner(scan);
    for (Result result : scanner) {
        // Process each result.
    }
    scanner.close();
}

Complete example

The following self-contained class combines all steps above. Copy it into your project, replace the endpoint with your actual value, and run it to verify connectivity.

import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
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.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;

public class HBaseQuickStart {
    public static void main(String[] args) throws IOException {
        // --- Configuration ---
        Configuration conf = HBaseConfiguration.create();
        // Replace with your actual endpoint from the Database Connection page.
        conf.set("hbase.zookeeper.quorum", "ld-xxxx-proxy-hbaseue.hbaseue.xxx.rds.aliyuncs.com:30020");
        conf.set("hbase.client.username", "root");
        conf.set("hbase.client.password", "root");
        // Uncomment if using the alihbase-connector dependency:
        //conf.set("hbase.client.connection.impl", AliHBaseUEClusterConnection.class.getName());

        // --- Connection ---
        // Connection is heavyweight — create once and share across all threads.
        // Close it in finally to prevent connection leaks.
        Connection connection = ConnectionFactory.createConnection(conf);
        try {
            // --- DDL: create a table ---
            // Admin is lightweight; create it as needed and close when done.
            try (Admin admin = connection.getAdmin()) {
                HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("tablename"));
                htd.addFamily(new HColumnDescriptor(Bytes.toBytes("family")));
                // In production, pre-split the table based on your data distribution.
                admin.createTable(htd);
            }

            // --- DML: write and read data ---
            // Table is lightweight and not thread-safe.
            // Each thread must get its own Table instance from the connection.
            try (Table table = connection.getTable(TableName.valueOf("tablename"))) {
                // Insert a row.
                Put put = new Put(Bytes.toBytes("row"));
                put.addColumn(Bytes.toBytes("family"), Bytes.toBytes("qualifier"), Bytes.toBytes("value"));
                table.put(put);

                // Read a single row.
                Get get = new Get(Bytes.toBytes("row"));
                Result res = table.get(get);

                // Scan a range of rows — cursor-like access over a key range.
                Scan scan = new Scan(Bytes.toBytes("startRow"), Bytes.toBytes("endRow"));
                ResultScanner scanner = table.getScanner(scan);
                for (Result result : scanner) {
                    // Process each result.
                }
                scanner.close();

                // Delete a row.
                Delete delete = new Delete(Bytes.toBytes("row"));
                table.delete(delete);
            }

            // --- DDL: clean up ---
            try (Admin admin = connection.getAdmin()) {
                admin.disableTable(TableName.valueOf("tablename"));
                admin.deleteTable(TableName.valueOf("tablename"));
            }
        } finally {
            connection.close();
        }
    }
}

What's next