原来jdbc也可以实现一个简单的sql客户端

之前一直想做这样一个功能,传过来一个sql,无论是增删改还是查询,又或者是DDL,可以像数据库客户端一样来显示出结果,之前一直纠结的是结果这个表格怎么显示,因为你是增删改或者DDL很明显应该返回一个受影响的数,而查询的结果是一个二维表格,甚至是一个行和列都不确定的表格。

今天利用了resultMetaData这个类实现了这个功能。

贴上代码,讲解一下:

显示主函数:

public static void main(String [] args) {
        String url = "jdbc:mysql://127.0.0.1:3306/test";
        String user = "*****";
        String password = "*****";
        String sqls="insert into test(name) VALUES ('name6');insert into test(name) VALUES ('name7');insert into test(name) select name from test";
        //String sqls="select * from test";
        getSqlsResult(url, user, password, sqls);
    }

接下来功能函数:

/**
     * 执行sql返回结果
     * @param url
     * @param user
     * @param password
     * @param sqls
     */
    private static void getSqlsResult(String url, String user, String password, String sqls) {
        Connection conn = getConnect(url,user,password);
        //select 语句
        if (sqls.trim().toLowerCase().startsWith("select")) {
            Statement statement=null;
            try {
                statement=conn.createStatement();
                ResultSet resultSet=statement.executeQuery(sqls);
                ResultSetMetaData resultSetMetaData=resultSet.getMetaData();
                for(int i=1;i<resultSetMetaData.getColumnCount()+1;i++){
                    System.out.print(resultSetMetaData.getColumnName(i)+resultSetMetaData.getColumnTypeName(i)+"\t");
                }
                System.out.println();
                while (resultSet.next()){
                    for(int j=1;j<resultSetMetaData.getColumnCount()+1;j++){
                        System.out.print(resultSet.getObject(j).toString()+"\t");
                    }
                    System.out.println();
                }
            } catch (SQLException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }

            //批量处理语句
        } else {
            if (supportBatch(conn)) {
                try {
                    conn.setAutoCommit(false);
                } catch (SQLException e) {
                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
                Statement statement = null;
                try {
                    String[] commands = sqls.split(";");
                    statement = conn.createStatement();
                    for (int i = 0; i < commands.length; i++) {
                        statement.addBatch(commands[i]);
                    }
                    int[] result = statement.executeBatch();
                    for (int i = 0; i < result.length; i++) {
                        System.out.println(commands[i] + "result:" + result[i]);
                    }
                    conn.commit();
                } catch (SQLException e) {
                    try {
                        conn.rollback();
                    } catch (SQLException e1) {
                        e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                    }
                    e.printStackTrace();
                }
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            } else {
                System.err.print("unsport batch!!!");
            }
        }

        closeConn(conn);
    }

    /**
     *  获取连接
     * @param url
     * @param user
     * @param password
     * @return 
     */
    private static Connection  getConnect(String url,String user,String password) {
        String driver = "com.mysql.jdbc.Driver";
        Connection conn = null;
        try {
            Class.forName(driver);
            conn = DriverManager.getConnection(url, user, password);

        } catch (ClassNotFoundException e) {
            System.out.println("can not find driver");
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 关闭连接
     * @param conn
     */
    private static void closeConn(Connection conn){
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
    }

    /**
     * 是否支持批处理
     * @param con
     * @return 
     */
    public static boolean supportBatch(Connection con) {
        try {
            DatabaseMetaData md = con.getMetaData();
            return md.supportsBatchUpdates();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }

主函数需要执行3条insert语句。我们看一下返回结果:

insert into test(name) VALUES ('name6')result:1
insert into test(name) VALUES ('name7')result:1
insert into test(name) select name from testresult:22

Process finished with exit code 0

执行结果是正确的。

接下来主函数传入查询的语句:

public static void main(String [] args) {
        String url = "jdbc:mysql://127.0.0.1:3306/test";
        String user = "*****";
        String password = "******";
        //String sqls="insert into test(name) VALUES ('name6');insert into test(name) VALUES ('name7');insert into test(name) select name from test";
        String sqls="select * from test";
        getSqlsResult(url, user, password, sqls);
    }

结果如下也没有什么问题

idINT	nameVARCHAR	
24	name6	
25	name7	
30	name6	
31	name7	
32	name6	
33	name7	
34	name6	
35	name7	
39	name6	
40	name7	
41	name6	
42	name7	
43	name6	
44	name7	
45	name6	
46	name7	
47	name6	
48	name7	
49	name6	
50	name7	
56	name6	
57	name7	
58	name6	
59	name7	
60	name6	
61	name7	
62	name6	
63	name7	
64	name6	
65	name7	
66	name6	
67	name7	
68	name6	
69	name7	
70	name6	
71	name7	
72	name6	
73	name7	
74	name6	
75	name7	
76	name6	
77	name7	
78	name6	
79	name7

看来大体思路是对的,接下来做一个界面就可以实现简单的数据库客户端了。

现在的问题是目前测试的是数值和字符串类型的字段,没有考虑其他特殊的字段,不过没有关系,resultsetmetadata可以取到元数据的类型的,包括数据库中的类型和java中的类型,只要到时候通过反射转一下就行。

接下来去做界面吧....

 上界面了

 

转载于:https://my.oschina.net/zimingforever/blog/66481

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值