import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
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;
/**
HBase当中的核心API :13个
HBaseConfiguration 配置信息
Connection
HBaseAdmin/Admin 管理员
HTable 整个表的抽象信息
HColumnDescriptor 列的描述信息
HTableDescriptor 列簇的描述信息
Put
Delete
Get
Scan
KeyValue
Cell
Result
ResultScanner
*/
public class HBase_First {
public static void main(String[] args) throws Exception {
/**
* 第一步: 获取连接
*/
// 创建一个可以用来管理hbase配置信息的config对象
Configuration config = HBaseConfiguration.create();
// 设置当前的程序去寻找的hbase在哪里
config.set("hbase.zookeeper.quorum", "hadoop02:2181,hadoop03:2181,hadoop04:2181");
//创建和建立连接
Connection con = ConnectionFactory.createConnection(config);
// 根据连接获取到一个管理员对象
Admin admin = con.getAdmin();
/**
* 第二步:通过连接进行数据库的响应操作
*/
//检查表是否存在,存在返回true
boolean tableExists = admin.tableExists(TableName.valueOf("user_info_1"));
System.out.println(tableExists);
/**
* 第三步:关闭连接
*/
admin.close();
con.close();
}
}
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
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;
import org.junit.Before;
import org.junit.Test;
public class HBase_API {
private static final String ZK_CONNECT_KEY = "hbase.zookeeper.quorum";
private static final String ZK_CONNECT_VALUE = "hadoop02:2181,hadoop03:2181,hadoop04:2181";
public static void main(String[] args) {
}
private static Connection con = null;
private static Admin admin = null;
private static Table table = null;
@Before
public void init(){
// 创建一个可以用来管理hbase配置信息的config对象
Configuration config = HBaseConfiguration.create();
// 设置当前的程序去寻找的hbase在哪里
config.set(ZK_CONNECT_KEY, ZK_CONNECT_VALUE);
try {
//创建和建立连接
con = ConnectionFactory.createConnection(config);
// 根据连接获取到一个管理员对象(做一个管理的操作如创建、删除、查询表用admin,针对表做具体的数据操作就通过con来获取表的对象)
admin = con.getAdmin();
//获取专门用来进行数据处理的、代表某张表的一个 表对象table,用来操作user_info这个表
table = con.getTable(TableName.valueOf("user_info"));
} catch (Exception e) {
System.out.println("获取hbase连接失败");
}
}
/**
* 创建表的方法
*/
@Test
public void createTable() throws Exception{
//创建一个表名对象tn,表名为my_stu
TableName tn = TableName.valueOf("my_stu");
//创建一个表的描述对象HTableDescriptor(包含表名和列簇名),并且它的表名为tn对象的值--my_stu
HTableDescriptor htd = new HTableDescriptor(tn);
//创建一个列簇为"cf1"的列簇对象cf1,注意在创建表时候必须写列簇
HColumnDescriptor cf1 = new HColumnDescriptor("cf1");
//添加一个列簇对象cf1
htd.addFamily(cf1);
//创建一个表
admin.createTable(htd);
//如果有tn名字的表,那么创建成功
if(admin.tableExists(tn)){
System.out.println("创建表成功");
}else{
System.out.println("创建表失败");
}
}
/**
* 输出所有的表的列簇名字
*/
@Test
public void listTables() throws Exception{
//HTableDescriptor的对象包含表名和列簇名,获取数据库中的所有表的信息
HTableDescriptor[] listTables = admin.listTables();
for(HTableDescriptor htd: listTables){
//输出所有的表名
System.out.print(htd.getTableName() + "\t");
//获取所有的列簇的一个集合
HColumnDescriptor[] columnFamilies = htd.getColumnFamilies();
for(HColumnDescriptor hcd : columnFamilies){
//获取当前列簇的名字getName()返回的是字节类型的
String name = Bytes.toString(hcd.getName());
// String name = new String(hcd.getName())
System.out.print(name + " ");
}
System.out.println();
}
}
/**
* 删除表
*/
@Test
public void dropTable() throws Exception{
//表名对象
TableName tn = TableName.valueOf("my_stu");
//检查表是否有效,也就是表是否启用,启用返回true,停用返回false
boolean tableEnabled = admin.isTableEnabled(tn);
if(tableEnabled){//先判断表的状态比较稳妥,否则停用状态再停用可能出问题
//把tn表停用
admin.disableTable(tn);
}
//删除my_stu表(先停用表再删除表)
admin.deleteTable(tn);
//判断tn表在不在数据库里面,如果在返回true
if(admin.tableExists(tn)){
System.out.println("删除表失败");
}else{
System.out.println("删除表成功");
}
}
/**
* 表示往某张表中进行数据的插入
*
* 专门用来进行数据处理的、代表某张表的一个 表对象,就是 HTable 类的一个实例对象----table
*/
//向某张表中插入一条数据
@Test
public void putData() throws Exception{
//创建一个put对象,因为要插入数据所以必须指定row key,现在仅仅是指定行健,没有对应的keyvalue值
Put put = new Put("rk01".getBytes());
//指定列簇、列、值,现在要插入的一行数据就准备好了
put.addColumn("base_info".getBytes(), "xx".getBytes(), "yy".getBytes());
//往表里插入数据,传一个put对象插入一行记录,穿多个put对象插入多行记录
table.put(put);
}
//向某张表中插入多条记录
@Test
public void putDatas() throws Exception{
Put put1 = new Put("rk03".getBytes());
put1.addColumn("base_info".getBytes(), "xxx".getBytes(), "yy".getBytes());
Put put2 = new Put("rk02".getBytes());
put2.addColumn("base_info".getBytes(), "xxx".getBytes(), "yy".getBytes());
List<Put> puts = new ArrayList();
puts.add(put1);
puts.add(put2);
//.put()方法可以传list的一堆Put对象,插入就用put()方法
table.put(puts);
}
//删除数据
@Test
public void deleteData() throws Exception{
//在增删改查row key都需要指定的,如果不写addColumn()那么就是删除rk这一行的数据
Delete delete = new Delete("rk02".getBytes());
//删除rk02这条记录下的base_info列簇的xxx key
delete.addColumn("base_info".getBytes(), "xxx".getBytes());
//删除就用delete()方法
table.delete(delete);
}
//get查询某个表中的数据
@Test
public void getData() throws Exception{
//行键row key,如果不下addFamily()方法就是查询一行的所有列簇下的所有cell的信息
Get get = new Get("baiyc_20150716_0005".getBytes());
//添加一个列簇对象(用来查询指定列簇下的cell信息)
get.addFamily("base_info".getBytes());
//返回一个Result对象
Result result = table.get(get);
//返回所有查询到的单元格cell
List<Cell> cells = result.listCells();
//循环拿cell
for(Cell c : cells){
//直接打印是看不懂的,cells本身就是个字节数组
System.out.println(c.toString());
//获取到列簇信息
String family = Bytes.toString(c.getFamily());
//获取到列key信息
String qualifier = Bytes.toString(c.getQualifier());
//获取到value值
String value = Bytes.toString(c.getValue());
//获取时间戳
long ts = c.getTimestamp();
System.out.println(family + "\t" + qualifier + "\t" + value + "\t" + ts);
}
}
//Scan查询某个表中的数据
@Test
public void getResultScanner() throws Exception{
//无参方法就是全部,不写下面的限制范围的方法就是全表扫描
Scan scan = new Scan();
//查询某些特定的列簇
// scan.addFamily("base_info".getBytes());
//查询base_info列簇和name列的信息
scan.addColumn("base_info".getBytes(), "name".getBytes());
//从哪个行键开始扫描
scan.setStartRow("rk01".getBytes());
//从哪个行键结束扫描
scan.setStopRow("zhangsan_20150701_0004".getBytes());
//上面的四条限制范围都可以单独或同时使用,且使用越多越严格
ResultScanner scanner = table.getScanner(scan);
//解析ResultScanner对象的信息并且打印输出,跟上面的很像
for (Result result : scanner) {
List<Cell> cells = result.listCells();
for (int i = 0; i < cells.size(); i++) {
Cell cell = cells.get(i);
System.out.println(Bytes.toString(cell.getRow()) + "\t" + Bytes.toString(cell.getFamily()) + "\t" + Bytes.toString(cell.getQualifier())
+ "\t" + Bytes.toString(cell.getValue()) + "\t" + cell.getTimestamp());
}
}
}
}
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
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.HTable;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.FamilyFilter;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.PageFilter;
import org.apache.hadoop.hbase.filter.RowFilter;
import com.ghgj.hbase.util.HBasePrintUtil;
public class FliterTest {
private static final String ZK_CONNECT_KEY = "hbase.zookeeper.quorum";
private static final String ZK_CONNECT_VALUE = "hadoop02:2181,hadoop03:2181,hadoop04:2181";
public static void main(String[] args) throws Exception {
Configuration conf = HBaseConfiguration.create();
conf.set(ZK_CONNECT_KEY, ZK_CONNECT_VALUE);
Connection con = ConnectionFactory.createConnection(conf);
Admin admin = con.getAdmin();
HTable table = (HTable) con.getTable(TableName.valueOf("user_info"));
Scan scan = new Scan();
/**
* 在这儿给scan添加过滤器
*
* 构造过滤器的时候,要注意这两个参数的意义:
*
* 第一个参数: 比较规则
* 第二个参数: 比较器
*/
Filter filter1 = new RowFilter(CompareOp.GREATER, new BinaryComparator("rk03".getBytes()));
Filter filter2 = new FamilyFilter(CompareOp.EQUAL, new BinaryComparator("base_info".getBytes()));
/**
* 分页过滤的构造参数就是 : 每一页的总数据条数
* Filter pageFilter = new PageFilter(3,4); ---- id : 9-12
* 真正的分页实现就只需要两个参数: pageIndex pageSize
*
* pageIndex: 第几页
*
* pageSzie :每页大小
*/
Filter pageFilter = new PageFilter(3);
Filter filter = new FilterList(filter1, filter2, pageFilter);
scan.setFilter(filter);
ResultScanner scanner = table.getScanner(scan);
HBasePrintUtil.printResultScanner(scanner);
admin.close();
con.close();
}
}
package com.ghgj.hbase.page;
import java.io.IOException;
import java.util.Iterator;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hbase.client.Connection;
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.filter.Filter;
import org.apache.hadoop.hbase.filter.PageFilter;
import org.apache.hadoop.hbase.util.Bytes;
import com.ghgj.hbase.util.HBasePrintUtil;
import com.ghgj.hbase.util.HBaseUtil;
public class HBase_Page {
public static void main(String[] args) throws Exception {
// ResultScanner pageData = getPageData(3, 10);
// ResultScanner pageData = getPageData(2, 2);
// ResultScanner pageData1 = getPageData(1, 3);
// ResultScanner pageData1 = getPageData("baiyc_20150716_0002", 3);
// ResultScanner pageData2 = getPageData("rk01", 3);
ResultScanner pageData2 = getPageData(3, 2000);
HBasePrintUtil.printResultScanner(pageData2);
}
/**
* @param pageIndex 第几页
* @param pageSize 每一页的记录总数
* @return
*
* 负责编写JS代码的前端人员。他们是不知道。怎么传入startRow
*/
public static ResultScanner getPageData(int pageIndex, int pageSize) throws Exception{
if(pageSize < 3 || pageSize > 15){
pageSize = 5;
}
/**
* 当前这个代码的真实作用就是把:;
*
* "baiyc_20150716_0001", 3
*
* 转换成:
*
* 2, 3
*
* 难点: 就是 pageIndex 转成 startRow
*/
String startRow = getCurrentPageStartRow(pageIndex, pageSize);
return getPageData(startRow, pageSize);
}
/**
* 当前这个方法的作用:
*
* 就是把 前端人员 穿送过来的 pageIndex 转换成 startRow
*
* 以方便调用底层最简单的获取一页分页数据的 方法: getPageData(startRow, pageSize)
*
* @param pageIndex
* @param pageSize
* @return
*/
private static String getCurrentPageStartRow(int pageIndex, int pageSize) throws Exception {
// 怎么实现?
// 如果 传送过来的额 pageIndex 不合法。 默认返回 第一页数据
if(pageIndex <= 1){
/*pageIndex == -1
转成了
startRow == null*/
return null;
}else{
// 从第二页开始的所有数据。
String startRow = null;
for(int i = 1; i <= pageIndex - 1; i++){
// 第几次循环,就是获取第几页的数据
ResultScanner pageData = getPageData(startRow, pageSize);
// 获取当前这一页的最后rowkey
Iterator<Result> iterator = pageData.iterator();
Result result = null;
while(iterator.hasNext()){
result = iterator.next();
}
// 让最后一个rowkey往后挪动一点位置,但是又不会等于下一页的 startRow
String endRowStr = new String(result.getRow());
byte[] add = Bytes.add(endRowStr.getBytes(), new byte[]{ 0x00});
String nextPageStartRowStr = Bytes.toString(add);
//
startRow = nextPageStartRowStr;
}
return startRow;
}
}
/**
* 描述:
*
* 从 startRow开始 查询 pageSize 条数据
*
* @param startRow
* @param pageSize
* @return
*/
public static ResultScanner getPageData(String startRow, int pageSize) throws IOException{
Connection con = HBaseUtil.getConnection();
// Admin admin = HBaseUtil.getAdmin();
Table table = HBaseUtil.getTable("user_info");
Scan scan = new Scan();
// 设置起始行健搞定
// 如果是第一页数据, 所以 scan.setStartRow这句代码根本就没有任何意义。。 不用设置即可
if(!StringUtils.isBlank(startRow)){
// 如果用户不传入 startRow, 或者传入了一个 非法的 startRow, 还是按照规则 返回 第一页数据
scan.setStartRow(startRow.getBytes());
}
// 设置总数据条件
Filter pageFilter = new PageFilter(pageSize);
scan.setFilter(pageFilter);
ResultScanner scanner = table.getScanner(scan);
return scanner;
}
}
package com.ghgj.hbase.mr;
import java.io.IOException;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.mapreduce.TableMapper;
import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.DoubleWritable;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
/**
* get 'stduent','rk01' ==== Result
*
* 需求:读出所有的记录(Result),然后提取出对应的 age 信息
*
* mapper阶段的
*
* 输入: 从hbase来
*
* key : rowkey
* value : result
*
* ImmutableBytesWritable, Result
*
* 输出: hdfs
*
* key : age
* value : 年龄值
*
* reducer阶段:
*
* 输入:
*
* key : "age"
* value : 年龄值 = 18
*
* 输出:
*
* key: NullWritbale
* value: 平均
*/
public class ReadDataFromHBaseToHDFSMR extends Configured implements Tool {
public static void main(String[] args) throws Exception {
int run = ToolRunner.run(new ReadDataFromHBaseToHDFSMR(), args);
System.exit(run);
}
@Override
public int run(String[] arg0) throws Exception {
Configuration config = HBaseConfiguration.create();
config.set("hbase.zookeeper.quorum", "hadoop02:2181,hadoop03:2181");
config.set("fs.defaultFS", "hdfs://myha01/");
config.addResource("config/core-site.xml");
config.addResource("config/hdfs-site.xml");
System.setProperty("HADOOP_USER_NAME", "hadoop");
Job job = Job.getInstance(config, "ReadDataFromHBaseToHDFSMR");
job.setJarByClass(ReadDataFromHBaseToHDFSMR.class);
// 从此开始,就是设置当前这个MR程序的各种job细节
Scan scan = new Scan();
scan.addColumn("info".getBytes(), "age".getBytes());
TableMapReduceUtil.initTableMapperJob(
"student".getBytes(), // 指定表名
scan, // 指定扫描数据的条件
ReadDataFromHBaseToHDFSMR_Mapper.class, // 指定mapper class
Text.class, // outputKeyClass mapper阶段的输出的key的类型
IntWritable.class, // outputValueClass mapper阶段的输出的value的类型
job,
false); // job对象
job.setReducerClass(ReadDataFromHBaseToHDFSMR_Reducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(DoubleWritable.class);
/**
* 在当前的MR程序中。 输入的数据是来自于 HBase, 按照常理来说,需要自定义一个数据读取组件 读 hbase
*
* 但是:TableMapReduceUtil.initTableMapperJob 这个方法已经做了。!!!!!!
*/
FileOutputFormat.setOutputPath(job, new Path("/student/avgage_output2"));
boolean isDone = job.waitForCompletion(true);
return isDone ? 0 : 1;
}
public static class ReadDataFromHBaseToHDFSMR_Mapper extends TableMapper<Text, IntWritable>{
Text outKey = new Text("age");
/**
* key = 就是rowkey
*
* value = 就是一个result对象
*/
@Override
protected void map(ImmutableBytesWritable key, Result value, Context context) throws IOException, InterruptedException {
boolean containsColumn = value.containsColumn("info".getBytes(), "age".getBytes());
if(containsColumn){
List<Cell> cells = value.getColumnCells("info".getBytes(), "age".getBytes());
Cell cell = cells.get(0);
byte[] cloneValue = CellUtil.cloneValue(cell);
String age = Bytes.toString(cloneValue);
context.write(outKey, new IntWritable(Integer.parseInt(age)));
}
}
}
public static class ReadDataFromHBaseToHDFSMR_Reducer extends Reducer<Text, IntWritable, Text, DoubleWritable>{
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int count = 0;
int sum = 0;
for(IntWritable iw : values){
count++;
sum += iw.get();
}
double avgAge = sum * 1D / count;
context.write(key, new DoubleWritable(avgAge));
}
}
}
package com.ghgj.hbase.mr;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.mapreduce.TableReducer;
import org.apache.hadoop.hbase.mapreduce1111.TableMapReduceUtil;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import org.junit.runner.Result;
/**
* 需求:读取HDFS上的数据。插入到HBase库中
*
* hbase.zookeeper.quorum == hadoop02:2181
*/
public class ReadHDFSDataToHBaseMR extends Configured implements Tool{
@Override
public int run(String[] arg0) throws Exception {
// Configuration conf = new Configuration();
// conf.set("fs.defaultFS", "hdfs://myha01/");
// conf.addResource("config/core-site.xml");
// conf.addResource("config/hdfs-site.xml");
// config === HBaseConfiguration
Configuration config = HBaseConfiguration.create();
config.set("hbase.zookeeper.quorum", "hadoop02:2181,hadoop03:2181");
config.set("fs.defaultFS", "hdfs://myha01/");
config.addResource("config/core-site.xml");
config.addResource("config/hdfs-site.xml");
System.setProperty("HADOOP_USER_NAME", "hadoop");
Job job = Job.getInstance(config, "ReadHDFSDataToHBaseMR");
job.setJarByClass(ReadHDFSDataToHBaseMR.class);
job.setMapperClass(HBaseMR_Mapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(NullWritable.class);
// 设置数据读取组件
job.setInputFormatClass(TextInputFormat.class);
// 设置数据的输出组件
// job.setOutputFormatClass(cls);
// TableMapReduceUtil.initTableReducerJob("student", HBaseMR_Reducer.class, job);
TableMapReduceUtil.initTableReducerJob("student", HBaseMR_Reducer.class, job, null, null, null, null, false);
job.setOutputKeyClass(NullWritable.class);
job.setOutputValueClass(Put.class);
// FileInputFormat.addInputPath(job, new Path("E:\\bigdata\\hbase\\student\\input"));
FileInputFormat.addInputPath(job, new Path("/student/input/"));
boolean isDone = job.waitForCompletion(true);
return isDone ? 0: 1;
}
public static void main(String[] args) throws Exception {
int run = ToolRunner.run(new ReadHDFSDataToHBaseMR(), args);
System.exit(run);
}
public static class HBaseMR_Mapper extends Mapper<LongWritable, Text, Text, NullWritable>{
/**
* 每次读取一行数据
*
* Put : 构造一个put对象的时候,需要
* put 'stduent','95001','cf:name','liyong'
*
*
* name:huangbo
* age:18
*
* name:xuzheng
*
*/
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, NullWritable>.Context context)
throws IOException, InterruptedException {
context.write(value, NullWritable.get());
}
}
public static class HBaseMR_Reducer extends TableReducer<Text, NullWritable, NullWritable>{
/**
* key === 95011,包小柏,男,18,MA
*
* 95001: rowkey
* 包小柏 : name
* 18 : age
* 男 : sex
* MA : department
*
* column family : cf
*/
@Override
protected void reduce(Text key, Iterable<NullWritable> values, Context context) throws IOException, InterruptedException {
String[] split = key.toString().split(",");
Put put = new Put(split[0].getBytes());
put.addColumn("info".getBytes(), "name".getBytes(), split[1].getBytes());
put.addColumn("info".getBytes(), "sex".getBytes(), split[2].getBytes());
put.addColumn("info".getBytes(), "age".getBytes(), split[3].getBytes());
put.addColumn("info".getBytes(), "department".getBytes(), split[4].getBytes());
context.write(NullWritable.get(), put);
}
}
}