行业知识
MyBatis3源码深度解析(六)DatabaseMetaData
文章目录
- 前言
- 2.6 DatabaseMetaData
- 2.6.1 创建DatabaseMetaData对象
- 2.6.2 获取数据源的基本信息
- 2.6.3 获取数据源支持特性
- 2.6.4 获取数据源限制
- 2.6.5 获取SQL对象及属性
- 2.6.6 获取事务���持
前言
本节研究DatabaseMetaData接口。该接口是一个模板接口,用于提供底层数据源相关的信息,具体实现由JDBC驱动程序来实现(本文的示例均是MySQL的驱动程序实现)。
()该接口的作用在于,为应用程序或工具确定如何与底层数据源交互,应用程序也可以使用该接口提供的方法获取数据源信息。
2.6 DatabaseMetaData
DatabaseMetaData接口中包含超过150个方法,还包含超过40个常量字段。这些方法可以大致分为以下几种类型:
()- 获取数据源的基本信息;
- 确定数据源是否支持某一特性或功能;
- 获取数据源的限制;
- 确定数据源包含哪些SQL对象以及这些对象的属性;
- 获取数据源对事务的支持。
2.6.1 创建DatabaseMetaData对象
创建DatabaseMetaData对象需要使用Connection对象提供的getMetadata()方法。示例如下:
// 创建DatabaseMetaData对象DatabaseMetaData metaData = connection.getMetaData();// 获取数据库表名允许的最大字符数int maxLen = metaData.getMaxTableNameLength();
2.6.2 获取数据源的基本信息
DatabaseMetaData接口提供了一些方法用于获取数据源的基本信息,包括URL、用户名等。
源码1:java/sql/DatabaseMetaData.java// 获取数据库URLString getURL() throws SQLException;// 获取数据库已知的用户String getUserName() throws SQLException;// 获取数据库产品名String getDatabaseProductName() throws SQLException;// 获取数据库产品的版本String getDatabaseProductVersion() throws SQLException;// 获取驱动主版本int getDriverMajorVersion();// 获取驱动副版本int getDriverMinorVersion();// 获取数据库供应商用于Schema的首选术语String getSchemaTerm() throws SQLException;// 获取数据库供应商用于Catalog的首选术语String getCatalogTerm() throws SQLException;// 获取数据库供应商用于Procedure的首选术语String getProcedureTerm() throws SQLException;// 获取null值是否高排序boolean nullsAreSortedHigh() throws SQLException;// 获取null值是否低排序boolean nullsAreSortedLow() throws SQLException;// 获取数据库是否将表存储在本地文件中boolean usesLocalFiles() throws SQLException;// 获取数据库是否为每个表使用一个文件boolean usesLocalFilePerTable() throws SQLException;// 获取数据库SQL关键字String getSQLKeywords() throws SQLException;
这些方法使用的示例如下:
@Testpublic void testDMD() { Connection connection = null; try { connection = DbUtils.getConnection(); // 获取DatabaseMetaData对象 DatabaseMetaData metaData = connection.getMetaData(); // 获取数据源的基本信息 System.out.println("数据库URL:" + metaData.getURL()); System.out.println("获取数据库已知的用户:" + metaData.getUserName()); System.out.println("数据库产品名:" + metaData.getDatabaseProductName()); System.out.println("获取数据库产品的版本:" + metaData.getDatabaseProductVersion()); System.out.println("驱动主版本:" + metaData.getDriverMajorVersion()); System.out.println("驱动副版本:" + metaData.getDriverMinorVersion()); System.out.println("数据库供应商用于Schema的首选术语:" + metaData.getSchemaTerm()); System.out.println("数据库供应商用于Catalog的首选术语:" + metaData.getCatalogTerm()); System.out.println("数据库供应商用于Procedure的首选术语:" + metaData.getProcedureTerm()); System.out.println("null值是否高排序:" + metaData.nullsAreSortedHigh()); System.out.println("null值是否低排序:" + metaData.nullsAreSortedLow()); System.out.println("数据库是否将表存储在本地文件中:" + metaData.usesLocalFiles()); System.out.println("数据库是否为每个表使用一个文件:" + metaData.usesLocalFilePerTable()); System.out.println("数据库SQL关键字:" + metaData.getSQLKeywords()); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭资源 DbUtils.close(null, null, connection); }}控制台打印执行结果:
数据库URL:jdbc:mysql://localhost:3306/mybatis_demo获取数据库已知的用户:root@localhost数据库产品名:MySQL获取数据库产品的版本:5.5.62驱动主版本:5驱动副版本:1数据库供应商用于Schema的首选术语:数据库供应商用于Catalog的首选术语:database数据库供应商用于Procedure的首选术语:PROCEDUREnull值是否高排序:falsenull值是否低排序:true数据库是否将表存储在本地文件中:false数据库是否为每个表使用一个文件:false数据库SQL关键字:ACCESSIBLE,ADD,ANALYZE,ASC,BEFORE,CASCADE,CHANGE,CONTINUE,DATABASE,DATABASES,DAY_HOUR,DAY_MICROSECOND,DAY_MINUTE,DAY_SECOND,DELAYED,DESC,DISTINCTROW,DIV,DUAL,ELSEIF,ENCLOSED,ESCAPED,EXIT,EXPLAIN,FLOAT4,FLOAT8,FORCE,FULLTEXT,GENERATED,HIGH_PRIORITY,HOUR_MICROSECOND,HOUR_MINUTE,HOUR_SECOND,IF,IGNORE,INDEX,INFILE,INT1,INT2,INT3,INT4,INT8,IO_AFTER_GTIDS,IO_BEFORE_GTIDS,ITERATE,KEY,KEYS,KILL,LEAVE,LIMIT,LINEAR,LINES,LOAD,LOCK,LONG,LONGBLOB,LONGTEXT,LOOP,LOW_PRIORITY,MASTER_BIND,MASTER_SSL_VERIFY_SERVER_CERT,MAXVALUE,MEDIUMBLOB,MEDIUMINT,MEDIUMTEXT,MIDDLEINT,MINUTE_MICROSECOND,MINUTE_SECOND,NO_WRITE_TO_BINLOG,OPTIMIZE,OPTIMIZER_COSTS,OPTION,OPTIONALLY,OUTFILE,PURGE,READ,READ_WRITE,REGEXP,RENAME,REPEAT,REPLACE,REQUIRE,RESIGNAL,RESTRICT,RLIKE,SCHEMA,SCHEMAS,SECOND_MICROSECOND,SEPARATOR,SHOW,SIGNAL,SPATIAL,SQL_BIG_RESULT,SQL_CALC_FOUND_ROWS,SQL_SMALL_RESULT,SSL,STARTING,STORED,STRAIGHT_JOIN,TERMINATED,TINYBLOB,TINYINT,TINYTEXT,UNDO,UNLOCK,UNSIGNED,USAGE,USE,UTC_DATE,UTC_TIME,UTC_TIMESTAMP,VARBINARY,VARCHARACTER,VIRTUAL,WHILE,WRITE,XOR,YEAR_MONTH,ZEROFILL
2.6.3 获取数据源支持特性
DatabaseMetaData接口还提供了一些方法用于确定数据源是否支持某个或一组特定的特性,以及用于描述数据源对某一特性的支持级别。
源码2:java/sql/DatabaseMetaData.java// 检索此数据源是否支持带有删除列的ALTER TABLE语句boolean supportsAlterTableWithDropColumn() throws SQLException;// 检索此数据源是否支持批量更新boolean supportsBatchUpdates() throws SQLException;// 检索此数据源是否支持完整地嵌套外部连接boolean supportsFullOuterJoins() throws SQLException;// 检索此数据源是否将双引号括起来的大小写混合的SQL标识符视为区分大小写,并以混合大小写的方式存储boolean supportsMixedCaseQuotedIdentifiers() throws SQLException;// 检索此数据源是否支持定位的DELETE语句boolean supportsPositionedDelete() throws SQLException;// 检索此数据源是否支持存储过程boolean supportsStoredProcedures() throws SQLException;// 检索此数据源是否支持ANSI92入门级SQL语法boolean supportsANSI92EntryLevelSQL() throws SQLException;// 检索此数据源是否支持ODBC核心SQL语法boolean supportsCoreSQLGrammar() throws SQLException;
这些方法的使用示例如下:
// ......System.out.println("检索此数据源是否支持带有删除列的ALTER TABLE语句:" + metaData.supportsAlterTableWithDropColumn());System.out.println("检索此数据源是否支持批量更新:" + metaData.supportsBatchUpdates());System.out.println("检索此数据源是否支持完整地嵌套外部连接:" + metaData.supportsFullOuterJoins());System.out.println("检索此数据源是否将双引号括起来的大小写混合的SQL标识符视为区分大小写,并以混合大小写的方式存储:" + metaData.supportsMixedCaseQuotedIdentifiers());System.out.println("检索此数据源是否支持定位的DELETE语句:" + metaData.supportsPositionedDelete());System.out.println("检索此数据源是否支持存储过程:" + metaData.supportsStoredProcedures());System.out.println("检索此数据源是否支持ANSI92入门级SQL语法:" + metaData.supportsANSI92EntryLevelSQL());System.out.println("检索此数据源是否支持ODBC核心SQL语法:" + metaData.supportsCoreSQLGrammar());// ......控制台打印执行结果:
检索此数据源是否支持带有删除列的ALTER TABLE语句:true检索此数据源是否支持批量更新:true检索此数据源是否支持完整地嵌套外部连接:false检索此数据源是否将双引号括起来的大小写混合的SQL标识符视为区分大小写,并以混合大小写的方式存储:false检索此数据源是否支持定位的DELETE语句:false检索此数据源是否支持存储过程:true检索此数据源是否支持ANSI92入门级SQL语法:true检索此数据源是否支持ODBC核心SQL语法:true
2.6.4 获取数据源限制
DatabaseMetaData接口提供了一些方法用于获取数据源的限制子信息。
源码3:java/sql/DatabaseMetaData.java// 获取数据库支持的最大连接数int getMaxConnections() throws SQLException;// 获取数据库支持的字符串字面量长度int getMaxCharLiteralLength() throws SQLException;// 获取数据库表中允许的最大列数int getMaxColumnsInTable() throws SQLException;// 获取最大行数int getMaxRowSize() throws SQLException;// 获取数据库在SQL语句中允许的最大字符出int getMaxStatementLength() throws SQLException;// 获取数据库在SELECT语句中允许的最大表数int getMaxTablesInSelect() throws SQLException;
这些方法的返回值类型均为int,当返回值为0时,标识没有限制或限制未知。示例如下:
// ......System.out.println("数据库支持的最大连接数:" + metaData.getMaxConnections());System.out.println("数据库支持的字符串字面量长度:" + metaData.getMaxCharLiteralLength());System.out.println("数据库表中允许的最大列数:" + metaData.getMaxColumnsInTable());System.out.println("最大行数:" + metaData.getMaxRowSize());System.out.println("数据库在SQL语句中允许的最大字符出:" + metaData.getMaxStatementLength());System.out.println("数据库在SELECT语句中允许的最大表数:" + metaData.getMaxTablesInSelect());// ......控制台输出执行结果:
数据库支持的最大连接数:0数据库支持的字符串字面量长度:16777208数据库表中允许的最大列数:512最大行数:2147483639数据库在SQL语句中允许的最大字符出:65531数据库在SELECT语句中允许的最大表数:256
2.6.5 获取SQL对象及属性
DatabaseMetaData接口提供了一些方法用于获取数据源有关SQL对象的信息,以及这些对象的属性信息。
源码4:java/sql/DatabaseMetaData.java// 获取Catalog信息ResultSet getCatalogs() throws SQLException;// 获取给定类别的函数参数和结果列的信息ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) throws SQLException;// 获取函数信息ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException;// 获取给定类别的存储过程参数和结果列信息ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException;// 获取主键信息ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException;// 获取存储过程信息ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException;// 获取Schema信息ResultSet getSchemas() throws SQLException;// 获取表信息ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String types[]) throws SQLException;// 获取用户自定义的数据类型ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException;
这些方法的返回值类型均为ResultSet,这个ResultSet对象的类型为TYPE_FORWARD_ONLY,并行性为CONCUR_READ_ONLY,而可保持性由JDBC驱动程序具体决定,可以通过getHoldability()方法获取。示例如下:
// ......ResultSet rs1 = metaData.getCatalogs();while (rs1.next()) { System.out.println(rs1.getString(1));}// ......控制台打印执行结果:
mybatis_demo
2.6.6 获取事务支持
DatabaseMetaData接口提供了一些方法用于判断数据源对事务的支持,主要包括:
源码5:java/sql/DatabaseMetaData.java// 是否支持某一事务隔离级别// 0 - TRANSACTION_NONE:无事务// 1 - TRANSACTION_READ_COMMITTED:读提交// 2 - TRANSACTION_READ_UNCOMMITTED:读未提交// 4 - TRANSACTION_REPEATABLE_READ:可重复读// 8 - TRANSACTION_SERIALIZABLE:串行化boolean supportsTransactionIsolationLevel(int level) throws SQLException;// 是否支持事务boolean supportsTransactions() throws SQLException;// 是否支持同时开启多个事务boolean supportsMultipleTransactions() throws SQLException;// 获取默认的事务隔离级别int getDefaultTransactionIsolation() throws SQLException;
这些方法的使用示例如下:
// ......System.out.println("是否支持事务级别-无事务:" + metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_NONE));System.out.println("是否支持事务级别-读未提交:" + metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED));System.out.println("是否支持事务级别-读提交:" + metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED));System.out.println("是否支持事务级别-可重复读:" + metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_REPEATABLE_READ));System.out.println("是否支持事务级别-串行化:" + metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE));System.out.println("是否支持事务:" + metaData.supportsTransactions());System.out.println("是否支持同时开启多个事务:" + metaData.supportsMultipleTransactions());System.out.println("默认的事务隔离级别:" + metaData.getDefaultTransactionIsolation());// ......控制台打印执行结果:
是否支持事务级别-无事务:false是否支持事务级别-读未提交:true是否支持事务级别-读提交:true是否支持事务级别-可重复读:true是否支持事务级别-串行化:true是否支持事务:true是否支持同时开启多个事务:true默认的事务隔离级别:2
…
本节完,更多内容请查阅分类专栏:MyBatis3源码深度解析
上一篇:TikTok国际版下载指南
下一篇:怎么租服务器玩游戏?