10.9 分析数据库信息

一、使用DatabaseMetaData分析数据库信息

JDBC提供了DatabaseMetaData来封装数据库连接对应数据库的信息,通过Connection提供的getMetaData()方法可以获取数据库对应的DatabaseMetaData对象。
DatabaseMetaData接口通常由驱动程序供应商提供实现,其目的是让用户了解底层数据库的相关信息。使用该接口的目的是发现如何处理底层数据库,所以必须利用该接口来找出底层数据库的功能,例如,调用supportCorrelatedSubqueries()方法查看是否可以使用关联子查询,或者调用supportsBatchUpdates()方法查看是否可以使用批量更新。
许多DatabaseMetaData方法一ResultSet对象的形式返回查询信息,然后使用ResultSet的常规方法(如getString(),getInt())即可从这些ResultSet对象中获取数据。如果查询信息不可用,将返回一个空的ResultSet对象。
DatabaseMetaData的很多方法都需要传入一个xxxPatttern模式字符串,这里的xxxPattern不是正则表达式,而是SQL语句的模式字符串,即用(%)代表任意多个字符,(_)代表一个字符。在通常情况下,如果把该模式字符串的字符串的参数值设置为null,即表示该参数不作为过滤条件。
下面程序通过DatabaseMetaData分析了当前Connection连接对应数据库的一些基本信息,包括当前数据库有多个数据表,存储过程,student_table表的数据列、主键、外键等信息。

package section8;

import java.io.FileInputStream;
import java.sql.*;
import java.util.Properties;

public class DatabaseMetaDataTest
{
    private static String driver;
    private static String url;
    private static String user;
    private static String pass;

    public void initParam(String fileName)
            throws Exception
    {
        //使用Properties类来加载属性
        Properties props=new Properties();
        props.load(new FileInputStream(fileName));
        driver=props.getProperty("driver");
        url=props.getProperty("url");
        user=props.getProperty("user");
        pass=props.getProperty("pass");
    }
    public void info()
        throws Exception
    {
        //加载驱动
        Class.forName(driver);
        try(
                //获取数据库连接
                Connection conn= DriverManager.getConnection(url,user,pass);
                )
        {
            //获取DatabaseMetaData对象
            DatabaseMetaData dbmd=conn.getMetaData();
            //获取MySQL支持的所有表类型
            ResultSet rs=dbmd.getTableTypes();
            System.out.println("--MySQL支持的表类型信息--");
            printResultSet(rs);
            //获取当前数据库的全部数据表
            rs=dbmd.getTables("select_test",null,"%",new String[]{"TABLE"});
            System.out.println("--当前数据库的数据表信息--");
            printResultSet(rs);
            //获取student_table表的主键
            rs=dbmd.getPrimaryKeys("select_test",null,"student_table");
            System.out.println("--student_table表的主键信息--");
            printResultSet(rs);
            //获取当前数据库的全部存储过程
            rs=dbmd.getProcedures("select_test",null,"%");
            System.out.println("--当前数据库的全部存储过程信息--");
            printResultSet(rs);
            //获取student_table和teacher_table表之间的外键约束
            rs=dbmd.getCrossReference("select_test",null,"teacher_table",null,null,"student_table");
            System.out.println("--student_table和teacher_table表之间的外键约束--");
            printResultSet(rs);
            //获取student_table表的全部数据列
            rs=dbmd.getColumns("select_test",null,"student_table","%");
            System.out.println("--student_table表的全部数据列--");
            printResultSet(rs);
        }
    }

    private void printResultSet(ResultSet rs)
            throws Exception
    {
        ResultSetMetaData rsmd=rs.getMetaData();
        //打印ResultSet的所有列标题
        for(var i=0;i<rsmd.getColumnCount();i++)
        {
            System.out.print(rsmd.getColumnName(i+1)+"\t");
        }
        System.out.print("\n");
        //打印ResultSet里的全部数据
        while(rs.next())
        {
            for(var i=0;i<rsmd.getColumnCount();i++)
            {
                System.out.print(rs.getString(i+1)+"\t");
            }
            System.out.print("\n");
        }
    }

    public static void main(String[] args)
        throws Exception
    {
        var dt=new DatabaseMetaDataTest();
        dt.initParam("src\\mysql.ini");
        dt.info();;
    }
}

二、使用系统表分析数据库信息

除了可以使用DatabaseMetaData来分析底层数据库信息之外,如果已经确定了应用程序所用的数据库系统,则可以通过数据库的系统表来分析数据库信息。系统表又称为数据字典,数据字典的数据通常由数据库系统复杂维护,用户通常只能查询数据字典,而不能修改数据字典的内容。
注意:对于MySQL与SQL Server这样的数据库,它们还提供一个系统数据库来存储这些系统表。系统表相当于视图,用户只能查看系统表的数据,不能直接修改系统表中的数据。
MySQL数据库使用information_schema数据库来保存系统表,在该数据库里包含大量系统表,常用系统表的简单介绍:
(1)tables:存放数据库里所有数据表的信息。
(2)schemata:存放数据库里所有数据库(与MySQL的Schema对应)的信息。

(3)views:存放数据库里所有视图信息。
(4)columns:存放数据库里所有列信息。

(5)routines:存放数据库里所有存储过程和函数信息。
(6)triggers:存放数据库里所有触发器的信息。
(7)key_column_usage:存放数据库里所有具有约束的键信息。
(8)table_constraints:存放数据库里全部约束的表信息。
(9)statistics:存放数据库里全部索引的信息。

三、选择合适的分析方式

通常而言,如果使用DatabaseMetaData来分析数据库信息,则具有很好的跨数据库特性,应用程序可以做到数据库无关;但无法准确获得数据库的更多细节。
使用数据库系统表来分析数据库信息会更加准确,但使用系统表有一个细节——这种方式与底层数据库耦合严重,采用这种方式将会导致程序只能运行于特定的数据库之上。

posted @ 2020-04-16 21:27  小新和风间  阅读(206)  评论(0编辑  收藏  举报