原來jdbc也能夠實現一個簡單的sql客戶端

以前一直想作這樣一個功能,傳過來一個sql,不管是增刪改仍是查詢,又或者是DDL,能夠像數據庫客戶端同樣來顯示出結果,以前一直糾結的是結果這個表格怎麼顯示,由於你是增刪改或者DDL很明顯應該返回一個受影響的數,而查詢的結果是一個二維表格,甚至是一個行和列都不肯定的表格。java

今天利用了resultMetaData這個類實現了這個功能。mysql

貼上代碼,講解一下:sql

顯示主函數:shell

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中的類型,只要到時候經過反射轉一下就行。函數

接下來去作界面吧....測試

 上界面了url

 

相關文章
相關標籤/搜索