以下是有关数据库架构导航的一些想法:
标准品
SQL-92标准定义了RDBMS如何实现包含其字典表的INFORMATION_SCHEMA。 实际上,某些RDBMS确实实现了标准规范的某些部分。 这些RDBMS附带了该标准的某些实现。
接近标准
- HSQLDB:非常接近真实标准
- Postgres:接近标准,但有一些调整(也有专有的字典表)
- SQL Server:接近标准但不完整(也具有专有的字典表)
标准的自由解释
- H2(最近有一些向后不兼容的更改)
- MySQL(仅从5.0开始,还具有专有的字典表)
其他RDBMS提供了他们自己的字典表概念。 对于像jOOQ这样的模式导航工具来说,要掌握这些技巧非常棘手。 字典表格局可以这样描述(我的偏见):
整齐有据的字典表
- DB2:这些字典表在某种程度上看起来像标准的,但名称不同。 他们感到直观。
- Oracle:在我看来,字典视图的集合要比标准提议的字典视图更好。 在整个Internet上非常易于理解和文档完善
- SQLite:没有字典表,但是SQLite存储过程使用起来非常简单。 毕竟这是一个简单的数据库
难以理解,没有详细记录的字典表
- Derby:创建了企业集团的概念,而不是使用通常的数据库语言,例如关系,键等。
- MySQL:旧的mysql模式非常痛苦。 幸运的是,MySQL 5.0不再适用
- Ingres:好吧……Ingres是一个古老的数据库 。 可用性并不是70年代的主要内容之一。
- Sybase SQL Anywhere:许多必须以复杂关系连接的对象。 文件稀缺
- Sybase ASE:比SQL Anywhere还要困难。 某些数据只能通过“技巧”获得
JDBC抽象
字典表的多样性似乎要求标准抽象。 尽管实际上可以在大多数RDBMS中实现SQL-92标准,但JDBC抽象甚至更好。 JDBC知道DatabaseMetaData对象,并允许轻松导航数据库模式。 不幸的是,此API 有时会抛出SQLFeatureNotSupportedException 。 关于哪个JDBC驱动程序实现多少API以及何时需要解决方法,没有通用的规则。 对于jOOQ代码生成,这些事实使该API毫无用处。
其他工具
如前所述,开源世界中还有其他一些工具。 在jOOQ中使用这些工具有一些缺点:
- 据我所知,这两个工具均已获得LGPL许可,这与jOOQ的Apache 2许可证不太兼容。
- 两种工具都很好地导航了实体关系,但是似乎缺乏对许多非标准构造的支持,例如UDT,高级存储过程用法(例如,返回游标,UDT等),ARRAY
- SchemaCrawler仅支持8个RDBMS,jOOQ现在有12个
- 两种工具都不活跃。 看这里和这里
有关更多信息,请访问其网站:
- 模式爬虫
- 模式间谍
Jooq-meta
由于上述原因,jOOQ附带了自己的数据库模式导航:jooq-meta。 该模块可以单独用作JDBC的DatabaseMetaData,SchemaCrawler或SchemaSpy的替代。 jooq-meta使用jOOQ设计的查询来导航数据库元数据,因此它也是集成测试套件的一部分。 例如,查看如何使用jooq-meta导航Ingres外键关系:
Result<Record> result = create().select(IirefConstraints.REF_CONSTRAINT_NAME.trim(),IirefConstraints.UNIQUE_CONSTRAINT_NAME.trim(),IirefConstraints.REF_TABLE_NAME.trim(),IiindexColumns.COLUMN_NAME.trim()).from(IICONSTRAINTS).join(IIREF_CONSTRAINTS).on(Iiconstraints.CONSTRAINT_NAME.equal(IirefConstraints.REF_CONSTRAINT_NAME)).and(Iiconstraints.SCHEMA_NAME.equal(IirefConstraints.REF_SCHEMA_NAME)).join(IICONSTRAINT_INDEXES).on(Iiconstraints.CONSTRAINT_NAME.equal(IiconstraintIndexes.CONSTRAINT_NAME)).and(Iiconstraints.SCHEMA_NAME.equal(IiconstraintIndexes.SCHEMA_NAME)).join(IIINDEXES).on(IiconstraintIndexes.INDEX_NAME.equal(Iiindexes.INDEX_NAME)).and(IiconstraintIndexes.SCHEMA_NAME.equal(Iiindexes.INDEX_OWNER)).join(IIINDEX_COLUMNS).on(Iiindexes.INDEX_NAME.equal(IiindexColumns.INDEX_NAME)).and(Iiindexes.INDEX_OWNER.equal(IiindexColumns.INDEX_OWNER)).where(Iiconstraints.SCHEMA_NAME.equal(getSchemaName())).and(Iiconstraints.CONSTRAINT_TYPE.equal("R")).orderBy(IirefConstraints.REF_TABLE_NAME.asc(),IirefConstraints.REF_CONSTRAINT_NAME.asc(),IiindexColumns.KEY_SEQUENCE.asc()).fetch();
结论
再一次可以说,RDBMS的世界是非常不同的。 Java中的数据库抽象仅在某种程度上在诸如JDBC,Hibernate / JPA之类的技术以及诸如SchemaCrawler,SchemaSpy和jooq-meta之类的第三方库中建立。
参考: JCG合作伙伴在“ Java,SQL和jOOQ”博客上提供的 Java数据库模式导航 。
- Java Persistence API:快速入门
- GWT 2 Spring 3 JPA 2 Hibernate 3.5教程
- JBoss 4.2.x Spring 3 JPA Hibernate教程
- Hibernate映射集合性能问题
翻译自: https://www.javacodegeeks.com/2011/09/database-schema-navigation-in-java.html