HBase API详解
一、Java API和HBase数据模型的关系
在Java中,与HBase数据库存储管理相关的类包括HBaseAdmin、HBaseConfiguration、HTable、HTableDescriptor、Put、Get以及Scanner,其中,与数据库相关的类包括HBaseAdmin和HBaseConfiguration,与表相关的包括HTable,操作列族的类是HTableDescriptor,列的修饰符包括Put、Get、Scanner三个类。
二、HBaseConfiguration类
通过HBaseConfiguration类可以对HBase进行相关配置,它是每一个HBase Client都会用到的对象,它的构造函数主要由以下两种:
1 public HBaseConfiguration(); 2 public HBaseConfiguration(final Configuration c); 3 /*默认的构造方式会尝试从hbase-default.xml和hbase-site.xml中读取配置。如果classpath没有这两个文件,就需要你自己设置配置。*/
它常用的操作主要是像下面的语句这样:
1 HBaseConfiguration hconfig = new HBaseConfiguration(); 2 hconfig.set("hbase.zookeeper.property.clientPort","8000");
这两条语句设置了“hbase.zookeeper.property.clientPort”属性的端口号为8000,一般情况下,HBaseConfiguration会使用构造函数进行初始化,然后再使用set、get方法添加必要的设置。
三、HBaseAdmin类
HBaseAdmin类主要是提供了一个接口来管理HBase数据库的表信息。它主要常用的一些表的操作方法,例如:创建表、删除表、浏览表、添加表或者删除表中数据,用法示例:
1 HBaseAdmin admin = new HBaseAdmin(hconfig); 2 hAdmin.createTable(“table name”); 3 hAdmin.disableTable("table name");
上面的语句首先创建一个表,然后使该表无效。在这个类的使用过程中,大多数还需要结合HTableDescriptor和HColumnDescriptor类,HTableDescriptor这个类主要是创建表的名字以及对应表的列族,HColumnDescriptor类主要是维护列族的信息,通常在创建表为表添加列族的时候使用,列族被创建之后不能直接修改,只能通过删除然后重建的方式修改,完整创建表的语句如下:
1 HBaseAdmin hAdmin = new HBaseAdmin(hbaseConfig); 2 HTableDescriptor t = new HTableDescriptor(tableName); 3 t.addFamily(new HColumnDescriptor(“f1″)); 4 t.addFamily(new HColumnDescriptor(“f2″)); 5 t.addFamily(new HColumnDescriptor(“f3″)); 6 t.addFamily(new HColumnDescriptor(“f4″)); 7 hAdmin.createTable(t);
四、HTable类
HTable主要是与HBase表进行通信,但是此方法对于更新操作时非线程安全的,如果有多个线程与单个HTable实例进行通信,那么写缓冲区可能会崩溃,常用的操作主要是:
1 HTable ht = new HTable(config,Bytes.toBytes(tablename)); 2 ResultScanner scanner = ht.getScanner(familyname);
五、Put类
Put类主要是获取单个行的信息,对单个行进行添加信息,同时结合Result类可以进行查询,方便的获取值或者各种(key-value)对,使用实例如下:
1 HTable ht = new HTable(config,Bytes.toBytes(tablename)); 2 Put put = new Put(rowname);//为指定行创建一个Put操作 3 put.add(family,qualifier,value); 4 ht.put(put); 5 Get get = new Get(Byte.toBytes(rowname)); 6 Result re = ht.get(get); 7 Bytes[] b = re.getValue((familyname+";"+columnname)); 8 ResultScanner scanner = ht.getScanner(Bytes.toBytes(family)); 9 for(Result var:scanner){ 10 Bytes[] b = var.getValue(familyname,columnname); 11 }
完整代码:
1 import java.io.IOException; 2 3 import org.apache.hadoop.conf.Configuration; 4 import org.apache.hadoop.hbase.HBaseConfiguration; 5 import org.apache.hadoop.hbase.HColumnDescriptor; 6 import org.apache.hadoop.hbase.HTableDescriptor; 7 import org.apache.hadoop.hbase.KeyValue; 8 import org.apache.hadoop.hbase.client.Delete; 9 import org.apache.hadoop.hbase.client.Get; 10 import org.apache.hadoop.hbase.client.HBaseAdmin; 11 import org.apache.hadoop.hbase.client.HTable; 12 import org.apache.hadoop.hbase.client.HTablePool; 13 import org.apache.hadoop.hbase.client.Put; 14 import org.apache.hadoop.hbase.client.Result; 15 import org.apache.hadoop.hbase.client.ResultScanner; 16 import org.apache.hadoop.hbase.client.Scan; 17 import org.apache.hadoop.hbase.util.Bytes; 18 19 public class Hbase { 20 // 声明静态配置 21 static Configuration conf = null; 22 static { 23 conf = HBaseConfiguration.create(); 24 conf.set("hbase.zookeeper.quorum", "localhost"); 25 } 26 27 /* 28 * 创建表 29 * 30 * @tableName 表名 31 * 32 * @family 列族列表 33 */ 34 public static void creatTable(String tableName, String[] family) 35 throws Exception { 36 HBaseAdmin admin = new HBaseAdmin(conf); 37 HTableDescriptor desc = new HTableDescriptor(tableName); 38 for (int i = 0; i < family.length; i++) { 39 desc.addFamily(new HColumnDescriptor(family[i])); 40 } 41 if (admin.tableExists(tableName)) { 42 System.out.println("table Exists!"); 43 System.exit(0); 44 } else { 45 admin.createTable(desc); 46 System.out.println("create table Success!"); 47 } 48 } 49 50 /* 51 * 为表添加数据(适合知道有多少列族的固定表) 52 * 53 * @rowKey rowKey 54 * 55 * @tableName 表名 56 * 57 * @column1 第一个列族列表 58 * 59 * @value1 第一个列的值的列表 60 * 61 * @column2 第二个列族列表 62 * 63 * @value2 第二个列的值的列表 64 */ 65 public static void addData(String rowKey, String tableName, 66 String[] column1, String[] value1, String[] column2, String[] value2) 67 throws IOException { 68 Put put = new Put(Bytes.toBytes(rowKey));// 设置rowkey 69 HTable table = new HTable(conf, Bytes.toBytes(tableName));// HTabel负责跟记录相关的操作如增删改查等// 70 // 获取表 71 HColumnDescriptor[] columnFamilies = table.getTableDescriptor() // 获取所有的列族 72 .getColumnFamilies(); 73 74 for (int i = 0; i < columnFamilies.length; i++) { 75 String familyName = columnFamilies[i].getNameAsString(); // 获取列族名 76 if (familyName.equals("article")) { // article列族put数据 77 for (int j = 0; j < column1.length; j++) { 78 put.add(Bytes.toBytes(familyName), 79 Bytes.toBytes(column1[j]), Bytes.toBytes(value1[j])); 80 } 81 } 82 if (familyName.equals("author")) { // author列族put数据 83 for (int j = 0; j < column2.length; j++) { 84 put.add(Bytes.toBytes(familyName), 85 Bytes.toBytes(column2[j]), Bytes.toBytes(value2[j])); 86 } 87 } 88 } 89 table.put(put); 90 System.out.println("add data Success!"); 91 } 92 93 /* 94 * 根据rwokey查询 95 * 96 * @rowKey rowKey 97 * 98 * @tableName 表名 99 */ 100 public static Result getResult(String tableName, String rowKey) 101 throws IOException { 102 Get get = new Get(Bytes.toBytes(rowKey)); 103 HTable table = new HTable(conf, Bytes.toBytes(tableName));// 获取表 104 Result result = table.get(get); 105 for (KeyValue kv : result.list()) { 106 System.out.println("family:" + Bytes.toString(kv.getFamily())); 107 System.out 108 .println("qualifier:" + Bytes.toString(kv.getQualifier())); 109 System.out.println("value:" + Bytes.toString(kv.getValue())); 110 System.out.println("Timestamp:" + kv.getTimestamp()); 111 System.out.println("-------------------------------------------"); 112 } 113 return result; 114 } 115 116 /* 117 * 遍历查询hbase表 118 * 119 * @tableName 表名 120 */ 121 public static void getResultScann(String tableName) throws IOException { 122 Scan scan = new Scan(); 123 ResultScanner rs = null; 124 HTable table = new HTable(conf, Bytes.toBytes(tableName)); 125 try { 126 rs = table.getScanner(scan); 127 for (Result r : rs) { 128 for (KeyValue kv : r.list()) { 129 System.out.println("row:" + Bytes.toString(kv.getRow())); 130 System.out.println("family:" 131 + Bytes.toString(kv.getFamily())); 132 System.out.println("qualifier:" 133 + Bytes.toString(kv.getQualifier())); 134 System.out 135 .println("value:" + Bytes.toString(kv.getValue())); 136 System.out.println("timestamp:" + kv.getTimestamp()); 137 System.out 138 .println("-------------------------------------------"); 139 } 140 } 141 } finally { 142 rs.close(); 143 } 144 } 145 146 /* 147 * 遍历查询hbase表 148 * 149 * @tableName 表名 150 */ 151 public static void getResultScann(String tableName, String start_rowkey, 152 String stop_rowkey) throws IOException { 153 Scan scan = new Scan(); 154 scan.setStartRow(Bytes.toBytes(start_rowkey)); 155 scan.setStopRow(Bytes.toBytes(stop_rowkey)); 156 ResultScanner rs = null; 157 HTable table = new HTable(conf, Bytes.toBytes(tableName)); 158 try { 159 rs = table.getScanner(scan); 160 for (Result r : rs) { 161 for (KeyValue kv : r.list()) { 162 System.out.println("row:" + Bytes.toString(kv.getRow())); 163 System.out.println("family:" 164 + Bytes.toString(kv.getFamily())); 165 System.out.println("qualifier:" 166 + Bytes.toString(kv.getQualifier())); 167 System.out 168 .println("value:" + Bytes.toString(kv.getValue())); 169 System.out.println("timestamp:" + kv.getTimestamp()); 170 System.out 171 .println("-------------------------------------------"); 172 } 173 } 174 } finally { 175 rs.close(); 176 } 177 } 178 179 /* 180 * 查询表中的某一列 181 * 182 * @tableName 表名 183 * 184 * @rowKey rowKey 185 */ 186 public static void getResultByColumn(String tableName, String rowKey, 187 String familyName, String columnName) throws IOException { 188 HTable table = new HTable(conf, Bytes.toBytes(tableName)); 189 Get get = new Get(Bytes.toBytes(rowKey)); 190 get.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(columnName)); // 获取指定列族和列修饰符对应的列 191 Result result = table.get(get); 192 for (KeyValue kv : result.list()) { 193 System.out.println("family:" + Bytes.toString(kv.getFamily())); 194 System.out 195 .println("qualifier:" + Bytes.toString(kv.getQualifier())); 196 System.out.println("value:" + Bytes.toString(kv.getValue())); 197 System.out.println("Timestamp:" + kv.getTimestamp()); 198 System.out.println("-------------------------------------------"); 199 } 200 } 201 202 /* 203 * 更新表中的某一列 204 * 205 * @tableName 表名 206 * 207 * @rowKey rowKey 208 * 209 * @familyName 列族名 210 * 211 * @columnName 列名 212 * 213 * @value 更新后的值 214 */ 215 public static void updateTable(String tableName, String rowKey, 216 String familyName, String columnName, String value) 217 throws IOException { 218 HTable table = new HTable(conf, Bytes.toBytes(tableName)); 219 Put put = new Put(Bytes.toBytes(rowKey)); 220 put.add(Bytes.toBytes(familyName), Bytes.toBytes(columnName), 221 Bytes.toBytes(value)); 222 table.put(put); 223 System.out.println("update table Success!"); 224 } 225 226 /* 227 * 查询某列数据的多个版本 228 * 229 * @tableName 表名 230 * 231 * @rowKey rowKey 232 * 233 * @familyName 列族名 234 * 235 * @columnName 列名 236 */ 237 public static void getResultByVersion(String tableName, String rowKey, 238 String familyName, String columnName) throws IOException { 239 HTable table = new HTable(conf, Bytes.toBytes(tableName)); 240 Get get = new Get(Bytes.toBytes(rowKey)); 241 get.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(columnName)); 242 get.setMaxVersions(5); 243 Result result = table.get(get); 244 for (KeyValue kv : result.list()) { 245 System.out.println("family:" + Bytes.toString(kv.getFamily())); 246 System.out 247 .println("qualifier:" + Bytes.toString(kv.getQualifier())); 248 System.out.println("value:" + Bytes.toString(kv.getValue())); 249 System.out.println("Timestamp:" + kv.getTimestamp()); 250 System.out.println("-------------------------------------------"); 251 } 252 /* 253 * List<?> results = table.get(get).list(); Iterator<?> it = 254 * results.iterator(); while (it.hasNext()) { 255 * System.out.println(it.next().toString()); } 256 */ 257 } 258 259 /* 260 * 删除指定的列 261 * 262 * @tableName 表名 263 * 264 * @rowKey rowKey 265 * 266 * @familyName 列族名 267 * 268 * @columnName 列名 269 */ 270 public static void deleteColumn(String tableName, String rowKey, 271 String falilyName, String columnName) throws IOException { 272 HTable table = new HTable(conf, Bytes.toBytes(tableName)); 273 Delete deleteColumn = new Delete(Bytes.toBytes(rowKey)); 274 deleteColumn.deleteColumns(Bytes.toBytes(falilyName), 275 Bytes.toBytes(columnName)); 276 table.delete(deleteColumn); 277 System.out.println(falilyName + ":" + columnName + "is deleted!"); 278 } 279 280 /* 281 * 删除指定的列 282 * 283 * @tableName 表名 284 * 285 * @rowKey rowKey 286 */ 287 public static void deleteAllColumn(String tableName, String rowKey) 288 throws IOException { 289 HTable table = new HTable(conf, Bytes.toBytes(tableName)); 290 Delete deleteAll = new Delete(Bytes.toBytes(rowKey)); 291 table.delete(deleteAll); 292 System.out.println("all columns are deleted!"); 293 } 294 295 /* 296 * 删除表 297 * 298 * @tableName 表名 299 */ 300 public static void deleteTable(String tableName) throws IOException { 301 HBaseAdmin admin = new HBaseAdmin(conf); 302 admin.disableTable(tableName); 303 admin.deleteTable(tableName); 304 System.out.println(tableName + "is deleted!"); 305 } 306 307 public static void main(String[] args) throws Exception { 308 309 // 创建表 310 String tableName = "blog2"; 311 String[] family = { "article", "author" }; 312 // creatTable(tableName, family); 313 314 // 为表添加数据 315 316 String[] column1 = { "title", "content", "tag" }; 317 String[] value1 = { 318 "Head First HBase", 319 "HBase is the Hadoop database. Use it when you need random, realtime read/write access to your Big Data.", 320 "Hadoop,HBase,NoSQL" }; 321 String[] column2 = { "name", "nickname" }; 322 String[] value2 = { "nicholas", "lee" }; 323 addData("rowkey1", "blog2", column1, value1, column2, value2); 324 addData("rowkey2", "blog2", column1, value1, column2, value2); 325 addData("rowkey3", "blog2", column1, value1, column2, value2); 326 327 // 遍历查询 328 getResultScann("blog2", "rowkey4", "rowkey5"); 329 // 根据row key范围遍历查询 330 getResultScann("blog2", "rowkey4", "rowkey5"); 331 332 // 查询 333 getResult("blog2", "rowkey1"); 334 335 // 查询某一列的值 336 getResultByColumn("blog2", "rowkey1", "author", "name"); 337 338 // 更新列 339 updateTable("blog2", "rowkey1", "author", "name", "bin"); 340 341 // 查询某一列的值 342 getResultByColumn("blog2", "rowkey1", "author", "name"); 343 344 // 查询某列的多版本 345 getResultByVersion("blog2", "rowkey1", "author", "name"); 346 347 // 删除一列 348 deleteColumn("blog2", "rowkey1", "author", "nickname"); 349 350 // 删除所有列 351 deleteAllColumn("blog2", "rowkey1"); 352 353 // 删除表 354 deleteTable("blog2"); 355 356 } 357 }