【超详】Java中的元数据 / 元数据分类/为什么需要元数据?/元数据管理技术

一、元数据分类:

1.业务元数据

主要包括业务术语、信息分类、指标定义、业务规则等。

2,技术元数据

数据结构、数据处理细节方面的技术化描述,主要包括源系统接口规范、数据仓库结构的描述(接口信息、表信息、程序信息等)以及经营分析数据处理过程的描述等。

3.管理元数据

主要包括人员角色、岗位职责、管理流程等信息。

4.安全元数据

主要包括访问安全、权限控制、分级管理、隐私控制、流程约束等信息。

5.稽核元数据

主要包括数据完整性和一致性检查、数据采集日志追踪、稽核规则、稽核流程、预警通知规则(数据质量)等信息。

二、为什么需要元数据?

当元数据作为数据的数据,主要应用目的,有以下几点:

  • 1、确认和检索(Discovery identification),主要致力于如何帮助人们检索和确认需要的资源,数据元素往往限于作者、标题、主题、位置等简单信息,Dublin Core是其典型代表。

2、著录描述(Cataloging),用于对数据单元进行详细、全面的著录描述,数据元素囊括内容、载体、位置与获取方式等等,MARC和FGDC/CSDGM是这类的典型代表。

3、资源管理(Resource Administration),支持资源的存储和使用管理,数据袁术除了包括比较全面的著录描述信息外,还往往包括权利管理、电子签名、资源评鉴、使用管理、支付审计等方面的信息。

4、资源保护与长期保存(Preservation and Archiving),支持对资源进行长期保存,数据元素除对资源进行描述和确认外,往往包括详细的格式信息、制作信息、保护条件、转换方式、保存责任等内容。

在网络资源描述方面,Dublin Core 经过多年国际性努力,已经成为了一个广为接受和应用的事实标准。

三、元数据管理技术

  • 子树分割(Subtree Partitioning)
  • 哈希(Hashing)

子树分割策略把分布式文件系统的全局命名空间和目录层次按照一定策略分割成多个子树,每个子树分布到一个特定的MDS中。

子树分割(Subtree Partitioning):

  • 静态子树分割只有在修改系统配置后,子树才会在MDS中重新分布。实现简单,充分利用存储局部性,但是权限验证耗时长,不能动态负载。

  • 动态子树分割策略将命名空间的不同子树委托授权给不同的MDS,方法灵活,分割粒度也相应较小,可以通过子树迁移来实现动态负载均衡。

哈希(Hashing):

哈希策略则利用文件或目录的某个特征值来计算hash值,并根据这些hash值将对应的文件或目录分布到MDS中。

静态哈系策略分布粒度更小,负载分布更均衡,且并发度更高。
缺点:元数据的均匀分布使得系统的一致性很难维护,目录重命名或者MDS集群的变动会导致规模庞大的元数据迁移。

LH(Lazy Hybrid)策略,它保留了目录层次结构,以便于提供文件系统语义,同时采用文件的全路径名称进行hash计算,从而把文件分布到不同的MDS中。它在保留子树分割和静态哈希的优点的同时,也不可避免的包含了二者的缺点。


【数据库中:】三种元数据

  • 数据库元数据
      通过java.sql.Connection获取对应的元数据

  • SQL语句元数据
      通过java.sql.PreparedStatement获取对应的元数据

  • 数据库结果集元数据
      通过java.sql.ResultSet获取对应的元数据
      
      
    【了解及其明白 】
     1. SQL语句元数据,参数元数据其中的参数个数 对应 ? 占位符个数
     2. 结果集元数据中的字段个数,和对应当前字段下标的字段名字
     
    【上代码】

package com.qfedu.b_matedata;
import org.junit.Test;
import util.JdbcUtil;
import java.sql.*;

/**
 * 元数据测试
 *
 * @author Anonymous 2020/3/24 14:39
 */
public class TestMetaData {
    // 数据库元数据演示
    @Test
    public void databaseMetaData() throws SQLException {
        Connection connection = JdbcUtil.getConnection();

        // 数据库元数据
        DatabaseMetaData metaData = connection.getMetaData();

        System.out.println("UserName:" + metaData.getUserName());
        System.out.println("DriverVersion:" + metaData.getDriverVersion());
        System.out.println("DriverName:" + metaData.getDriverName());
        System.out.println("URL:" + metaData.getURL());

        System.out.println(connection);
    }

    @Test
    public void sqlMetaData() throws SQLException {
        // 获取数据库连接
        Connection connection = JdbcUtil.getConnection();

        // 准备SQL语句
        // ? 表示SQL语句参数占位符!!!
        String sql = "insert into nzgp2001.user(id, userName, password) VALUE (?,?,?)";

        // 预处理SQL语句,获取PreparedStatement对象
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();

        // [重点]
        System.out.println("当前SQL语句的参数个数:"  + parameterMetaData.getParameterCount());
        JdbcUtil.close(connection, preparedStatement);
    }

    @Test
    public void resultMetaData() throws SQLException {
        // 获取数据库连接
        Connection connection = JdbcUtil.getConnection();

        // 准备SQL语句
        // ? 表示SQL语句参数占位符!!!
        String sql = "select * from user";

        // 预处理SQL语句,获取PreparedStatement对象
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        ResultSet resultSet = preparedStatement.executeQuery();

        ResultSetMetaData metaData = resultSet.getMetaData();

        // 查询结果集的字段个数
        int columnCount = metaData.getColumnCount();

        while (resultSet.next()) {
            for (int i = 1; i <= columnCount; i++) {
                // 字段名字
                String columnName = metaData.getColumnName(i);

                // 通过字段名从数据库结果集中读取对应字段的数据
                System.out.println(columnName + ":" + resultSet.getObject(columnName));
            }
        }
        // [重点]
        JdbcUtil.close(connection, preparedStatement, resultSet);
    }
}

1、链接数据库
使用数据库的元数据对象(DatabaseMetaData)连接的数据库,获取版本号。

package com.lpy.jdbc.metadata;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
public class Demo1 {
    public static void main(String[] args) throws Exception{
        ComboPooledDataSource ds=new ComboPooledDataSource();
        Connection conn=ds.getConnection();
        DatabaseMetaData dbmd=conn.getMetaData();
        System.out.println(dbmd.getDatabaseProductName());
        System.out.println(dbmd.getDatabaseMajorVersion());
        System.out.println(dbmd.getDatabaseMinorVersion());
        System.out.println(dbmd.getDriverMajorVersion());
        System.out.println(dbmd.getDriverName());
    }
}

2、预编译statement执行sql
使用参数元数据对象(ParameterMetaData)在预编译sql之后,知道预编译的sql有几个参数。

 private static void t1() throws SQLException {
        ComboPooledDataSource ds = new ComboPooledDataSource();
        Connection conn = ds.getConnection();
        String sql = "insert into employee(id,username,gender,birthday,email,age)VALUES (?,?,?,?,?,?)";
        PreparedStatement stmt = conn.prepareStatement(sql);
       /* stmt.setInt(1,1);
        stmt.setString(2,"lpy");
        stmt.setString(3,"男");
        stmt.setDate(4,new Date(new java.util.Date().getTime()));
        stmt.setString(5,"123");
        stmt.setInt(6,25);*/
        //参数元数据
        ParameterMetaData pmd = stmt.getParameterMetaData();
        //把参数放入数组
        Object[] values = new Object[]{2, "lpy", "男", new Date(new java.util.Date().getTime()), "@qq", 26};
        //得到sql中几个参数
        int count = pmd.getParameterCount();
        for (int i = 1; i <= count; i++) {
            stmt.setObject(i, values[i - 1]);
        }
        stmt.executeUpdate();
    }

3.执行查询sql,返回结果集
使用结果集元数据对象(ResultSetMetaData) ResultSet rs ,知道表的字段数和字段名称

  private static void t1() throws SQLException {
        ComboPooledDataSource ds = new ComboPooledDataSource();
        Connection conn = ds.getConnection();
        String sql = "SELECT *FROM stu where id=?";
        PreparedStatement stmt = conn.prepareStatement(sql);
        ParameterMetaData pm = stmt.getParameterMetaData();
        int count = pm.getParameterCount();
        Object[] values = new Object[]{2};
        for (int i = 1; i <= count; i++) {
            stmt.setObject(i, values[i - 1]);
        }
        ResultSet rs = stmt.executeQuery();
        ResultSetMetaData rsm = rs.getMetaData();
        int colcount = rsm.getColumnCount();
        while (rs.next()) {
            for (int i = 1; i <= colcount; i++) {
                Object value = rs.getObject(i);
                System.out.println(value);
            }
        }
    }

最后我们整理一个查询与更新的工具类

package com.lpy.jdbc.metadata;
 
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.beanutils.BeanUtils;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
 
public class SQLUtil {
    public static void update(String sql, Object[] values) {
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            Connection conn = ds.getConnection();
            PreparedStatement stmt = conn.prepareStatement(sql);
            ParameterMetaData pm = stmt.getParameterMetaData();
            int count = pm.getParameterCount();
            for (int i = 1; i <= count; i++) {
                stmt.setObject(i, values[i - 1]);
            }
            stmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public static <T>List<T> Query(String sql, Object[] values, Class<T> clazz) {
        try {
            List<T> list = new ArrayList<>();
            ComboPooledDataSource ds = new ComboPooledDataSource();
            Connection conn = ds.getConnection();
            PreparedStatement stmt = conn.prepareStatement(sql);
            ParameterMetaData pm = stmt.getParameterMetaData();
            int count = pm.getParameterCount();
            if (values != null) {
                for (int i = 1; i <= count; i++) {
                    stmt.setObject(i, values[i - 1]);
                }
            }
            ResultSet rs = stmt.executeQuery();
            ResultSetMetaData rsm = rs.getMetaData();
            int colcount = rsm.getColumnCount();
            while (rs.next()) {
                T obj = clazz.newInstance();
                for (int i = 1; i <= colcount; i++) {
                    Object value = rs.getObject(i);
                    String name = rsm.getColumnName(i);
                    BeanUtils.copyProperty(obj, name, value);
                }
                list.add(obj);
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}
发布了50 篇原创文章 · 获赞 13 · 访问量 2393

猜你喜欢

转载自blog.csdn.net/endless_Y/article/details/105088872