使用DatabaseMetaData和ResultSetMetaData查看数据库信息

/**DatabaseMetaData接口查看数据库的整体综合信息,它位于java.sql包中,
* 由数据库驱动程序供应商提供,里面定义了很多关于此数据库的信息,例如版
* 本号、此JDBC驱动程序的名称等等。ResultSetMetaData可用于获取关于
* ResultSet 对象中列的类型和属性信息的对象,也位于java.sql包中。下面
* 这个程序的主要功能是查看所有数据库、进入指定的数据库查看所有表、查看表
* 的详细信息、以及使用select、update、insert、delete操作数据表信息等。
* 因为效果图太多,这里我就不截图了,有兴趣的朋友可以在自己机上试试看。
* 下面是实现的代码:
*/

/**
* 静态导入System包,因为在下面用System.out.println()
* 比较多,有此import语句就可以省略前面的System了。这是
* jdk1.5的新语法,有兴趣的朋友可以看看java核心技术的第
* 七版,所有的新语法都有介绍。
*/
import static java.lang.System.*;

/** 导入下面要用到的所有类 */
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Scanner;

public class Client {
/**
* 定义几个全局变量
*/
private Connection con = null;

private PreparedStatement pstmt = null;

private ResultSet rs = null;

private ResultSetMetaData rsmd = null;

private String url = "";

/**
* 首先使用static块加载mysql的驱动,static块里面的代码在 Client类一加载就执行,且只执行一次
*/
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

/**
* useMysql方法,功能是使用use命令进入参数指定的数据库
*
* @param dbName
* 数据库名
* @return void
*/
public void useMysql(String dbName) {
url = "jdbc:mysql://localhost:3306/" + dbName;
try {
con = DriverManager.getConnection(url, "usename", "password");
out.println("数据库已改变!");
} catch (Exception e) {
out.println("Exception:" + e.getMessage());
}
}

/**
* execute 方法根据参数判断执行指定的命令
*
* @param prefix
* 命令的第一个单词
* @param sql
* 要执行sql语句sql语句
*/
public void execute(String prefix, String sql) {
if (prefix.equals("use")) {
useMysql(sql);
} else if (prefix.equals("show")) {
show(sql);
} else if (prefix.equals("desc")) {
desc(sql);
} else if (prefix.equals("select")) {
select(prefix + " " + sql);
} else if (prefix.equals("update") || prefix.equals("insert")
|| prefix.equals("delete")) {
update(prefix + " " + sql);
} else {
out.println("错误的命令!");
}
}

/**
* update方法 用于执行update、insert、delete命令
*
* @param sql
* 要执行sql语句
*/
private void update(String sql) {
if (con == null) {
out.println("请先使用use命令!");
} else {
try {
pstmt = con.prepareStatement(sql);
// 如果影响行数不为则说明sql语句执行成功
if (pstmt.executeUpdate(sql) != 0) {
out.println("执行成功!");
}
} catch (Exception e) {
out.println(e.getMessage());
}
}
}

/**
* select 方法,用于执行select语句。此方法写了大量的格式化语
* 句。也使用到了jdk1.5的新语法。那就是System.out.printf()方法。
* 使用方法和C语言差不多。
* @param sql
* 要执行sql语句
*/
private void select(String sql) {
if (con == null) {
out.println("请先使用use命令!");
} else {
try {
pstmt = con.prepareStatement(sql);
rs = pstmt.executeQuery();
rsmd = rs.getMetaData();

int j = 15 * rsmd.getColumnCount() + rsmd.getColumnCount() - 1;

out.print("+");
for (int i = 0; i < j; i++)
out.print("-");
out.print("+\n");

for (int i = 1; i <= rsmd.getColumnCount(); i++) {
out.printf("|%-15s", rsmd.getColumnName(i));
}
out.print("|\n+");

for (int i = 0; i < j; i++)
out.print("-");
out.print("+\n");

// 表中数据的信息
while (rs.next()) {
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
out.printf("|%-15s", rs.getObject(i).toString());
}
out.println("|");
}
out.print("+");

for (int i = 0; i < j; i++)
out.print("-");
out.print("+\n");
} catch (Exception e) {
out.println(e.getMessage());
}
}
}

/**
* desc方法,用于查看指定表的具体信息,类似于mysql命令的desc语句的功能
*
* @param table
* 指定的表名
*/
private void desc(String table) {
if (con == null) {
out.println("请先使用use命令!");
} else {
try {
pstmt = con.prepareStatement("select * from " + table);
rs = pstmt.executeQuery();
rsmd = rs.getMetaData();

out.print("+");
for (int i = 0; i < 68; i++)
out.print("-");
out.print("+\n");

out.printf("|%-25s|%-15s|%-10s|%-15s|\n", "Field", "Type",
"Null", "Extra");
out.print("+");

for (int i = 0; i < 68; i++)
out.print("-");
out.print("+\n");

// 表的详细信息
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
out.printf("|%-25s", rsmd.getColumnName(i));
out.printf("|%-15s", rsmd.getColumnTypeName(i) + "("
+ rsmd.getColumnDisplaySize(i) + ")");
out.printf("|%-10s", ((rsmd.isNullable(i) == 1) ? "YES"
: "NO"));
out.printf("|%-15s|\n",
rsmd.isAutoIncrement(i) ? "auto_increment" : "");
}
out.print("+");

for (int i = 0; i < 68; i++)
out.print("-");
out.print("+\n");

} catch (Exception e) {
out.println(e.getMessage());
}
}
}

/**
* show 方法,根据用户输入的信息判断是show tables 还是show databases 再进行处理
*
* @param obj
* 要查看的对象
*/
private void show(String obj) {
if (obj.equals("tables")) {
if (con == null) {
out.println("请先使用use命令!");
} else {
try {
DatabaseMetaData dsmd = con.getMetaData();
rs = dsmd.getTables(null, null, null, null);

out.print("+");
for (int i = 0; i < 78; i++)
out.print("-");
out.print("+\n");

out.printf("|%-27s|%-12s|%-12s|%-12s|", "表名称", "表类别",
"表类型", "表模式");
out.println();
out.print("+");

for (int i = 0; i < 78; i++)
out.print("-");
out.print("+");
out.println();

while (rs.next()) {
out.printf("|%-30s|%-15s|%-15s|%-15s|", rs
.getString("TABLE_NAME"), rs
.getString("TABLE_CAT"), rs
.getString("TABLE_TYPE"), rs
.getString("TABLE_SCHEM"));
out.println();
}

out.print("+");
for (int i = 0; i < 78; i++)
out.print("-");
out.print("+");
out.println();
} catch (Exception e) {
out.println(e.getMessage());
}
}
} else if (obj.equals("databases")) {
try {
con = DriverManager.getConnection("jdbc:mysql:///", "usename",
"password");
DatabaseMetaData dsmd = con.getMetaData();
rs = dsmd.getCatalogs();

out.print("+");
for (int i = 0; i < 30; i++)
out.print("-");
out.print("+");

out.println();
out.printf("|%-30s|\n", "DATABASE");

out.print("+");
for (int i = 0; i < 30; i++)
out.print("-");
out.print("+");

out.println();
while (rs.next()) {
out.printf("|%-30s|\n", rs.getString(1));
}

out.print("+");
for (int i = 0; i < 30; i++)
out.print("-");
out.print("+");
out.println();
} catch (Exception e) {
out.println(e.getMessage());
}
} else {
out.println("错误的命令!");
}
}

public static void main(String[] args) {
/**
* Scanner也是jdk1.5新加进来的一个类,在java.util
* 包中,具体用法可以查看jdk1.5的API,这里是从键盘获
* 得一个输入流,比用BufferedReader简单的多了。
*/
Scanner scanner = new Scanner(System.in);
Client client = new Client();
out.println("查看所有数据库使用show databases命令");
out.println("进入数据库使用use命令(use databaseName)");
out.println("查看数据库表信息使用show tables命令");
out.println("显示表信息使用desc命令(desc tableName)");
out.println("执行sql命令使用select,update,delete");
out.println("退出请使用 quit ");
String command = "";
while (true) {
try {
out.print("mysql> ");
command = scanner.nextLine();
//判断输入的命令是否为quit或者QUIT,是则跳出循环,退出程序
if (command.trim().equals("quit")
|| command.trim().equals("QUIT")) {
break;
}
//使用正则表达式去掉输入字符串的前后空格后再把中间所有超过一
//个空格的地方转换为一个空格
command = command.trim().replaceAll(" +", " ");
//经过上面处理后取到命令的第一个关键字
String prefix = command.substring(0, command.indexOf(" "));
String sql = command.substring(command.indexOf(" ") + 1);
client.execute(prefix, sql);
} catch (Exception e) {
out.println(e.getMessage());
}
}
}
}

你可能感兴趣的:(sql,mysql,jdbc,正则表达式,J#)