1.创建表
public static void createSchemaTables(Configuration configuration) throws IOException {
Connection conn = ConnectionFactory.createConnection(configuration);
Admin admin = conn.getAdmin();
HTableDescriptor table = new HTableDescriptor(TableName.valueOf("my-table2"));
table.addFamily(new HColumnDescriptor("mycf"));
admin.createTable(table);
createOrOverwrite(admin,table);
}
2.创建覆盖表
public static void createOrOverwrite(Admin admin,HTableDescriptor table) throws IOException {
if (admin.tableExists(table.getTableName())){
admin.disableTable(table.getTableName());
admin.deleteTable(table.getTableName());
}
admin.createTable(table);
}
3.修改表(新增一个列族)
public static void modifySchemaTables(Configuration configuration)throws Exception{
Connection conn = ConnectionFactory.createConnection(configuration);
Admin admin = conn.getAdmin();
TableName tableName = TableName.valueOf("my-table2");
if(!admin.tableExists(tableName)){
System.out.println("table not exist!");
System.exit(-1);
}
HColumnDescriptor newColumn = new HColumnDescriptor("newcf");
admin.addColumn(tableName,newColumn);
HTableDescriptor table = admin.getTableDescriptor(tableName);
table.modifyFamily(newColumn);
admin.modifyTable(tableName,table);
}
4.删除表
public static void deleteSchema(Configuration configuration)throws Exception{
Connection conn = ConnectionFactory.createConnection(configuration);
Admin admin = conn.getAdmin();
TableName tableName = TableName.valueOf("my-table2");
admin.disableTable(tableName);
// admin.deleteColumn(tableName,"mycf".getBytes());删除列族,可以加上,也可以不加
admin.deleteTable(tableName);
}
CRUD
CRUD是Create,Read,Update,Delete的单词首字母,基本上所有的数据库都会有这几种操作,Hbase也不例外。
在执行CRUD时,不在需要Admin,而是Table接口,早期使用Table不需要手动去调用,不过后来改成了手动调用。
早期(已经被deprecated)
HTable table1 = new HTable(configuration, "tableName");
现在
Table table = conn.getTable(TableName.valueOf("tableName"));
1.Put
put方法相当于增和改方法,因为改的话,也是添加,只不过覆盖之前的数据罢了。
Put有几个构造函数,其中最简单使用最多的就是
Put(byte [] row)
可以添加一个数据
put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("name"),Bytes.toBytes("zhangsan1"));
只有调用Table接口的put方法,数据才能真正生效
table.put(put);
如果新增很多数据,也可以采用语法糖的格式,由于addColumn方法返回的也是put对象
put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("name"),Bytes.toBytes("zhangsan1"))
.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"),Bytes.toBytes(12))
.addColumn(Bytes.toBytes("info"),Bytes.toBytes("sex"),Bytes.toBytes("male"));
checkAndPut
为什么会用到这个方法,这个方法但从词义上说,就是检查再进行put.
如果你在put过程之前,已经有人改动过数据怎么办?
那么我们就可以使用这个方法,检查你要put数据是不是和现在存在的数据一致,如果一致返回true,不一致false,不写入数据。
boolean b = table.checkAndPut("r1".getBytes(), "info".getBytes(), "name".getBytes(), "zss12".getBytes(), put);
System.out.println(b);//false
boolean b = table.checkAndPut("r1".getBytes(), "info".getBytes(), "name".getBytes(), "zx12123".getBytes(), put);
System.out.println(b);//true
Append
append方法不会创建或者修改列,只是往列的字节数组上追加字节
基本构造方法
Append(byte[] rowkey);
Append append = new Append(“r1”.getBytes());
append.add(“info”.getBytes(), “name”.getBytes(),“lili”.getBytes());
table.append(append);
还有这个构造方法,就是从字节数组rowArray截取截取一部分字节
Append(final byte [] rowArray, final int rowOffset, final int rowLength)
Increment
Increment构造方法:
Increment(byte [] row)
Increment(final byte [] row, final int offset, final int length)
Increment(Increment i)
在使用Increment时,一定要保证你在Hbase存储的数据是Long类型的
put.addColumn("info".getBytes(),"age1".getBytes(),Bytes.toBytes(6L));
Increment incre = new Increment("r1".getBytes());
incre.addColumn("info".getBytes(),"age1".getBytes(),10L);
table.increment(incre);
输出结果16
2.Get
Get方法相当于shell命令中的get方法,即查,和Put一样都是Table接口提供的方法
其构造方法最常用最简单的:
因此,Get类只能够根据行键去查
Get(byte [] row)
你也可以使用get对象就行一些设置,比如最大版本,添加要取的列族等
get.setMaxVersions();
get.addColumn("cf".getBytes(),"name".getBytes());
最后通过get方法进行获取,返回Result类型
使用Result对象的getValue方法获取单元格数据
Result result = table.get(get);
byte[] value = result.getValue(Bytes.toBytes("info2"), Bytes.toBytes("name"));
System.out.println(Bytes.toString(value));
Result
Hbase会把get查询到的数据封装到result实例中,result还有其他方法:
byte [] value,//用于你只查询一个列的值
boolean isEmpty //查询结果是否为空
int size()//返回查找列的数量
Cell
get.setMaxVersions();//设置最大版本
List<Cell> cells = result.getColumnCells(Bytes.toBytes("info2"), Bytes.toBytes("name"));
for (Cell cell:cells){
//通过循环将以前版本数据全部输出
//相当于shell命令
// get 'user','r1',{COLUMN=>'info1:name',VERSIONS=>10}
//byte[] value = cell.getValue();
byte[] cValue = CellUtil.cloneValue(cell);
System.out.println(Bytes.toString(cValue));
}
3.delete
常用构造方法,其实不用说也知道
Delete(byte [] row)
delete.addColumn("cf".getBytes(),"name".getBytes());//删除指定列的最新版本
delete.addColumn("cf".getBytes(),"name".getBytes(),2222222222222L);//删除指定列的版本
delete.addFamily("cf".getBytes());//删除指定列族的所有版本的列
delete.addFamily("cf".getBytes(),2222222222222L);//删除指定列族的小于等于指定版本号的所有列
delete.addColumns("cf".getBytes(),"name".getBytes());//删除指定列的所有版本
delete.addColumns("cf".getBytes(),"name".getBytes(),222222L);//删除指定列的的小于等于指定版本号的所有列
checkAndDelete
如果数据一致则true进行删除,否则false,删除不会发生返回false
boolean b = table.checkAndDelete("r1".getBytes(), "cf".getBytes(), "name".getBytes(), "name1".getBytes(), delete);
mutationRow
如果我们想要同时对多个列进行操作,那么就需要使用mutationRow方法
此方法有两个构造函数
RowMutations()//源码上说这个方法不使用
RowMutations(byte [] row)
add(Put p)
add(Delete p)
RowMutations rowMutations = new RowMutations("r1".getBytes());
//添加id列
Put put = new Put("r1".getBytes());
put.addColumn("info1".getBytes(),"id".getBytes(),"1".getBytes());
//修改info1:name列值
Put edit = new Put("r1".getBytes());
edit.addColumn("info1".getBytes(),"name".getBytes(),"nnnn1".getBytes());
//删除sex列
Delete delete = new Delete("r1".getBytes());
delete.addColumn("info1".getBytes(),"sex".getBytes());
rowMutations.add(put);
rowMutations.add(edit);
rowMutations.add(delete);
table.mutateRow(rowMutations);
和Put,Delete 一样,mutationRow也是有checkAndMutate方法,不过,这一次必须要使用Put,Delete的那个第二种方式采取枚举的方式
boolean b = table.checkAndMutate("r1".getBytes(), "info1".getBytes(), "name".getBytes(), CompareFilter.CompareOp.EQUAL, "name1".getBytes(), rowMutations);
4.Scan扫描
Scan构造方法:
Scan()//扫描所有的行
Scan(byte [] startRow)//从startRow开始扫描
Scan(byte [] startRow, Filter filter)//从startRow开始扫描被filter过滤的行
Scan(byte [] startRow, byte [] stopRow)//扫描[startRow,stopRow)之间的行
Scan和get有本质上不同,table.getScanner(scan)这一步只是获取结果扫描器(ResultScanner)并不是实际返回结果,必须遍历ResultScanner才可以得到值
ResultScanner results = table.getScanner(scan);
Iterator<Result> iterator = results.iterator();
for (Result result:results ){
byte[] value = result.getValue("info1".getBytes(), "name".getBytes());
System.out.println(Bytes.toString(value));
}