MetaModel元数据模型-初识

一、前言

1.简介

MetaModel 是用来重建 SQL 99 兼容的数据库元模型。
MetaModel 提供了一个数据为中心的 API 用于探索、查询和更新数据,数据格式支持关系数据库(JDBC)、CSV 文件、Excel 表格、MongoDB 和 CouchDB 等等。你可以编写真正跨存储系统的应用程序。
此外 MetaModel 的 API 非常易学易用,类似于 SQL 语法,但是类型安全的,你可以把它想象成 LinQ for Java。

2.文档

METAMODEL WIKI

Datastore typeDataContext class nameProperties “type” valueVariants supported/available
JDBC / Relational DatabasesJdbcDataContextjdbcPostgreSQL, MySQL, Microsoft SQL Server, Oracle DB, IBM DB2 Apache Hive, Apache Derby, SQLite, Ingres, H2, HSQLDB (… and many more)
CSV filesCsvDataContextcsvComma-separated Tab-separated Anything-separated files
Fixed width value filesFixedWidthDataContextfixed-widthFixed width EBCDIC
Microsoft Excel spreadsheetsExcelDataContextexcel.xls .xlsx
Microsoft Access database filesAccessDataContext-.mdb .accdb
OpenOffice.org database filesOpenOfficeDataContext-.odb
XML filesXmlDomDataContext XmlSaxDataContext xmlDOM-based parsing (all in-memory) SAX-based parsing (streaming)
JSON filesJsonDataContextjson
ElasticSearchElasticSearchDataContext ElasticSearchRestDataContextelasticsearchNative Java API RESTful JSON API
MongoDBMongoDbDataContext-MongoDB 2.x MongoDB 3.x
Apache CouchDBCouchDbDataContextcouchdb
Apache CassandraCassandraDataContextcassandra
Apache HBaseHBaseDataContexthbase
Apache KafkaKafkaDataContext
Neo4jNeo4jDataContext-
Salesforce.comSalesforceDataContextsalesforce
SugarCRMSugarCrmDataContext-
Java collectionsPojoDataContextpojoCollection<Object[]> Collection<Map<String, Object>> Collection<JavaBean>
Collections of other datastoresCompositeDataContext

二、集成

        <dependency>
            <groupId>org.apache.metamodel</groupId>
            <artifactId>MetaModel-full</artifactId>
            <version>5.3.3</version>
        </dependency>

三、使用示例

gitee源码:https://gitee.com/ryou5416/meta-model.git

1.CsvTest

package com.example.metamodel;

import org.apache.metamodel.DataContext;
import org.apache.metamodel.UpdateableDataContext;
import org.apache.metamodel.csv.CsvConfiguration;
import org.apache.metamodel.csv.CsvDataContext;
import org.apache.metamodel.data.DataSet;
import org.apache.metamodel.factory.DataContextFactoryRegistryImpl;
import org.apache.metamodel.factory.DataContextPropertiesImpl;
import org.apache.metamodel.factory.ResourceFactory;
import org.apache.metamodel.insert.InsertInto;
import org.apache.metamodel.query.CompiledQuery;
import org.apache.metamodel.query.Query;
import org.apache.metamodel.query.QueryParameter;
import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.schema.TableType;
import org.apache.metamodel.util.AbstractResource;
import org.apache.metamodel.util.ClasspathResource;
import org.apache.metamodel.util.FileResource;
import org.apache.metamodel.util.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.util.Assert;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.List;

import static org.apache.metamodel.factory.DataContextPropertiesImpl.*;

/**
 * @author :ouruyi
 * @version 1.0
 * @date :Created in 2021/7/5 14:56
 * 功能描述:
 */
public class CsvTest {

    @Test
    void test1() {
        /**
         * 可设置表定义 {@link DataContextPropertiesImpl#PROPERTY_TABLE_DEFS}
         */
        final DataContextPropertiesImpl properties = new DataContextPropertiesImpl();
        properties.put(PROPERTY_DATA_CONTEXT_TYPE, "csv");
        properties.put(PROPERTY_COLUMN_NAME_LINE_NUMBER, 1);
        /**
         * 可用前缀 file classpath mem http https hdfs
         * @see ResourceFactory
         */
        properties.put(PROPERTY_RESOURCE_PROPERTIES, "classpath:/data/csv/data.csv");
        DataContext dataContext = DataContextFactoryRegistryImpl.getDefaultInstance().createDataContext(properties);
        final Schema schema = dataContext.getDefaultSchema();
        final List<Table> tables = schema.getTables(TableType.TABLE);
        final Table table = tables.get(0);
        DataSet result = dataContext.query().from(table).select(table.getColumns()).orderBy(table.getColumnByName("name")).execute();
        try {
            while (result.next()) {
                System.out.println("Row: " + Arrays.toString(result.getRow().getValues()));
            }
        } finally {
            result.close();
        }
    }

    @Test
    void test2() {
        /**
         * @see AbstractResource
         */
        Resource resource = new ClasspathResource("/data/csv/data.csv");
        Assert.isTrue(resource.isExists(), "文件不存在!");
        /**
         * 可设置表定义 {@link org.apache.metamodel.schema.naming.CustomColumnNamingStrategy#CustomColumnNamingStrategy(java.lang.String...)}
         */
        CsvConfiguration configuration = new CsvConfiguration(1, "UTF-8", ',', '"', '\\');
        DataContext dataContext = new CsvDataContext(resource, configuration);
        final Schema schema = dataContext.getDefaultSchema();
        final List<Table> tables = schema.getTables(TableType.TABLE);
        final Table table = tables.get(0);
        DataSet result = dataContext.query().from(table).select(table.getColumns()).orderBy(table.getColumnByName("name")).execute();
        try {
            while (result.next()) {
                System.out.println("Row: " + Arrays.toString(result.getRow().getValues()));
            }
        } finally {
            result.close();
        }
    }

    /**
     * 绑定变量 降低语法解析次数,提升性能及安全性
     */
    @Test
    void test3() {
        /**
         * @see AbstractResource
         */
        Resource resource = new ClasspathResource("/data/csv/data.csv");
        Assert.isTrue(resource.isExists(), "文件不存在!");
        /**
         * 可设置表定义 {@link org.apache.metamodel.schema.naming.CustomColumnNamingStrategy#CustomColumnNamingStrategy(java.lang.String...)}
         */
        CsvConfiguration configuration = new CsvConfiguration(1, "UTF-8", ',', '"', '\\');
        DataContext dataContext = new CsvDataContext(resource, configuration);
        final Schema schema = dataContext.getDefaultSchema();
        final Table table = schema.getTableByName("default_table");
        final Query query = dataContext
                .query()
                .from(table)
                .select(table.getColumns())
                .where("name").eq(new QueryParameter())
                .orderBy(table.getColumnByName("name"))
                .toQuery();
        /**
         * SELECT default_table.age FROM csv.default_table WHERE data.csv.name = ? ORDER BY data.csv.name ASC
         * data.csv tableName
         * csv scheme
         * default_table 别名
         */
        System.out.println(query);
        // 预编译 类似于jdbc prepareStatement,对于JdbcDataContext,内部确实用的是prepareStatement(适配器模式)
        CompiledQuery compiledQuery = dataContext.compileQuery(query);
        try (DataSet result = dataContext.executeQuery(compiledQuery, "jan")) {
            while (result.next()) {
                System.out.println("Row: " + Arrays.toString(result.getRow().getValues()));
            }
        }
    }

    /**
     * 更新数据
     * 注意:ClasspathResource默认“只读”(不推荐)
     */
    @Test
    void update() throws FileNotFoundException {
        final File file = ResourceUtils.getFile("classpath:data/csv/data.csv");
        Resource resource= new FileResource(file);
        Assert.isTrue(resource.isExists(), "文件不存在!");
        CsvConfiguration configuration = new CsvConfiguration(1, "UTF-8", ',', '"', '\\');
        UpdateableDataContext dataContext = new CsvDataContext(resource, configuration);
        final Schema schema = dataContext.getDefaultSchema();
        final Table table = schema.getTableByName("data.csv");
        // 写入target/classes/data/csv/data.csv
        dataContext.executeUpdate(new InsertInto(table).value("name", "Polly the Sheep").value("age", 10));
        dataContext.executeUpdate(callback -> {
            callback.insertInto(table).value("name", "Polly the Sheep").value("age", 10).execute();
            callback.update(table).where("name").eq("Polly the Sheep").value("age", 20).execute();
            callback.deleteFrom(table).where("name").eq("Polly the Sheep").execute();
        });
        /**
         * https://cwiki.apache.org/confluence/display/METAMODEL/UpdateableDataContext
         * 下面语句要单独写才可以删除掉记录?
         */
        dataContext.executeUpdate(callback -> callback.deleteFrom(table).where("name").eq("Polly the Sheep").execute());
    }



}

2.JdbcTest

package com.example.metamodel;

import org.apache.metamodel.DataContext;
import org.apache.metamodel.data.DataSet;
import org.apache.metamodel.factory.DataContextFactoryRegistryImpl;
import org.apache.metamodel.factory.DataContextPropertiesImpl;
import org.apache.metamodel.jdbc.JdbcDataContext;
import org.apache.metamodel.query.Query;
import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.schema.TableType;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;

import javax.sql.DataSource;
import java.util.Arrays;

import static org.apache.metamodel.factory.DataContextPropertiesImpl.*;

/**
 * @author :ouruyi
 * @version 1.0
 * @date :Created in 2021/7/5 14:42
 * 功能描述:
 */
@SpringBootTest
public class JdbcTest {

    @javax.annotation.Resource
    Environment environment;

    @javax.annotation.Resource
    DataSource dataSource;

    @Test
    void test1() {
        final DataContextPropertiesImpl properties = new DataContextPropertiesImpl();
        properties.put(PROPERTY_DATA_CONTEXT_TYPE, "jdbc");
        properties.put(PROPERTY_URL, environment.getProperty("spring.datasource.url"));
        properties.put(PROPERTY_USERNAME, environment.getProperty("spring.datasource.username"));
        properties.put(PROPERTY_PASSWORD, environment.getProperty("spring.datasource.password"));
        properties.put(PROPERTY_TABLE_TYPES, new TableType[]{TableType.TABLE, TableType.VIEW});
        DataContext dataContext = DataContextFactoryRegistryImpl.getDefaultInstance().createDataContext(properties);
        final Schema schema = dataContext.getDefaultSchema();
        final Table user = schema.getTableByName("USER");
        final Query query = dataContext.query().from(user).select(user.getColumns()).toQuery();
        try (final DataSet result = dataContext.executeQuery(query)) {
            while (result.next()) {
                System.out.println("Row: " + Arrays.toString(result.getRow().getValues()));
            }
        }

    }

    @Test
    void test2() {
        final JdbcDataContext dataContext = new JdbcDataContext(dataSource);
        final Schema schema = dataContext.getDefaultSchema();
        final Table user = schema.getTableByName("USER");
        final Query query = dataContext.query().from(user).select(user.getColumns()).toQuery();
        try (final DataSet result = dataContext.executeQuery(query)) {
            while (result.next()) {
                System.out.println("Row: " + Arrays.toString(result.getRow().getValues()));
            }
        }

    }

}

3.JsonTest

package com.example.metamodel;

import cn.hutool.core.io.FileUtil;
import org.apache.metamodel.DataContext;
import org.apache.metamodel.data.DataSet;
import org.apache.metamodel.factory.DataContextFactoryRegistryImpl;
import org.apache.metamodel.factory.DataContextPropertiesImpl;
import org.apache.metamodel.json.JsonDataContext;
import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.schema.TableType;
import org.apache.metamodel.util.ClasspathResource;
import org.apache.metamodel.util.InMemoryResource;
import org.apache.metamodel.util.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.util.Assert;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;

import static org.apache.metamodel.factory.DataContextPropertiesImpl.PROPERTY_DATA_CONTEXT_TYPE;
import static org.apache.metamodel.factory.DataContextPropertiesImpl.PROPERTY_RESOURCE_PROPERTIES;

/**
 * @author :ouruyi
 * @version 1.0
 * @date :Created in 2021/7/5 14:42
 * 功能描述:
 */
public class JsonTest {

    @Test
    void test1() {
        final DataContextPropertiesImpl properties = new DataContextPropertiesImpl();
        properties.put(PROPERTY_DATA_CONTEXT_TYPE, "json");
        properties.put(PROPERTY_RESOURCE_PROPERTIES, "classpath:/data/json/data.json");
        DataContext dataContext = DataContextFactoryRegistryImpl.getDefaultInstance().createDataContext(properties);
        final Schema schema = dataContext.getDefaultSchema();
        final List<Table> tables = schema.getTables(TableType.TABLE);
        final Table table = tables.get(0);
        DataSet result = dataContext.query().from(table).select(table.getColumns()).orderBy(table.getColumnByName("name")).execute();
        try {
            while (result.next()) {
                System.out.println("Row: " + Arrays.toString(result.getRow().getValues()));
            }
        } finally {
            result.close();
        }

    }

    @Test
    void test2() {
        Resource resource = new ClasspathResource("/data/json/data.json");
        Assert.isTrue(resource.isExists(), "文件不存在!");
        final JsonDataContext dataContext = new JsonDataContext(resource);
        final Schema schema = dataContext.getDefaultSchema();
        final List<Table> tables = schema.getTables(TableType.TABLE);
        final Table table = tables.get(0);
        DataSet result = dataContext.query().from(table).select(table.getColumns()).orderBy(table.getColumnByName("name")).execute();
        try {
            while (result.next()) {
                System.out.println("Row: " + Arrays.toString(result.getRow().getValues()));
            }
        } finally {
            result.close();
        }
    }

    @Test
    void test3() throws IOException {
        byte[] bytes = FileUtil.readBytes("data/json/data.json");
        Resource resource = new InMemoryResource("/data/json/data.json");
        try (final OutputStream outputStream = resource.write()) {
            outputStream.write(bytes);
            /**
             * 请务必调用该方法
             * @see org.apache.metamodel.util.InMemoryResource#createOutputStream(boolean)
             */
            outputStream.flush();
        }
        final JsonDataContext dataContext = new JsonDataContext(resource);
        final Schema schema = dataContext.getDefaultSchema();
        final List<Table> tables = schema.getTables(TableType.TABLE);
        final Table table = tables.get(0);
        System.out.println(table.getColumns());
        DataSet result = dataContext.query().from(table).select(table.getColumns()).execute();
        try {
            while (result.next()) {
                System.out.println("Row: " + Arrays.toString(result.getRow().getValues()));
            }
        } finally {
            result.close();
        }
    }


}

4.XmlTest

package com.example.metamodel;

import org.apache.metamodel.data.DataSet;
import org.apache.metamodel.query.Query;
import org.apache.metamodel.schema.Column;
import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.util.ClasspathResource;
import org.apache.metamodel.util.Resource;
import org.apache.metamodel.xml.XmlSaxDataContext;
import org.apache.metamodel.xml.XmlSaxTableDef;
import org.junit.jupiter.api.Test;
import org.springframework.util.Assert;

import java.util.Arrays;

/**
 * @author :ouruyi
 * @version 1.0
 * @date :Created in 2021/7/5 14:42
 * 功能描述:推荐使用XmlSaxDataContext,官方已不再建议使用XmlDomDataContext
 */
public class XmlTest {

    @Test
    void test1() {

    }

    @Test
    void test2() {
        Resource resource = new ClasspathResource("/data/xml/data.xml");
        Assert.isTrue(resource.isExists(), "文件不存在!");

        XmlSaxTableDef employeeTableDef = new XmlSaxTableDef(
                "/root/organization/employees/employee",
                new String[] {
                        "/root/organization/employees/employee/name",
                        "/root/organization/employees/employee/gender",
                        "index(/root/organization)"
                }
        );

        XmlSaxTableDef organizationTableDef = new XmlSaxTableDef(
                "/root/organization",
                new String[] {
                        "/root/organization/name",
                        "/root/organization@type"
                }
        );

        final XmlSaxDataContext dataContext = new XmlSaxDataContext(resource, employeeTableDef, organizationTableDef);
        final Schema schema = dataContext.getDefaultSchema();
        System.out.println(schema.getTableNames());
        final Table organizationTable = schema.getTableByName("/organization");
        final Table employeeTable = schema.getTableByName("/employee");

        Column fk = employeeTable.getColumnByName("index(/root/organization)");


        Column empName = employeeTable.getColumnByName("/name");
        Column gender = employeeTable.getColumnByName("/gender");
        Column orgId = organizationTable.getColumnByName("row_id");
        Column orgName = organizationTable.getColumnByName("/name");

        Query q = dataContext.query().from(employeeTable)
                .innerJoin(organizationTable).on(fk, orgId)
                .select(empName).as("employee")
                .select(gender).as("gender")
                .select(orgName).as("company").toQuery();


        try (DataSet result = dataContext.executeQuery(q)) {
            while (result.next()) {
                System.out.println("Row: " + Arrays.toString(result.getRow().getValues()));
            }
        }

    }

    @Test
    void test3() {
        Resource resource = new ClasspathResource("/data/xml/data.xml");
        Assert.isTrue(resource.isExists(), "文件不存在!");

        XmlSaxTableDef tableDef = new XmlSaxTableDef(
                "/root/organization/employees/employee",
                new String[] {
                        "/root/organization/employees/employee/name",
                        "/root/organization/employees/employee/gender"
                }
        );

        final XmlSaxDataContext dataContext = new XmlSaxDataContext(resource, tableDef);
        final Schema schema = dataContext.getDefaultSchema();
        final Table table = schema.getTableByName("/employee");

        Query q = dataContext.query().from(table)
                .select(table.getColumns()).toQuery();


        try (DataSet result = dataContext.executeQuery(q)) {
            while (result.next()) {
                System.out.println("Row: " + Arrays.toString(result.getRow().getValues()));
            }
        }

    }



}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: CWM(Common Warehouse Metamodel)是一种元数据模型,它为数据仓库和商业智能系统的元数据提供了一种标准化的、综合性的描述方式。CWM包含了一系列的规范和元模型,其中核心内容主要包括以下几个方面。 首先,CWM定义了一套通用的元模型,用于描述与数据仓库和商业智能系统相关的元数据。这些元模型包括了数据仓库中的各种对象,例如维度、事实表、数据库表等,以及它们之间的关系和属性。通过这些通用的元模型,CWM提供了一种统一的、标准化的元数据描述方法,使得不同数据仓库和商业智能系统之间的元数据可以互相理解和交换。 其次,CWM定义了一组通用的元模型操作,用于对元数据进行管理和操作。这些操作包括元数据的创建、修改、查询、删除等,以及元数据之间的关联和依赖关系的管理。通过这些操作,CWM提供了对元数据的全生命周期管理,使得元数据可以在不同的环境中被有效地管理和利用。 另外,CWM还定义了一套元数据交换格式,用于在不同的数据仓库和商业智能系统之间进行元数据的交换和共享。这个交换格式基于XML技术,以一种结构化的方式描述了元数据的各个方面,包括对象的定义、属性的定义、关系和依赖关系等。通过这个元数据交换格式,CWM使得不同系统之间的元数据可以方便地进行交换和共享,从而实现了元数据的互操作性和可移植性。 总之,CWM是一种元数据模型,它提供了一套通用的、标准化的方法和规范,用于描述和管理数据仓库和商业智能系统的元数据。CWM的核心内容包括元模型、元模型操作和元数据交换格式,通过这些内容,CWM实现了对元数据的一致性管理和跨系统的元数据交换与共享。 ### 回答2: CWM(Common Warehouse Metamodel)即通用仓库元模型,是一种用于描述数据仓库和商业智能系统元数据模型。CWM的核心内容包括以下几个方面: 1. 元对象模型(MOF):CWM使用统一的元对象模型来描述元数据,并定义了一系列元对象类型和关联关系。这样可以确保不同数据仓库和商业智能系统之间的元数据互操作性,提供了一个标准的元数据描述和交换方式。 2. 元数据仓库:CWM提供了一种标准的元数据仓库模型,用于存储和管理数据仓库和商业智能系统中的元数据。元数据仓库可以为用户和应用程序提供统一的元数据访问接口,便于元数据的查询、更新和管理。 3. 共享元数据:CWM通过定义元数据模型、元数据交换格式和元数据接口等标准,可以实现不同数据仓库和商业智能系统之间的元数据共享。这样可以提高元数据的一致性和可重用性,减少系统集成和维护的成本。 4. 元数据管理:CWM提供了一套元数据管理的方法和工具,包括元数据的采集、存储、更新和删除等操作。元数据管理可以帮助用户和管理员对元数据进行有效的管理和控制,保证数据仓库和商业智能系统的正常运行。 总之,CWM是一种用于描述数据仓库和商业智能系统中元数据模型,包括元对象模型、元数据仓库、共享元数据和元数据管理等核心内容。它提供了一套标准的元数据描述和交换方式,可以提高元数据的一致性和可重用性,简化系统集成和维护的工作。 ### 回答3: CWM(Common Warehouse Metamodel)是一种用于数据仓库和商业智能系统的元数据模型。它为数据仓库提供了一个统一的元数据定义和管理框架,以支持数据的集成、转换和利用。 CWM的核心内容包括以下几个方面: 1. 元模型Metamodel):CWM定义了一系列的元模型,用于描述数据仓库中的各种数据、元数据和它们之间的关系。这些元模型包括了范围从数据项、数据集合、元数据容器到模式、模型和对象的抽象层次。通过元模型,CWM提供了一种可扩展和可移植的元数据管理架构。 2. 元对象(Metaclass):CWM定义了多种元对象,用于表示元数据中的各种对象和概念,如数据表、列、索引、视图、数据仓库、数据源等。每个元对象都有一组属性和关系来描述它们的特性和关联。 3. 元属性(Metaproperty):CWM定义了一系列元属性,用于描述元对象的属性,如数据类型、长度、精度等。通过元属性,CWM可以对元对象的特性进行描述和约束。 4. 元关联(Metaassociation):CWM定义了元关联,用于描述元对象之间的关系和联接。元关联可以用于建立数据仓库中数据项、数据集合之间的关联关系,以支持数据的集成和查询。 CWM的核心内容还包括了用于数据转换、集成、查询、分析和数据挖掘的相关模型和技术,如ETL(Extract, Transform, Load)、OLAP(Online Analytical Processing)、数据挖掘、模型驱动开发等。 总的来说,CWM作为一个元数据模型,提供了一种标准化的元数据管理方式,用于描述和管理数据仓库中的各种数据和元数据。它为数据仓库的设计、开发、维护和利用提供了一种统一的框架和方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬山境KL攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值