java程序连接HBase

PixPin_2026-01-05_14-40-50

PixPin_2026-01-05_14-40-59

PixPin_2026-01-05_14-41-11

PixPin_2026-01-05_14-41-18

PixPin_2026-01-05_14-41-26

PixPin_2026-01-05_14-41-33

HBaseStudentOperation:

package com.hadoop.experiment6;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * HBase学生表操作类
 * 完成实验4的HBase部分
 */
public class HBaseStudentOperation {

    private static Configuration conf = null;
    private static Connection connection = null;

    /**
     * 静态初始化块,创建HBase连接
     */
    static {
        try {
            // 创建HBase配置
            conf = HBaseConfiguration.create();
            // 设置ZooKeeper地址(根据你的虚拟机IP)
            conf.set("hbase.zookeeper.quorum", "192.168.249.129");
            conf.set("hbase.zookeeper.property.clientPort", "2181");
            // 设置超时时间
            conf.set("hbase.client.operation.timeout", "30000");
            conf.set("hbase.client.scanner.timeout.period", "30000");

            // 创建连接
            connection = ConnectionFactory.createConnection(conf);
            System.out.println("✓ HBase连接成功");

        } catch (IOException e) {
            System.err.println("✗ HBase连接失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 关闭连接
     */
    public static void close() {
        if (connection != null) {
            try {
                connection.close();
                System.out.println("✓ HBase连接已关闭");
            } catch (IOException e) {
                System.err.println("关闭连接失败: " + e.getMessage());
            }
        }
    }

    /**
     * 工具方法:打印分隔线
     */
    private static void printSeparator(String title) {
        System.out.println("\n" + repeatString("=", 60));
        System.out.println(title);
        System.out.println(repeatString("=", 60));
    }

    private static void printSubSeparator(String title) {
        System.out.println("\n" + repeatString("-", 40));
        System.out.println(title);
        System.out.println(repeatString("-", 40));
    }

    /**
     * 重复字符串(兼容Java 1.8)
     */
    private static String repeatString(String str, int count) {
        if (count <= 0) {
            return "";
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < count; i++) {
            sb.append(str);
        }
        return sb.toString();
    }

    /**
     * 1. 创建Student表(如果存在则先删除)
     * 表结构:两个列族 name 和 score
     */
    public static void createStudentTable() throws IOException {
        printSeparator("1. 创建Student表");

        if (connection == null) {
            throw new IOException("HBase连接未建立");
        }

        try (Admin admin = connection.getAdmin()) {
            TableName tableName = TableName.valueOf("Student");

            // 检查表是否存在,存在则删除
            if (admin.tableExists(tableName)) {
                System.out.println("表 Student 已存在,先删除...");

                // 禁用表
                if (admin.isTableEnabled(tableName)) {
                    admin.disableTable(tableName);
                    System.out.println("  已禁用表");
                }

                // 删除表
                admin.deleteTable(tableName);
                System.out.println("  已删除表");
            }

            // 创建表描述符
            TableDescriptorBuilder tableBuilder = TableDescriptorBuilder.newBuilder(tableName);

            // 添加列族:name(用于存储姓名信息,虽然表中name是行键,但这里还是创建列族)
            ColumnFamilyDescriptor nameFamily = ColumnFamilyDescriptorBuilder
                    .newBuilder(Bytes.toBytes("name"))
                    .setMaxVersions(1)
                    .build();
            tableBuilder.setColumnFamily(nameFamily);

            // 添加列族:score(用于存储各科成绩)
            ColumnFamilyDescriptor scoreFamily = ColumnFamilyDescriptorBuilder
                    .newBuilder(Bytes.toBytes("score"))
                    .setMaxVersions(1)
                    .build();
            tableBuilder.setColumnFamily(scoreFamily);

            // 创建表
            TableDescriptor tableDesc = tableBuilder.build();
            admin.createTable(tableDesc);
            System.out.println("✓ Student表创建成功");
            System.out.println("  列族: name, score");

        } catch (Exception e) {
            System.err.println("创建表失败: " + e.getMessage());
            throw e;
        }
    }

    /**
     * 2. 插入初始数据
     * zhangsan: English=69, Math=86, Computer=77
     * lisi: English=55, Math=100, Computer=88
     */
    public static void insertInitialData() throws IOException {
        printSeparator("2. 插入初始数据");

        try (Table table = connection.getTable(TableName.valueOf("Student"))) {

            // 插入zhangsan的数据
            Put put1 = new Put(Bytes.toBytes("zhangsan"));
            put1.addColumn(Bytes.toBytes("score"), Bytes.toBytes("English"), Bytes.toBytes("69"));
            put1.addColumn(Bytes.toBytes("score"), Bytes.toBytes("Math"), Bytes.toBytes("86"));
            put1.addColumn(Bytes.toBytes("score"), Bytes.toBytes("Computer"), Bytes.toBytes("77"));
            table.put(put1);
            System.out.println("✓ 插入zhangsan: English=69, Math=86, Computer=77");

            // 插入lisi的数据
            Put put2 = new Put(Bytes.toBytes("lisi"));
            put2.addColumn(Bytes.toBytes("score"), Bytes.toBytes("English"), Bytes.toBytes("55"));
            put2.addColumn(Bytes.toBytes("score"), Bytes.toBytes("Math"), Bytes.toBytes("100"));
            put2.addColumn(Bytes.toBytes("score"), Bytes.toBytes("Computer"), Bytes.toBytes("88"));
            table.put(put2);
            System.out.println("✓ 插入lisi: English=55, Math=100, Computer=88");

        } catch (Exception e) {
            System.err.println("插入数据失败: " + e.getMessage());
            throw e;
        }
    }

    /**
     * 3. 用scan命令浏览Student表的相关信息
     */
    public static void scanStudentTable() throws IOException {
        printSeparator("3. 浏览Student表的所有记录");

        try (Table table = connection.getTable(TableName.valueOf("Student"))) {
            Scan scan = new Scan();
            ResultScanner scanner = table.getScanner(scan);

            System.out.println("行键\t\t列族:列\t\t值");
            System.out.println(repeatString("-", 50));

            int rowCount = 0;
            for (Result result : scanner) {
                rowCount++;
                String rowKey = Bytes.toString(result.getRow());

                for (Cell cell : result.rawCells()) {
                    String family = Bytes.toString(CellUtil.cloneFamily(cell));
                    String qualifier = Bytes.toString(CellUtil.cloneQualifier(cell));
                    String value = Bytes.toString(CellUtil.cloneValue(cell));

                    System.out.printf("%-10s\t%s:%s\t\t%s\n", rowKey, family, qualifier, value);
                }
            }

            if (rowCount == 0) {
                System.out.println("表为空");
            } else {
                System.out.println("\n✓ 总共 " + rowCount + " 行记录");
            }

            scanner.close();

        } catch (Exception e) {
            System.err.println("扫描表失败: " + e.getMessage());
            throw e;
        }
    }

    /**
     * 4. 查询zhangsan的Computer成绩
     */
    public static void queryZhangsanComputerScore() throws IOException {
        printSeparator("4. 查询zhangsan的Computer成绩");

        try (Table table = connection.getTable(TableName.valueOf("Student"))) {
            Get get = new Get(Bytes.toBytes("zhangsan"));
            get.addColumn(Bytes.toBytes("score"), Bytes.toBytes("Computer"));

            Result result = table.get(get);

            byte[] value = result.getValue(Bytes.toBytes("score"), Bytes.toBytes("Computer"));
            if (value != null) {
                String score = Bytes.toString(value);
                System.out.println("学生: zhangsan");
                System.out.println("科目: Computer");
                System.out.println("成绩: " + score);
            } else {
                System.out.println("未找到zhangsan的Computer成绩");
            }

        } catch (Exception e) {
            System.err.println("查询失败: " + e.getMessage());
            throw e;
        }
    }

    /**
     * 5. 修改lisi的Math成绩,改为95
     */
    public static void updateLisiMathScore() throws IOException {
        printSeparator("5. 修改lisi的Math成绩,改为95");

        try (Table table = connection.getTable(TableName.valueOf("Student"))) {
            // 先获取旧值
            Get get = new Get(Bytes.toBytes("lisi"));
            get.addColumn(Bytes.toBytes("score"), Bytes.toBytes("Math"));

            Result result = table.get(get);
            byte[] oldValue = result.getValue(Bytes.toBytes("score"), Bytes.toBytes("Math"));

            if (oldValue != null) {
                System.out.println("原成绩: " + Bytes.toString(oldValue));
            } else {
                System.out.println("原成绩: 不存在");
            }

            // 修改为95
            Put put = new Put(Bytes.toBytes("lisi"));
            put.addColumn(Bytes.toBytes("score"), Bytes.toBytes("Math"), Bytes.toBytes("95"));
            table.put(put);

            System.out.println("新成绩: 95");
            System.out.println("✓ 修改成功");

        } catch (Exception e) {
            System.err.println("修改失败: " + e.getMessage());
            throw e;
        }
    }

    /**
     * 6. 添加scofield的数据
     * 实验要求2(1): English:45 Math:89 Computer:100
     */
    public static void addScofieldRecord() throws IOException {
        printSeparator("6. 添加scofield记录");

        try (Table table = connection.getTable(TableName.valueOf("Student"))) {
            Put put = new Put(Bytes.toBytes("scofield"));
            put.addColumn(Bytes.toBytes("score"), Bytes.toBytes("English"), Bytes.toBytes("45"));
            put.addColumn(Bytes.toBytes("score"), Bytes.toBytes("Math"), Bytes.toBytes("89"));
            put.addColumn(Bytes.toBytes("score"), Bytes.toBytes("Computer"), Bytes.toBytes("100"));

            table.put(put);

            System.out.println("✓ 添加scofield记录成功");
            System.out.println("  English: 45");
            System.out.println("  Math: 89");
            System.out.println("  Computer: 100");

        } catch (Exception e) {
            System.err.println("添加记录失败: " + e.getMessage());
            throw e;
        }
    }

    /**
     * 7. 获取scofield的English成绩信息
     * 实验要求2(2)
     */
    public static void getScofieldEnglishScore() throws IOException {
        printSeparator("7. 获取scofield的English成绩信息");

        try (Table table = connection.getTable(TableName.valueOf("Student"))) {
            Get get = new Get(Bytes.toBytes("scofield"));
            get.addColumn(Bytes.toBytes("score"), Bytes.toBytes("English"));

            Result result = table.get(get);

            byte[] value = result.getValue(Bytes.toBytes("score"), Bytes.toBytes("English"));
            if (value != null) {
                String score = Bytes.toString(value);
                System.out.println("学生: scofield");
                System.out.println("科目: English");
                System.out.println("成绩: " + score);

                // 显示成绩等级
                int scoreInt = Integer.parseInt(score);
                String grade = getGrade(scoreInt);
                System.out.println("等级: " + grade);
            } else {
                System.out.println("未找到scofield的English成绩");
            }

        } catch (Exception e) {
            System.err.println("查询失败: " + e.getMessage());
            throw e;
        }
    }

    /**
     * 根据分数获取等级
     */
    private static String getGrade(int score) {
        if (score >= 90) return "优秀";
        else if (score >= 80) return "良好";
        else if (score >= 70) return "中等";
        else if (score >= 60) return "及格";
        else return "不及格";
    }

    /**
     * 8. 查询特定学生的所有成绩
     */
    public static void queryStudentAllScores(String studentName) throws IOException {
        printSubSeparator("查询" + studentName + "的所有成绩");

        try (Table table = connection.getTable(TableName.valueOf("Student"))) {
            Get get = new Get(Bytes.toBytes(studentName));

            Result result = table.get(get);

            if (result.isEmpty()) {
                System.out.println("学生 " + studentName + " 不存在");
                return;
            }

            System.out.println("学生: " + studentName);

            List<Cell> cells = result.listCells();
            if (cells != null) {
                for (Cell cell : cells) {
                    String family = Bytes.toString(CellUtil.cloneFamily(cell));
                    String qualifier = Bytes.toString(CellUtil.cloneQualifier(cell));
                    String value = Bytes.toString(CellUtil.cloneValue(cell));

                    if (family.equals("score")) {
                        System.out.println("  " + qualifier + ": " + value);
                    }
                }
            }

        } catch (Exception e) {
            System.err.println("查询失败: " + e.getMessage());
            throw e;
        }
    }

    /**
     * 9. 计算平均分(扩展功能)
     */
    public static void calculateAverageScores() throws IOException {
        printSeparator("扩展功能:计算各科平均分");

        try (Table table = connection.getTable(TableName.valueOf("Student"))) {
            Scan scan = new Scan();
            ResultScanner scanner = table.getScanner(scan);

            int englishTotal = 0, mathTotal = 0, computerTotal = 0;
            int englishCount = 0, mathCount = 0, computerCount = 0;
            int studentCount = 0;

            for (Result result : scanner) {
                studentCount++;
                String rowKey = Bytes.toString(result.getRow());

                // 获取各科成绩
                byte[] englishValue = result.getValue(Bytes.toBytes("score"), Bytes.toBytes("English"));
                byte[] mathValue = result.getValue(Bytes.toBytes("score"), Bytes.toBytes("Math"));
                byte[] computerValue = result.getValue(Bytes.toBytes("score"), Bytes.toBytes("Computer"));

                if (englishValue != null) {
                    englishTotal += Integer.parseInt(Bytes.toString(englishValue));
                    englishCount++;
                }

                if (mathValue != null) {
                    mathTotal += Integer.parseInt(Bytes.toString(mathValue));
                    mathCount++;
                }

                if (computerValue != null) {
                    computerTotal += Integer.parseInt(Bytes.toString(computerValue));
                    computerCount++;
                }
            }

            scanner.close();

            System.out.println("学生总数: " + studentCount);
            System.out.println("----------------------------");

            if (englishCount > 0) {
                double englishAvg = (double) englishTotal / englishCount;
                System.out.printf("英语平均分: %.2f (%d人)\n", englishAvg, englishCount);
            }

            if (mathCount > 0) {
                double mathAvg = (double) mathTotal / mathCount;
                System.out.printf("数学平均分: %.2f (%d人)\n", mathAvg, mathCount);
            }

            if (computerCount > 0) {
                double computerAvg = (double) computerTotal / computerCount;
                System.out.printf("计算机平均分: %.2f (%d人)\n", computerAvg, computerCount);
            }

        } catch (Exception e) {
            System.err.println("计算平均分失败: " + e.getMessage());
            throw e;
        }
    }
}

HbaseStudentExperimentDemo:

package com.hadoop.experiment6;
/**
 * 实验4 HBase部分完整演示
 */
public class HBaseStudentExperimentDemo {

    public static void main(String[] args) {
        System.out.println("=== 实验4:NoSQL和关系数据库的操作比较 ===\n");
        System.out.println("=== HBase数据库操作部分 ===\n");

        try {
            // ==================== 演示开始 ====================
            System.out.println(repeatString("★", 60));
            System.out.println("             HBase学生表操作演示");
            System.out.println(repeatString("★", 60));

            // 第一部分:基本操作演示
            System.out.println("\n" + repeatString("=", 60));
            System.out.println("第一部分:基本表操作");
            System.out.println(repeatString("=", 60));

            // 1. 创建表
            System.out.println("\n1. 创建Student表");
            System.out.println(repeatString("-", 40));
            HBaseStudentOperation.createStudentTable();

            // 2. 插入数据
            System.out.println("\n2. 插入初始数据");
            System.out.println(repeatString("-", 40));
            HBaseStudentOperation.insertInitialData();

            // 查看初始数据
            System.out.println("\n3. 查看初始数据");
            System.out.println(repeatString("-", 40));
            HBaseStudentOperation.scanStudentTable();

            // 第二部分:查询和修改操作
            System.out.println("\n" + repeatString("=", 60));
            System.out.println("第二部分:查询和修改操作");
            System.out.println(repeatString("=", 60));

            // 4. 查询zhangsan的Computer成绩
            System.out.println("\n4. 查询zhangsan的Computer成绩");
            System.out.println(repeatString("-", 40));
            HBaseStudentOperation.queryZhangsanComputerScore();

            // 5. 修改lisi的Math成绩
            System.out.println("\n5. 修改lisi的Math成绩");
            System.out.println(repeatString("-", 40));
            HBaseStudentOperation.updateLisiMathScore();

            // 查看修改后的数据
            System.out.println("\n修改后的表数据:");
            HBaseStudentOperation.scanStudentTable();

            // 第三部分:HBase API编程
            System.out.println("\n" + repeatString("=", 60));
            System.out.println("第三部分:HBase API编程");
            System.out.println(repeatString("=", 60));

            // 6. 添加scofield记录
            System.out.println("\n6. 添加scofield记录");
            System.out.println(repeatString("-", 40));
            System.out.println("要添加的数据:");
            System.out.println("  English: 45");
            System.out.println("  Math: 89");
            System.out.println("  Computer: 100");
            HBaseStudentOperation.addScofieldRecord();

            // 7. 获取scofield的English成绩
            System.out.println("\n7. 获取scofield的English成绩");
            System.out.println(repeatString("-", 40));
            HBaseStudentOperation.getScofieldEnglishScore();

            // 查看完整表数据
            System.out.println("\n完整表数据:");
            HBaseStudentOperation.scanStudentTable();

            // 第四部分:扩展功能
            System.out.println("\n" + repeatString("=", 60));
            System.out.println("第四部分:扩展功能演示");
            System.out.println(repeatString("=", 60));

            // 查询各学生成绩
            System.out.println("\n各学生成绩详情:");
            HBaseStudentOperation.queryStudentAllScores("zhangsan");
            HBaseStudentOperation.queryStudentAllScores("lisi");
            HBaseStudentOperation.queryStudentAllScores("scofield");

            // 统计功能
            System.out.println("\n成绩统计:");
            HBaseStudentOperation.calculateAverageScores();

            // ==================== 演示总结 ====================
            System.out.println("\n" + repeatString("★", 60));
            System.out.println("                  实验总结");
            System.out.println(repeatString("★", 60));

            System.out.println("\n✓ 已完成的HBase操作:");
            System.out.println("  1. 表的创建和删除");
            System.out.println("  2. 数据的插入和查询");
            System.out.println("  3. 数据的修改和更新");
            System.out.println("  4. HBase Shell命令对应实现");
            System.out.println("  5. HBase API编程实现");
            System.out.println("  6. 扩展统计功能");

            System.out.println("\n✓ 实验要点:");
            System.out.println("  • HBase表设计:行键+列族+列限定符");
            System.out.println("  • 与MySQL的对比:");
            System.out.println("    - MySQL: 结构化数据,固定schema");
            System.out.println("    - HBase: 半结构化数据,动态schema");
            System.out.println("    - MySQL: 支持复杂查询,事务");
            System.out.println("    - HBase: 高并发读写,海量数据存储");

        } catch (Exception e) {
            System.err.println("演示过程中出现错误: " + e.getMessage());
            e.printStackTrace();
        } finally {
            // 关闭连接
            HBaseStudentOperation.close();
        }
    }

    /**
     * 重复字符串(兼容Java 1.8)
     */
    private static String repeatString(String str, int count) {
        if (count <= 0) {
            return "";
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < count; i++) {
            sb.append(str);
        }
        return sb.toString();
    }
}
posted @ 2025-12-30 22:35  vivi_vimi  阅读(3)  评论(0)    收藏  举报