元數據(MetaData):
元數據(MetaData),即定義數據的數據.比如,我們要搜索一首歌(歌本身就是數據),可以通過歌名,歌手,專輯等信息來搜索,這些歌名,歌手,專輯就是這首歌的元數據.因此數據庫的元數據就是一些註明數據庫信息的數據.
JDBC來處理數據庫的接口主要有三個,即:
Connection : 由Connection對象的getMetaData()方法獲取的是DatabaseMetaData對象。
PreparedStatement : 由PreparedStatement對象的getParameterMetaData ()方法獲取的是ParameterMetaData對象。
ResultSet : 由ResultSet對象的getMetaData()方法獲取的是ResultSetMetaData對象。
一、DatabaseMetaData(數據庫元數據)
DatabaseMetaData是由Connection對象通過getMetaData方法獲取而來,主要封裝了數據庫本身的一些綜合信息,例如數據庫的產品名稱,數據庫的版本號,數據庫的URL,是否支持事務等等,能獲取的信息比較多,具體可以參考DatabaseMetaData的API文檔。
以下有一些關於DatabaseMetaData的常用方法: getDatabaseProductName:獲取數據庫的產品名稱
getDatabaseProductVersion:獲取數據庫的版本號
getUserName:獲取數據庫的用戶名
getURL:獲取數據庫連接的URL
getDriverName:獲取數據庫的驅動名稱
driverVersion:獲取數據庫的驅動版本號
isReadOnly:查看數據庫是否只允許讀操作
supportsTransactions:查看數據庫是否支持事務
代碼演示:
@Test
public void dataBaseMetaDataTest() throws Exception {
// 得到Connection對象
Connection con = JdbcUtil.getConnection();
// 得到DataBaseMetaData對象
DatabaseMetaData metaData = con.getMetaData();
System.out.println("獲取數據庫的產品名稱: " + metaData.getDatabaseProductName());
System.out.println("獲取數據庫的版本號: " + metaData.getDatabaseProductVersion());
System.out.println("獲取數據庫的用戶名: " + metaData.getUserName());
System.out.println("獲取數據庫的URL: " + metaData.getURL());
System.out.println("獲取數據庫的驅動名稱: " + metaData.getDriverName());
System.out.println("獲取數據庫的驅動版本號: " + metaData.getDriverVersion());
System.out.println("查看數據庫是否只允許讀操作: " + metaData.isReadOnly());
System.out.println("查看數據庫是否支持事務: " + metaData.supportsTransactions());
}
獲取數據庫的產品名稱: MySQL
獲取數據庫的版本號: 5.7.22-log
獲取數據庫的用戶名: root@localhost
獲取數據庫的URL: jdbc:mysql://localhost:3306/day16?characterEncoding=utf-8
獲取數據庫的驅動名稱: MySQL-AB JDBC Driver
獲取數據庫的驅動版本號: mysql-connector-java-5.1.7 ( Revision: ${svn.Revision} )
查看數據庫是否只允許讀操作: false
查看數據庫是否支持事務: true
二、ParameterMetaData(參數元數據)
ParameterMetaData是由PreparedStatement對象通過getParameterMetaData方法獲取而來,主要是針對PreparedStatement對象和其預編譯的SQL命令語句提供一些信息,比如像”insert into account(id,name,money) values(?,?,?)”這樣的預編譯SQL語句,ParameterMetaData能提供佔位符參數的個數,獲取指定位置佔位符的SQL類型等等.
以下有一些關於ParameterMetaData的常用方法: getParameterCount:獲取預編譯SQL語句中佔位符參數的個數
代碼演示:
@Test
public void parameterMetaDataTest() throws Exception{
//得到Connection對象
Connection con = JdbcUtil.getConnection();
//創建SQL
String sql = "select * from dept where id=? and sname=?";
//預編譯SQL,得到prepareStatement對象
PreparedStatement prepareStatement = con.prepareStatement(sql);
//得到parameterMetaData對象
ParameterMetaData parameterMetaData = prepareStatement.getParameterMetaData();
//獲取參數個數
int count = parameterMetaData.getParameterCount();
//輸出
System.out.println("佔位符個數爲: " + count);
}
輸出結果:
佔位符個數爲: 2
三、ResultSetMetaData(結果集元數據)
ResultSetMetaData是由ResultSet對象通過getMetaData方法獲取而來,主要是針對由數據庫執行的SQL腳本命令獲取的結果集對象ResultSet中提供的一些信息,比如結果集中的列數、指定列的名稱、指定列的SQL類型等等,可以說這個是對於框架來說非常重要的一個對象。
以下有一些關於ResultSetMetaData的常用方法:
getColumnCount:獲取結果集中列項目的個數
getColumnType:獲取指定列的SQL類型對應於Java中Types類的字段
getColumnTypeName:獲取指定列的SQL類型
getClassName:獲取指定列SQL類型對應於Java中的類型(包名加類名)
代碼演示:
對應表:
@Test
public void resultSetMetaDataTest(){
Connection con = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
//得到Connection對象
con = JdbcUtil.getConnection();
String sql = "select * from student";
//預編譯sql語句,得到PreparedStatement對象
stmt = con.prepareStatement(sql);
//執行sql
rs = stmt.executeQuery();
//得到結果集元對象
ResultSetMetaData metaData = rs.getMetaData();
System.out.println("獲取結果集的列數: " + metaData.getColumnCount());
System.out.println("獲取指定列的名稱: " + metaData.getColumnName(1));
System.out.println("獲取指定列的SQL類型對應於java.sql.Types類的字段: " + metaData.getColumnType(2));
System.out.println("獲取指定列的SQL類型: " + metaData.getColumnTypeName(1));
System.out.println("獲取指定列SQL類型對應於Java的類型: " + metaData.getColumnClassName(1));
System.out.println("獲取指定列所在的表的名稱: " + metaData.getTableName(1));
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
throw new RuntimeException(e);
}finally{
JdbcUtil.close(con, stmt, rs);
}
}
運行結果:
獲取結果集的列數: 3
獲取指定列的名稱: id
獲取指定列的SQL類型對應於java.sql.Types類的字段: 12
獲取指定列的SQL類型: INT
獲取指定列SQL類型對應於Java的類型: java.lang.Integer
獲取指定列所在的表的名稱: student
代碼演示:
@Test
public void resultSetMetaDataTest2(){
Connection con = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
//得到Connection對象
con = JdbcUtil.getConnection();
String sql = "select * from student";
//預編譯sql語句,得到PreparedStatement對象
stmt = con.prepareStatement(sql);
//執行sql
rs = stmt.executeQuery();
//得到結果集元對象
ResultSetMetaData metaData = rs.getMetaData();
//迭代每一行
while(rs.next()){
//獲取列數
int count = metaData.getColumnCount();
//遍歷,獲取每一列的列名和值
for (int i = 0; i < count; i++) {
//獲取列名
String columnName = metaData.getColumnName(i+1);
//獲取列名對應的值
Object object = rs.getObject(columnName);
//輸出
System.out.print(columnName + "=" + object + " ");
}
System.out.println();
}
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
throw new RuntimeException(e);
}finally{
JdbcUtil.close(con, stmt, rs);
}
}
運行結果:
id=1 sname=陳柯佛 gender=男
id=2 sname=王思聰 gender=男
id=3 sname=方文山 gender=男
id=4 sname=德澤 gender=男
id=5 sname=海超 gender=男
id=6 sname=海陽 gender=男
id=7 sname=海榮 gender=男
應用:
代碼演示:
/**
* @author chenkefo
* 通用的dao,自己寫的所有的dao都繼承此類
* 此類定義了2個同用的方法:
* 1.更新(insert/update/delete)
* 2.查詢
*/
public class BaseDao {
// 初始化參數
private Connection conn;
private PreparedStatement stmt;
private ResultSet rs;
/**
* 更新通用方法
*/
public void update(String sql, Object[] paramsValue) {
try {
// 獲取Connection對象
conn = JdbcUtil.getConnection();
// 預編譯sql,獲取preparedstatement
stmt = conn.prepareStatement(sql);
// 得到參數元數據
ParameterMetaData parameterMetaData = stmt.getParameterMetaData();
// 得到佔位符個數
int count = parameterMetaData.getParameterCount();
// 佔位符賦值
if (paramsValue != null && paramsValue.length > 0) {
for (int i = 0; i < count; i++) {
stmt.setObject(i + 1, paramsValue[i]);
}
}
// 執行sql
stmt.executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
throw new RuntimeException(e);
} finally {
// 關閉資源
JdbcUtil.close(conn, stmt, null);
}
}
/**
* 查詢通用方法
*/
public <T> List<T> query(String sql, Object[] paramsValue, Class<T> clazz) {
try {
//創建返回集合
List<T> list = new ArrayList<T>();
//得到Connection對象
conn = JdbcUtil.getConnection();
//預編譯sql,得到preparedStatement
stmt = conn.prepareStatement(sql);
//得到參數元對象
ParameterMetaData parameterMetaData = stmt.getParameterMetaData();
//得到佔位符個數
int count = parameterMetaData.getParameterCount();
//爲佔位符賦值
if (paramsValue != null && paramsValue.length > 0) {
for (int i = 0; i < count; i++) {
stmt.setObject(i + 1, paramsValue[i]);
}
}
//執行sql
rs = stmt.executeQuery();
//得到結果集元
ResultSetMetaData metaData = rs.getMetaData();
//獲取列數
int columnCount = metaData.getColumnCount();
//遍歷結果集
while (rs.next()) {
//創建對象
T t = clazz.newInstance();
//遍歷每一列
for (int i = 0; i < columnCount; i++) {
//獲取每一列的名字
String columnName = metaData.getColumnName(i + 1);
//通過列名,獲取值
Object object = rs.getObject(columnName);
//通過beanUtils爲對象賦值
BeanUtils.copyProperty(t, columnName, object);
}
//把對象添加至集合
list.add(t);
}
//返回集合
return list;
} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
throw new RuntimeException();
} finally {
//關閉資源
JdbcUtil.close(conn, stmt, rs);
}
}
}