使用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());
   }
  }
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值