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

03月 28th, 2008

/**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());
}
}
}
}

标签:, ,

相关日志


This entry was posted on 星期五, 03月 28th, 2008 at 10:37 am and is filed under MYSQL主机. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply