数据库元数据获取工具

 

1.  简介

源码地址:https://github.com/wukenaihe/db-metahtml

邮箱:541931314@qq.comjava

有任何bug能够直接发送邮件告知承诺会立刻进行修改,若是须要添加功能或者改进也但愿告知,会及时进行改进。但愿可以点赞(\(^o^)/~)git

 

数据库的元数据库获取到如今为止并无太好用的开源框架,最有名气的多是schemacrawler。不过这个软件实在是太大太大了,不只包括元数据的获取,还包括表、列等信息的显示。同时它的性能存在巨大弊端,基本上oracle数据库他就不太能用,会把oracle里面的许多临时表、垃圾表等都一古脑儿拉出来,很是可怕。它的接口相对比较简单,getDatabase只有这么一个获取方法,若是你要获取一张表,你也得用这个方法。github

若是,不用开源框架,你能够选择用jdbc标准DatabaseMeta接口。使用不方便,须要处理大量的SQLException同时,他也不能获取触发器、存储过程、函数等定义内容。sql

若是,直接从数据库里面获取数据库元数据,至关复杂。数据库

1.1. 设计目标

  • l  简单,易用
  • l  易用扩展
  • l  线程安全
  • l  高性能

简单,易用:数据库之间的元数据相差很是大,且均不遵照SQL标准。因此,咱们把元数据进行了抽象。根据SQL标准及经常使用内容,组成了一个类树。安全

易扩展:容许添加别的数据库实现方式,容许方便的重写现有方法。数据结构

高性能:轻量,能获取小部分的元数据。oracle

2.  例子

https://github.com/wukenaihe/db-meta-example框架

Maven

<repositories>

      <repository>

         <id>clojars</id>

         <name>Clojars repository</name>

         <url>https://clojars.org/repo</url>

      </repository>

</repositories>

<dependencies>
        <dependency>
            <groupId>org.clojars.xumh</groupId>
            <artifactId>db-meta</artifactId>
            <version>0.0.1-Release</version>
        </dependency>
<dependencies>

在中国颇有可能下载不下来,能够用开源中国上面的maven。不过去缺乏依赖logback,须要本身添加下。

<dependency>
  <groupId>com.cgs.dbMeta</groupId>
  <artifactId>db-meta</artifactId>
  <version>0.0.1-Release</version>
</dependency>

<dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-classic</artifactId>
   <version>1.0.9</version>
</dependency>

 

http://maven.oschina.net/index.html#nexus-search;quick~db-meta

如何使用maven,你们能够参照:http://maven.oschina.net/help.html

public static void main(String[] args) {

      MysqlDataSource datasource = new MysqlDataSource();

      datasource.setServerName("localhost");

      datasource.setPort(3306);

      datasource.setDatabaseName("dctest");

      datasource.setUser("root");

      datasource.setPassword("123456");  

      MetaLoader metaLoader=new MetaLoaderImpl(datasource);

      Set<String> tableNames=metaLoader.getTableNames();

      System.out.print("数据库中拥有表:");

      System.out.println(tableNames);
     
      Table table=metaLoader.getTable("des");

      PrintUtils.printTable(table);

       Map<String, Procedure> procedures=metaLoader.getProcedures();

//    System.out.println(procedures);

    }

3.  程序结构

3.1. 元数据结构

 

  • Database:数据库,拥有多个Schema
  • Schema:数据集,这个数据库与SQL中的数据集略微不一样(Oracle:schema,mySql:catalog,SqlServer:catalog.schema)。这是由于,不一样数据库对schema的解释不一样形成的。
  • Table:拥有列、主键、外键、约束、触发器、索引和权限。
  • Column:名称、注释、是否为null、类型(java.sql.Types)、类型(数据库类型名称)、精度、小数位数、默认值。
  • 主键:主键名,列名(按照定义的顺序)
  • 外键:外键引用关系、外键删除规则、外键更新规则
  • 索引:名称、惟一性、索引类型(JDBC定义)、页数、定义和列名
  • 约束:名称、约束类型、约束定义(如”D1 Is not null”)
  • 触发器:名称、所属表、定义
  • 权限:授予者、被授予者、权限、是否有授予权限
  • 存储过程:名称、定义(大量信息被压缩在定义中)
  • 函数:名称、定义(大量信息被压缩在定义中)

3.2. API

经过等级来进行控制,这样可以避免读取没必要要的信息而影响性能。

 

标准

驱动信息(JDBC

Yes  Yes  Yes 

数据库信息

 Yes Yes   Yes

 Yes Yes  Yes 

主键

 Yes  Yes Yes 

约束

 No

Yes  Yes 

视图(视为表)

  No

  No

Yes 

索引

  No

 Yes Yes 

外键

  No

Yes  Yes 

权限

  No

  No

 Yes

触发器

  No

  No

Yes 

 Yse   Yes
Yes 

 

MetaLoader接口

方法

说明

Set<String> getTableNames()

获取表名(当前Schema)

Table getTable(String tableName)

获取表(标准级别)

Table getTable(String tableName,SchemaInfoLevel schemaLevel)

如上

Table getTable(String tableName,SchemaInfo schemaInfo)

获取指定Schema下的,特定表

Set<SchemaInfo> getSchemaInfos()

获取数据下的Schema信息

Schema getSchema()

获取当前schema

Schema getSchema(SchemaInfo schemaInfo)

获取指定的schema元数据

Set<String> getProcedureNames()

获取当前schema存储过程名称

Procedure getProcedure(String procedureName)

获取存储过程

Map<String,Procedure> getProcedures()

获取当前schema存储过程集合

Set<String> getTriggerNames()

获取当前schema触发器名称

Trigger getTrigger(String triggerName)

获取指定的触发器

Map<String, Trigger> getTriggers()

获取当前schema触发器集合

Set<String> getFunctionNames()

获取当前函数名称

Function getFunction(String name)

获取指定的函数

Map<String, Function> getFunctions()

获取当前schema函数集合

Database getDatabase()

获取数据库元数据(标准)

Database getDatabase(SchemaInfoLevel level)

获取指定级别的数据库元数据

 

4.  设计过程

不一样的数据库,获取元数据的方式必然不一样,从这一点来看,咱们须要一个策略模式。策略模式也方便进行扩展。

数据库决定以后,实际上也已经决定会使用哪一个具体实现。因此,在程序中实现方式的创建将交由一个工程,根据数据库类型自动创建。

咱们的数据库要求是线程安全的,因此要求不具备状态,每个方法都具备获取链接、关闭链接等步骤,因此咱们在这里使用了一个模板模式。MetaLoader的方法仍是比较复杂的。因此,咱们抽象除了一个MetaCrawler接口,进行细化,MetaLoader的方法实现能够经过MetaCrawler的组合实现。

部分实现,咱们使用的是DatabaseMeta,任何数据库都是同样的。可是部分信息如触发器、存储过程、函数等信息,DatabaseMeta是获取不到的,又要分开实现。因此,毫无疑问,咱们这里也使用了模板模式。

 

JDBC的异常为SQLException异常,抛出的异常都必须接住,会让代码结构很是混乱。同时,在close的方法抛出的异常,一般交给开发人员是没法进行任何处理的。因此,咱们选择catch这类没法处理的异常,而后进行日志输出。

4.1. 线程安全

public Procedure getProcedure(String procedureName) {

      Connection con = JDBCUtils.getConnection(dataSource);

      MetaCrawler metaCrawler=null;

      Procedure p;

      try{

         metaCrawler=factory.newInstance(con);

         p=metaCrawler.getProcedure(procedureName);

         return p;

      }catch(DataAccessException e){

         logger.debug(e.getMessage(),e);

         throw new DatabaseMetaGetMetaException("Get tables error!", e);

      }finally{

         JDBCUtils.closeConnection(con);

      }

}

 

在方法的开始位置会获取一个链接,而后经过工厂建立一个实例。在方法的末尾关闭链接。整个过程都是无状态的,因此是线程安全的。

相关文章
相关标签/搜索