zoukankan      html  css  js  c++  java
  • 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)+"	");
            }
            System.out.print("
    ");
            //打印ResultSet里的全部数据
            while(rs.next())
            {
                for(var i=0;i<rsmd.getColumnCount();i++)
                {
                    System.out.print(rs.getString(i+1)+"	");
                }
                System.out.print("
    ");
            }
        }
    
        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来分析数据库信息,则具有很好的跨数据库特性,应用程序可以做到数据库无关;但无法准确获得数据库的更多细节。
    使用数据库系统表来分析数据库信息会更加准确,但使用系统表有一个细节——这种方式与底层数据库耦合严重,采用这种方式将会导致程序只能运行于特定的数据库之上。

  • 相关阅读:
    “Swift Language Version” (SWIFT_VERSION) build setting must be set to a supported value for targets which use Swift
    webSocket通讯
    动画效果
    史上最简单MySQL教程详解(进阶篇)之视图
    “野生”程序猿写博客一年的感悟
    成都“小甜甜”:她给了男人希望,男人却被嘲笑X丝
    史上最简单MySQL教程详解(进阶篇)之索引及失效场合总结
    SpringBoot简明教程之快速创建第一个SpringBoot应用
    史上最简单MySQL教程详解(进阶篇)之深入理解事务处理内部的动作
    史上最简单MySQL教程详解(进阶篇)之锁与事务处理分离水平(二)
  • 原文地址:https://www.cnblogs.com/weststar/p/12711826.html
Copyright © 2011-2022 走看看