1.數據庫中的元數據
(1) 什麼是數據元數據?
元數據(MetaData),是指定義數據結構的數據。那麼數據庫元數據就是指定義數據庫各類對象結構的數據。 例如數據庫中的數據庫名,表明, 列名、用戶名、版本名以及從SQL語句得到的結果中的大部分字符串是元數據
(2)數據庫元數據的作用
在應用設計時能夠充分地利用數據庫元數據
深入理解了數據庫組織結構,再去理解數據訪問相關框架的實現原理會更加容易。
(3)如何獲取元數據
在我們前面使用JDBC來處理數據庫的接口主要有三個,即Connection,PreparedStatement和ResultSet這三個,而對於這三個接口,還可以獲取不同類型的元數據,通過這些元數據類獲得一些數據庫的信息。下面將對這三種類型的元數據對象進行各自的介紹並通過使用MYSQL數據庫進行案例說明
2 數據庫元數據
2.1 概述
數據庫元數據(DatabaseMetaData):是由Connection對象通過getMetaData方法獲取而來,主要封裝了是對數據庫本身的一些整體綜合信息,例如數據庫的產品名稱,數據庫的版本號,數據庫的URL,是否支持事務等等。
以下有一些關於DatabaseMetaData的常用方法:
getDatabaseProductName:獲取數據庫的產品名稱
getDatabaseProductName:獲取數據庫的版本號
getUserName:獲取數據庫的用戶名
getURL:獲取數據庫連接的URL
getDriverName:獲取數據庫的驅動名稱
driverVersion:獲取數據庫的驅動版本號
isReadOnly:查看數據庫是否只允許讀操作
supportsTransactions:查看數據庫是否支持事務
代碼示例:
基礎類:MetaDataBase
package com.shunli.autocodeutils.metadate;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
/**
* @author shunli
* @描述:
* @create 2020/2/16
* @since 1.0.0
*/
public class MetaDataBase {
private static String userName = "root";
private static String password = "root";
private String tableName = "";
//這裏用的的是mysql-connector-java-8.0.19版本,所以driver和url跟老版本不同
private static String driver = "com.mysql.cj.jdbc.Driver";
private static String url = "jdbc:mysql://127.0.0.1:3306/[tableName]?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT";
public MetaDataBase() {
url = url.replace("[tableName]", tableName);
}
public MetaDataBase(String tableName) {
this.tableName = tableName;
url = url.replace("[tableName]", tableName);
}
/**
* 獲取連接
* @return
* @throws Exception
*/
public Connection getConnection() throws Exception {
//獲取數據庫的備註信息
Properties properties = new Properties();
//設置連接屬性,使得可獲取到表的REMARK(備註)
properties.put("remarksReporting","true");
properties.put("user",userName);
properties.put("password",password);
//註冊驅動
Class.forName(driver);
return DriverManager.getConnection(url, properties);
}
}
獲取數據庫元數據基本信息:
package com.shunli.autocodeutils.metadate;
import org.junit.jupiter.api.Test;
import java.sql.*;
/**
* @author shunli
* @描述:
* @create 2020/2/12
* @since 1.0.0
*/
public class DataBaseMetaDataTest {
private MetaDataBase metaDataBase = new MetaDataBase();
/**
* 獲取數據庫元數據基本信息
* @throws Exception
*/
@Test
public void getDatabaseMetaData() throws Exception {
//獲取數據庫元數據
Connection connection = metaDataBase.getConnection();
DatabaseMetaData dbMetaData = connection.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);
//獲取數據庫連接URL
String userUrl = dbMetaData.getURL();
System.out.println(userUrl);
//獲取數據庫驅動
String driverName = dbMetaData.getDriverName();
System.out.println(driverName);
//獲取數據庫驅動版本號
String driverVersion = dbMetaData.getDriverVersion();
System.out.println(driverVersion);
//查看數據庫是否允許讀操作
boolean isReadOnly = dbMetaData.isReadOnly();
System.out.println(isReadOnly);
//查看數據庫是否支持事務操作
boolean supportsTransactions = dbMetaData.supportsTransactions();
System.out.println(supportsTransactions);
//關閉
connection.close();
}
}
獲取數據庫列表:
/**
* 獲取數據庫列表
*/
@Test
public void getDataBaseList() throws Exception {
//獲取元數據
Connection connection = metaDataBase.getConnection();
DatabaseMetaData metaData = connection.getMetaData();
//獲取數據庫列表
ResultSet rs = metaData.getCatalogs();
//遍歷獲取所有數據庫表
while (rs.next()) {
//打印數據庫名稱
System.out.println(rs.getString(1));
}
//釋放資源
rs.close();
connection.close();
}
獲取某數據庫中的所有表信息:
/**
* 獲取所有的數據庫表信息
* @throws Exception
*/
@Test
public void getTableInfo() throws Exception {
//獲取元數據
Connection connection = metaDataBase.getConnection();
DatabaseMetaData metaData = connection.getMetaData();
/**
* 參數說明:
* String catalog 查詢指定數據庫,傳空查詢所有數據庫的表信息
* String schemaPattern 對於mysql來說直接傳null,對於oracle:用戶名(大寫)
* String tableNamePattern 查詢指定表,爲空時查詢所有表
* String types[] 查詢數據庫表類型:TABLE(表)、VIEW(視圖)
*/
//獲取所有的數據庫表信息
ResultSet tablers = metaData.getTables(null, null, null, new String[]{"TABLE"});
//拼裝table
while (tablers.next()) {
//所屬數據庫
System.out.println(tablers.getString(1));
//所屬schema
System.out.println(tablers.getString(2));
//表名
System.out.println(tablers.getString(3));
//數據庫表類型
System.out.println(tablers.getString(4));
//數據庫表備註
System.out.println(tablers.getString(5));
}
}
3.參數元數據
參數元數據(ParameterMetaData):是由PreparedStatement對象通過getParameterMetaData方法獲取而
來,主要是針對PreparedStatement對象和其預編譯的SQL命令語句提供一些信息,ParameterMetaData能提供佔位符參數的個數,獲取指定位置佔位符的SQL類型等等
以下有一些關於ParameterMetaData的常用方法:
getParameterCount:獲取預編譯SQL語句中佔位符參數的個數
示例:
package com.shunli.autocodeutils.metadate;
import org.junit.Test;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
/**
* @author shunli
* @描述:
* @create 2020/2/16
* @since 1.0.0
*/
public class ParameterMetaDataTest {
private MetaDataBase metaDataBase = new MetaDataBase("o2o");
@Test
public void test() throws Exception {
String sql = "select * from tb_area where area_id=?";
Connection connection = metaDataBase.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, "500");
//獲取ParameterMetaData對象
ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();
//獲取參數個數
int paramCount = parameterMetaData.getParameterCount();
System.out.println(paramCount);
}
}
4.結果集元數據
結果集元數據(ResultSetMetaData):是由ResultSet對象通過getMetaData方法獲取而來,主要是針對由數據庫執行的SQL腳本命令獲取的結果集對象ResultSet中提供的一些信息,比如結果集中的列數、指定列的名稱、指定列的SQL類型等等,可以說這個是對於框架來說非常重要的一個對象。
以下有一些關於ResultSetMetaData的常用方法:
getColumnCount:獲取結果集中列項目的個數
getColumnType:獲取指定列的SQL類型對應於Java中Types類的字段
getColumnTypeName:獲取指定列的SQL類型
getClassName:獲取指定列SQL類型對應於Java中的類型(包名加類名)
示例:
package com.shunli.autocodeutils.metadate;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
/**
* @author shunli
* @描述:
* @create 2020/2/16
* @since 1.0.0
*/
public class ResultSetMetaDataTest {
private MetaDataBase metaDataBase = new MetaDataBase("o2o");
@Test
public void test() throws Exception {
String sql = "select * from tb_area where area_id=?";
Connection connection = metaDataBase.getConnection();
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, "500");
//執行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);
System.out.println(columnName);
//獲取java類型
String columnClassName = metaData.getColumnClassName(i);
System.out.println(columnClassName);
//獲取sql類型
String columnTypeName = metaData.getColumnTypeName(i);
System.out.println(columnTypeName);
}
System.out.println(columnCount);
}
}