需求:
将HBase中的表封装成对象,类似于MyBatis框架中的一张表封装成一个对象,类对应表名,字段对应属性, 因此使用注解可以实现这种场景
实现流程:
使用idea工具创建注解
对于HBase表的特性,我们需要依次创建Table(表名),Column(列),RowKey(主键)等注解
Table
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String value(); // 用来存放注解中的值,并且如果需要获取注解中的值可以用过这个获取
}
Column
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String family() default "info"; // 给注解的这个属性一个默认的值,但注解没有给这个属性赋值时,默认这个值
String column() default "";
}
RowKey
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
/**
* 这个注解只需用来指明哪个属性是表的主键
*/
public @interface RowKey {
}
@Target({ElementType.TYPE}):表示注解只能注解类 @Retention(RetentionPolicy.RUNTIME):注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在 @Target({ElementType.FIELD}):表示注解只能注解属性
创建一个对象来使用
// 指明这个对象对应表 ct:calllog
@Table("ct:calllog")
public class Calllog {
// 表明这个属性为表的主键
@RowKey
private String rowKey;
// 表示这个属性在caller这个列族中
@Column(family = "caller")
private String call1;
@Column(family = "caller")
private String call2;
@Column(family = "caller")
private String callTime;
@Column(family = "caller")
private String duration;
@Column(family = "caller")
private String flag = "1";
public Calllog(){
}
public Calllog(String data) {
String[] datas = data.split("\t");
this.call1 = datas[0];
this.call2 = datas[1];
this.callTime = datas[2];
this.duration = datas[3];
}
public String getRowKey() {
return rowKey;
}
public void setRowKey(String rowKey) {
this.rowKey = rowKey;
}
public String getCall1() {
return call1;
}
public void setCall1(String call1) {
this.call1 = call1;
}
public String getCall2() {
return call2;
}
public void setCall2(String call2) {
this.call2 = call2;
}
public String getCallTime() {
return callTime;
}
public void setCallTime(String callTime) {
this.callTime = callTime;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
}
既然一张表对应一个对象,那么我们就可以实现代码自动封装数据,将数据对象直接保存到HBase,以后我们只需根据HBase表创建相应的类,加上注解表明,其余的操作都不用管,节省了大量的插入冗余操作
代码实现
/**
* 自动封装数据,将数据对象直接保存到HBase
* @param object
*/
protected void putData(Object object) throws Exception {
// 获取对象的类
Class clazz = object.getClass();
// 获取类的注解
Table table = (Table)clazz.getAnnotation(Table.class);
// 根据注解获取表名
String tableName = table.value();
// 获取类属性
Field[] fields = clazz.getDeclaredFields();
String rowKey = "";
// 遍历类所有的属性,获取含有RowKey注解的属性
for (Field field : fields) {
RowKey rowkey = (RowKey)field.getAnnotation(RowKey.class);
if ( rowkey != null ){
// 获取对象中的属性值
field.setAccessible(true);
rowKey = (String)field.get(object);
break;
}
}
Connection conn = getConnection();
Table table = conn.getTable(TableName.valueOf(tableName));
Put put = new Put(Bytes.toBytes(rowKey));
// 遍历类中的所有属性,获取含有Column注解的属性
for (Field field : fields) {
Column column = (Column)field.getAnnotation(Column.class);
if ( column != null ){
// 获取属性中的注解中的值
String columnName = column.column();
// 如果注解中没赋值,则列名默认取属性名
if ( columnName == null || columnName.equals("") ){
// 获取属性的属性名
columnName = field.getName();
}
// 获取属性值
field.setAccessible(true);
String value = (String)field.get(object);
put.addColumn(Bytes.toBytes(column.family()),
Bytes.toBytes(columnName),
Bytes.toBytes(value));
}
}
table.put(put);
table.close();
}