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);
        }
    }
}

 

上一篇:Git remote 修改源


下一篇:stmt.executeQuery不执行解决办法