JDBC元數據(MetaData)學習

原文鏈接:https://blog.csdn.net/chenkefo/article/details/81901776

元數據(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);
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章