JDBC适用任意表的数据库查询以及结果美化输出

Java JDBC通用数据库表查询&查询结果美化输出

当你使用cmd查询数据库时结果是这样的 ↓

cmd查询数据库结果

而你自己用JDBC写java程序输出结果是这样的 ↓
你自己的程序输出结果
除了第一列其他参差不齐2333,那么我们该如何输出像cmd那样华丽整齐高端大气的样子呢,针对这个问题我在网上搜了好久,结果找到的都是教你怎么把结果打包为list的教程,真是脑壳疼,那么只好自己来写了。

解决方法构思

我们这次要完成的是一个适用于任意表的查询方法,也就是说查询之前我们并不知道表里有多少列以及每一列的数值类型。

首先在这里再啰嗦一遍JDBC的使用:

Class.forName("com.mysql.jdbc.Driver");
//这里我的编辑器会给一个小提示,说上面这个可以改成新的com.mysql.cj.jdbc.Driver
//因为我用的是新版的jdbc,这里为了兼容性依旧使用旧版,不影响使用
static String url = "jdbc:mysql://localhost:3306/text";//text是我的数据库名,这里改成你自己的数据库名
private String username = "????";你的数据库用户名
private String password = "****";你的数据库密码
static Connection conn = DriverManager.getConnection(url, username, password);//建立数据库连接
static Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
//这里加上ResultSet.TYPE_SCROLL_INSENSITIVE和ResultSet.CONCUR_UPDATABLE是为了让查询结果集rs的光标可以任意移动
//如果不加的话执行完rs.next()光标后移之后就无法返回,这样做的目的后面会说
static ResultSet rs =null;//查询结果集
String s = "???";//你要查询的表名
String com = "SELECT * FROM " + s + ";";
rs = st.executeQuery(com);//执行查询命令得到结果集rs

到这里为止是得到数据库查询结果集rs的过程,其实这些都大同小异,真正的区别之处在于对结果集rs的处理以及输出,我们接着往下看。

这里可以先想一想,我们想要得到cmd那样的整齐输出需要什么?首先是知道每一列查询结果的长度,就是字面意思的显示长度,因为导致输出结果对不齐的根本原因就是每行查询结果的长度不一致,知道了长度之后就可以通过程序自动加空格补齐,使每一列中每行元素长度相等。第二,得知了输出结果长度这一关键信息就可以加上+ -------- + ---------------- + 这样的分隔线。第三,想要结果整齐还需要一个字符等宽字体,你可以观察一下你的编辑器的集成控制台和你电脑的命令行,它们显示的每一个字符都是等宽的,中文汉字宽度正好是英文字母的两倍,电脑上的带的黑体Consolas字体都是字符等宽字体,当然你也可以自己下载。我最近写Java GUI程序用到JTextArea发现自己下载的字体设置font后使用不了,只能用系统带的等宽字体,有大神有解决方法麻烦告诉我一声。

解决方法实现

我们先来写一个可以得到字符串长度的方法

public static int getLength(String s){
    
    
    int length=0;//保存字符串长度
    String chinese="[\u0391-\uFFE5]";//用来判断字符是否为中文字符
    for (int i = 0; i < s.length(); i++){
    
    
        String temp = s.substring(i, i + 1);//拆分字符串得到第i个字符
        if (temp.matches(chinese)){
    
    
            length=length+2;//判断为中文字符,记录字符串总长度加二
        }else{
    
    
            length=length+1;//判断非中文字符,记录字符串总长度加一
        }
    }
    return length;//返回字符串长度
}

在其他地方调用此方法来获得字符串长度

接下来就是对rs结果集的处理了,这个方法有那么一丢丢复杂,但是为了得到整齐的输出结果也是值得的,我会在代码中加入详细的注释。

public static void printResults(ResultSet rs) {
    
    
        try {
    
    
            ResultSetMetaData md = rs.getMetaData();
            //为了使该方法适用于任意表,所以需要程序自己读取列信息,ResultSetMetaData 正是服务于此
            int columnCount = md.getColumnCount(); // 获取查询结果集的列数
            int maxlength[] = new int[100];// 保存每一列的最大长度,一般情况下不会有超过100列的表吧。。。

            while (rs.next()) {
    
    //遍历查询结果,获取每一列字符串长度的最大值,保存在数组中
                for (int i = 0; i < columnCount; i++) {
    
    
                    int n = getLength(String.valueOf(rs.getObject(i + 1)));//getLenght为自定义方法
                    if (n > maxlength[i]) {
    
    
                        maxlength[i] = n;
                    }
                }
            }
            rs.first();//遍历一遍得到每一列的最大长度之后将光标移至起始位置,接下来输出还要遍历一遍
            
            String colname = "";// 保存每一列的列名
            String line="";//用于构造分隔线
            for (int i = 0; i < columnCount; i++) {
    
    
                String name = md.getColumnName(i + 1);//获取列名
                int n1 = getLength(name);//获取列名的长度,与该列最大长度对比
                if (n1 > maxlength[i]) {
    
    
                    maxlength[i] = n1;//如果列名长度比该列最大长度还大,则该列最大长度设为列名长度
                }
                int n2 = maxlength[i] - getLength(name) + 3;//最大长度减去列名长度加3作为补充空格的数量
                for (int k = 1; k <= n2; k++) {
    
    //循环来补充空格
                    name = name + " ";
                }
                int n3=maxlength[i]+3;//分隔线补充减号的数量
                String subline="";
                for(int k=1;k<=n3;k++){
    
    
                    subline = subline + "-";
                }
                colname = colname + "| " + name;//每行的每个元素之间用竖线分隔
                line=line+"+-"+subline;//分隔线在与竖线对齐处添加“+”
            }
            
            System.out.println("\nReturn Massage :");//输出内容提示
            System.out.println(line+"+");//输出第一行分隔线
            System.out.println(colname+"|");//输出列名
            System.out.println(line+"+");//输出第二行分隔线
            
            while (true) {
    
    //遍历输出所有元素,每次循环读取一整行
                String out = "";//用于构造每行的输出内容
                String row = null;//用于在循环中临时保存新得到的内容
                for (int i = 0; i < columnCount; i++) {
    
    //每次循环读取该行下一列的元素
                    row = String.valueOf(rs.getObject(i + 1));//获取内容并转为字符串
                    int n = maxlength[i] - getLength(row) + 3;//添加空格的数量
                    for (int k = 1; k <= n; k++) {
    
    //循环添加空格
                        row = row + " ";
                    }
                    out = out + "| " + row;//构造该行输出内容
                }
                System.out.println(out+"|");//输出该行所有内容
                if(!rs.next())break;//当读取完所有行之后结束循环
                //注:此处的rs.next()不能放到 while 的括号里,因为上面rs.first()光标移动到首位
                //如果 while 执行一次括号里的条件,光标会变到第二行,第一行会被忽略
            }
            System.out.println(line+"+");//输出最后的分隔线
        } catch (Exception e) {
    
    
            //添加你对错误消息的处理,我这里省略了
        }
    }

到此为止,查询结果集的美化输出也完成了,我们来跑一下程序看看效果
在这里插入图片描述

扫描二维码关注公众号,回复: 14822883 查看本文章

完美还原cmd命令行的输出效果,瞬间变得整齐了有木有,这样的输出看着才舒坦。那么本次分享也该到此为止了,有帮助的小伙伴记得点个赞,谢谢!

猜你喜欢

转载自blog.csdn.net/NEKOic/article/details/117447836