之前一直想做这样一个功能,传过来一个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中的类型,只要到时候通过反射转一下就行。
接下来去做界面吧....
上界面了