目录
元数据(MetaData),是指定义数据结构的数据。
例如这张表的表头(列名)

当然还有数据库名和表名。

除了这些还有用户名、版本名以及从SQL语句得到的结果中的大部分字符串都是元数据。
那数据库中的元数据有什么作用呢?
主要有两个方面:
- 应用设计方面,例如代码生成器,它里面就需要用到数据库元数据。
- 如果你了解了数据库元数据,就能对数据库的一些框架有更深层次的了解,例如 jpa,Mybatis。
我们在JAVA中操作数据库,无非就是JDBC,不管是MySQL还是Oracle 或者是其他数据库,基本都是通过JDBC的连接去跟数据库打交道。
使用JDBC来处理数据库的接口主要有三个,即Connection,PreparedStatement和ResultSet这三个接口。
对于这三个接口,还可以获取不同类型的元数据。
| 接口 | 说明 |
| Connection | 获取数据库元数据(DatabaseMetaData) |
| PreparedStatement | 获取我们发送请求获得的参数元数据(ParameterMetaData) |
| ResultSet | 获取结果集元数据(ResultSetMetaData) |
下面将对这三种类型的元数据对象进行各自的介绍并通过使用MYSQL数据库进行案例说明。
数据库元数据(DatabaseMetaData):是由Connection对象通过getMetaData方法获取而来,主要封装了是对数据库本身的一些整体综合信息,例如数据库的名称,数据库的版本号,数据库的URL,是否支持事务等等。
以下有一些关于DatabaseMetaData的常用方法:
| 方法 | 说明 |
| getDatabaseProductName | 获取数据库的名称 |
| getDatabaseProductName | 获取数据库的版本号 |
| getUserName | 获取数据库的用户名 |
| getURL | 获取数据库连接的URL |
| getDriverName | 获取数据库的驱动名称 |
| driverVersion | 获取数据库的驱动版本号 |
| isReadOnly | 查看数据库是否只允许读操作 |
| supportsTransactions | 查看数据库是否支持事务 |
我随便找的一个以前做Demo 的 项目(SpringBoot项目)去写了。
引入的mySql 依赖。
- <!--mysql-->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <scope>runtime</scope>
- </dependency>
既然是SpringBoot项目,那当然是直接使用 yml文件 配置数据库连接啦。
- server:
- port: 80
- spring:
- application:
- name: mp
- datasource: # 配置数据源信息
- url: jdbc:mysql://127.0.0.1:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false
- username: root
- password: 1234
- driver-class-name: com.mysql.cj.jdbc.Driver
- @SpringBootTest
- class MetadataTest {
-
- // 数据源
- @Resource
- DataSource dataSourcee;
-
- @Test
- void Test01() {
- try {
- //获取数据库元数据
- DatabaseMetaData dbMetaData = dataSourcee.getConnection().getMetaData();
- //获取数据库产品名称
- String productName = dbMetaData.getDatabaseProductName();
- System.out.println("数据库产品名称:" + productName);
-
- // 获取数据库版本号
- String productVersion = dbMetaData.getDatabaseProductVersion();
- System.out.println("数据库版本号:"+productVersion);
-
- // 获取数据库用户名
- String userName = dbMetaData.getUserName();
- System.out.println("数据库用户名:"+userName);
-
- } catch (Exception throwables) {
- throwables.printStackTrace();
- }
- }
- }
这里就写了三个哈,反正都大同小异,剩下的大家自己去尝试。
效果:

- @SpringBootTest
- class MetadataTest {
-
- // 数据源
- @Resource
- DataSource dataSourcee;
-
- @Test
- void Test01() {
- try {
- //获取数据库元数据
- DatabaseMetaData dbMetaData = dataSourcee.getConnection().getMetaData();
-
- //获取数据库列表
- ResultSet rs = dbMetaData.getCatalogs();
- //遍历获取所有数据库表
- while (rs.next()) {
- //打印数据库名称
- System.out.println("表名:"+rs.getString(1));
- }
- //释放资源
- rs.close();
- dataSourcee.getConnection().close();
- } catch (Exception throwables) {
- throwables.printStackTrace();
- }
- }

- @Test
- void Test01() {
- try {
- //获取数据库元数据
- DatabaseMetaData dbMetaData = dataSourcee.getConnection().getMetaData();
- // 获取指定数据库中指定的表信息
- ResultSet tablers = dbMetaData.getTables(null, null, "t_user", new String[]{"TABLE"});
- //拼装table
- while (tablers.next()) {
- //所属数据库 1 || TABLE_CAT
- System.out.println("所属数据库:" + tablers.getString("TABLE_CAT"));
- //表模式 2 || TABLE_SCHEM
- System.out.println("表模式:" + tablers.getString("TABLE_SCHEM"));
- //表名 3 || TABLE_NAME
- System.out.println("表名:" + tablers.getString("TABLE_NAME"));
- //数据库表类型 4 || TABLE_TYPE
- System.out.println("类型:" + tablers.getString("TABLE_TYPE"));
- //数据库表备注 5 || REMARKS
- System.out.println("备注:" + tablers.getString("REMARKS"));
- }
- } catch (Exception throwables) {
- throwables.printStackTrace();
- }
- }
其中获取表数据的方法 getTables 中的4个参数分别是:
| 参数 | 说明 |
| catalog | 数据库名称,null 就是所有数据库 |
| schemaPattern | 模式名称,在mysql中没什么特别意义,所以直接填 null . |
| tableNamePattern | 表名,null 就是所有表 |
| types[] | 类型: TABLE:表 VIEW:视图 |
看看执行效果吧:

- @Test
- void Test01() {
- try {
- //获取数据库元数据
- DatabaseMetaData dbMetaData = dataSourcee.getConnection().getMetaData();
- // 获取指定数据库表中的字段信息
- ResultSet columns = dbMetaData.getColumns("mybatis_plus", null, "t_user", null);
- //拼装table
- while (columns.next()) {
- //所属数据库 1 || TABLE_CAT
- System.out.println("所属数据库:" + columns.getString("TABLE_CAT"));
- //表模式 2 || TABLE_SCHEM
- System.out.println("表模式:" + columns.getString("TABLE_SCHEM"));
- //表名 3 || TABLE_NAME
- System.out.println("表名:" + columns.getString("TABLE_NAME"));
- // 列名 4 || COLUMN_NAME
- System.out.println("列名:" + columns.getString("COLUMN_NAME"));
- //数据库表类型 5 || DATA_TYPE
- System.out.println("类型:" + columns.getString("DATA_TYPE"));
- //数据库表备注 12 || REMARKS
- System.out.println("备注:" + columns.getString("REMARKS"));
- }
- } catch (Exception throwables) {
- throwables.printStackTrace();
- }
- }
这个没什么改变,就换了个方法 getColumns
参数一样的就是最后一个变成 列名,null就代表查找所有列。
参数元数据(ParameterMetaData):是由PreparedStatement对象通过getParameterMetaData方法获取而来,主要是针对PreparedStatement对象和其预编译的SQL命令语句提供一些信息,ParameterMetaData能提供占位符参数的个数,获取指定位置占位符的SQL类型等等。
- @Test
- void Test01() {
- try {
- String sql = "select * from t_user where uid = ?";
- PreparedStatement pstmt = dataSourcee.getConnection().prepareStatement(sql);
- //获取ParameterMetaData对象
- ParameterMetaData paramMetaData = pstmt.getParameterMetaData();
- pstmt.setString(1, "1");
- //获取参数个数
- int paramCount = paramMetaData.getParameterCount();
- System.out.println(paramCount);
- } catch (Exception throwables) {
- throwables.printStackTrace();
- }
- }
当然它还有很多其它的方法。这个对刚学JDBC连接数据库的同学应该很熟悉,反正我是忘得差不多了。
结果集元数据(ResultSetMetaData):是由ResultSet对象通过getMetaData方法获取而来,主要是针对由数据 库执行的SQL脚本命令获取的结果集对象ResultSet中提供的一些信息,比如结果集中的列数、指定列的名称、指定列的SQL类型等等,可以说这个是对于框架来说非常重要的一个对象。
常用方法有:
| 方法 | 说明 |
| getColumnCount | 获取结果集中列项目的个数 |
| getColumnType | 获取指定列的SQL类型对应于Java中Types类的字段 |
| getColumnTypeName | 获取指定列的SQL类型 |
| getClassName | 获取指定列SQL类型对应于Java中的类型(包名加类名) |
- @Test
- void Test01() {
- try {
- String sql = "select * from t_user where uid = ?";
- PreparedStatement pstmt = dataSourcee.getConnection().prepareStatement(sql);
- //获取ParameterMetaData对象
- ParameterMetaData paramMetaData = pstmt.getParameterMetaData();
- pstmt.setString(1, "1");
- //执行sql语句
- ResultSet rs = pstmt.executeQuery();
- //获取ResultSetMetaData对象
- ResultSetMetaData metaData = rs.getMetaData();
- //获取查询字段数量
- int columnCount = metaData.getColumnCount();
- for (int i = 1; i <= columnCount; i++) {
- //获取列名称
- String columnName = metaData.getColumnName(i);
- //获取java类型
- String columnClassName = metaData.getColumnClassName(i);
- //获取sql类型
- String columnTypeName = metaData.getColumnTypeName(i);
- System.out.println("列名称"+columnName);
- System.out.println("java类型"+columnClassName);
- System.out.println("sql类型"+columnTypeName);
- }
- System.out.println(columnCount);
- } catch (Exception throwables) {
- throwables.printStackTrace();
- }
- }