源码地址:https://github.com/wukenaihe/db-metahtml
邮箱:541931314@qq.comjava
有任何bug能够直接发送邮件告知承诺会立刻进行修改,若是须要添加功能或者改进也但愿告知,会及时进行改进。但愿可以点赞(\(^o^)/~)git
数据库的元数据库获取到如今为止并无太好用的开源框架,最有名气的多是schemacrawler。不过这个软件实在是太大太大了,不只包括元数据的获取,还包括表、列等信息的显示。同时它的性能存在巨大弊端,基本上oracle数据库他就不太能用,会把oracle里面的许多临时表、垃圾表等都一古脑儿拉出来,很是可怕。它的接口相对比较简单,getDatabase只有这么一个获取方法,若是你要获取一张表,你也得用这个方法。github
若是,不用开源框架,你能够选择用jdbc标准DatabaseMeta接口。使用不方便,须要处理大量的SQLException同时,他也不能获取触发器、存储过程、函数等定义内容。sql
若是,直接从数据库里面获取数据库元数据,至关复杂。数据库
简单,易用:数据库之间的元数据相差很是大,且均不遵照SQL标准。因此,咱们把元数据进行了抽象。根据SQL标准及经常使用内容,组成了一个类树。安全
易扩展:容许添加别的数据库实现方式,容许方便的重写现有方法。数据结构
高性能:轻量,能获取小部分的元数据。oracle
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); }
经过等级来进行控制,这样可以避免读取没必要要的信息而影响性能。
|
小 |
标准 |
大 |
驱动信息(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) |
获取指定级别的数据库元数据 |
不一样的数据库,获取元数据的方式必然不一样,从这一点来看,咱们须要一个策略模式。策略模式也方便进行扩展。
数据库决定以后,实际上也已经决定会使用哪一个具体实现。因此,在程序中实现方式的创建将交由一个工程,根据数据库类型自动创建。
咱们的数据库要求是线程安全的,因此要求不具备状态,每个方法都具备获取链接、关闭链接等步骤,因此咱们在这里使用了一个模板模式。MetaLoader的方法仍是比较复杂的。因此,咱们抽象除了一个MetaCrawler接口,进行细化,MetaLoader的方法实现能够经过MetaCrawler的组合实现。
部分实现,咱们使用的是DatabaseMeta,任何数据库都是同样的。可是部分信息如触发器、存储过程、函数等信息,DatabaseMeta是获取不到的,又要分开实现。因此,毫无疑问,咱们这里也使用了模板模式。
JDBC的异常为SQLException异常,抛出的异常都必须接住,会让代码结构很是混乱。同时,在close的方法抛出的异常,一般交给开发人员是没法进行任何处理的。因此,咱们选择catch这类没法处理的异常,而后进行日志输出。
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); } }
在方法的开始位置会获取一个链接,而后经过工厂建立一个实例。在方法的末尾关闭链接。整个过程都是无状态的,因此是线程安全的。