Spring Boot集成olingo快速入门demo

news2024/11/19 4:26:11

1.什么是olingo?

Apache Olingo 是个 Java 库,用来实现 Open Data Protocol (OData)。 Apache Olingo 包括服务客户端和 OData 服务器方面。

Open Data Protocol (开放数据协议,OData)

是用来查询和更新数据的一种Web协议,其提供了把存在于应用程序中的数据暴露出来的方式。OData运用且构建于很多 Web技术之上,比如HTTP、Atom Publishing Protocol(AtomPub)和JSON,提供了从各种应用程序、服务和存储库中访问信息的能力。OData被用来从各种数据源中暴露和访问信息, 这些数据源包括但不限于:关系数据库、文件系统、内容管理系统和传统Web站点。

2.代码工程

实验目标

利用olingo实现oData协议

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot-demo</artifactId>
        <groupId>com.et</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>olingo</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.olingo</groupId>
            <artifactId>olingo-odata2-core</artifactId>
            <version>2.0.11</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.ws.rs</groupId>
                    <artifactId>javax.ws.rs-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.olingo</groupId>
            <artifactId>olingo-odata2-jpa-processor-core</artifactId>
            <version>2.0.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.olingo</groupId>
            <artifactId>olingo-odata2-jpa-processor-ref</artifactId>
            <version>2.0.11</version>
            <exclusions>
                <exclusion>
                    <groupId>org.eclipse.persistence</groupId>
                    <artifactId>eclipselink</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jersey</artifactId>
        </dependency>


    </dependencies>
    <profiles>
        <profile>
            <id>local</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <activatedProperties>local</activatedProperties>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>com.h2database</groupId>
                    <artifactId>h2</artifactId>
                    <scope>runtime</scope>
                </dependency>
            </dependencies>
        </profile>

        <profile>
            <id>cloud</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <properties>
                <activatedProperties>cloud</activatedProperties>
            </properties>
        </profile>
    </profiles>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

config

package com.et.olingo.config;

import com.et.olingo.service.OdataJpaServiceFactory;
import org.apache.olingo.odata2.api.ODataServiceFactory;
import org.apache.olingo.odata2.core.rest.ODataRootLocator;
import org.apache.olingo.odata2.core.rest.app.ODataApplication;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.Path;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.ext.Provider;
import java.io.IOException;

@Component
@ApplicationPath("/odata")
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig(OdataJpaServiceFactory serviceFactory, EntityManagerFactory entityManagerFactory) {
        ODataApplication oDataApplication = new ODataApplication();
        oDataApplication
                .getClasses()
                .forEach( c -> {
                    if ( !ODataRootLocator.class.isAssignableFrom(c)) {
                        register(c);
                    }
                });
        register(new ODataServiceRootLocator(serviceFactory));
        register(new EntityManagerFilter(entityManagerFactory));
    }

    @Path("/")
    public static class ODataServiceRootLocator extends ODataRootLocator {

        private OdataJpaServiceFactory serviceFactory;

        @Inject
        public ODataServiceRootLocator (OdataJpaServiceFactory serviceFactory) {
            this.serviceFactory = serviceFactory;
        }

        @Override
        public ODataServiceFactory getServiceFactory() {
            return this.serviceFactory;
        }
    }

    @Provider
    public static class EntityManagerFilter implements ContainerRequestFilter,
            ContainerResponseFilter {
        public static final String EM_REQUEST_ATTRIBUTE =
                EntityManagerFilter.class.getName() + "_ENTITY_MANAGER";
        private final EntityManagerFactory entityManagerFactory;

        @Context
        private HttpServletRequest httpRequest;
        public EntityManagerFilter(EntityManagerFactory entityManagerFactory) {
            this.entityManagerFactory = entityManagerFactory;
        }

        @Override
        public void filter(ContainerRequestContext containerRequestContext) throws IOException {
            EntityManager entityManager = this.entityManagerFactory.createEntityManager();
            httpRequest.setAttribute(EM_REQUEST_ATTRIBUTE, entityManager);
            if (!"GET".equalsIgnoreCase(containerRequestContext.getMethod())) {
                entityManager.getTransaction().begin();
            }
        }
        @Override
        public void filter(ContainerRequestContext requestContext,
                           ContainerResponseContext responseContext) throws IOException {
            EntityManager entityManager = (EntityManager) httpRequest.getAttribute(EM_REQUEST_ATTRIBUTE);
            if (!"GET".equalsIgnoreCase(requestContext.getMethod())) {
                EntityTransaction entityTransaction = entityManager.getTransaction(); //we do not commit because it's just a READ
                if (entityTransaction.isActive() && !entityTransaction.getRollbackOnly()) {
                    entityTransaction.commit();
                }
            }
            entityManager.close();
        }
    }

}

controller

package com.et.olingo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class HelloWorldController {
    @RequestMapping("/hello")
    public Map<String, Object> showHelloWorld(){
        Map<String, Object> map = new HashMap<>();
        map.put("msg", "HelloWorld");
        return map;
    }
}

entity

138327882-76404655-f383-46e6-82af-677560b5ccee

service

package com.et.olingo.service;

import com.et.olingo.entity.Child;
import org.apache.olingo.odata2.api.edm.EdmException;
import org.apache.olingo.odata2.api.ep.EntityProviderException;
import org.apache.olingo.odata2.api.exception.ODataException;
import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
import org.apache.olingo.odata2.api.processor.ODataResponse;
import org.apache.olingo.odata2.api.uri.info.*;
import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
import org.apache.olingo.odata2.jpa.processor.api.ODataJPADefaultProcessor;
import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.util.List;

public class CustomODataJpaProcessor extends ODataJPADefaultProcessor {

    private Logger logger = LoggerFactory.getLogger(getClass());

    public CustomODataJpaProcessor(ODataJPAContext oDataJPAContext) {
        super(oDataJPAContext);
    }

    @Override
    public ODataResponse readEntitySet(final GetEntitySetUriInfo uriParserResultView, final String contentType) throws ODataJPAModelException, ODataJPARuntimeException, EdmException {
        logger.info("READ: Entity Set {} called", uriParserResultView.getTargetEntitySet().getName());
        try {
            List<Object> jpaEntities = jpaProcessor.process(uriParserResultView);
            return responseBuilder.build(uriParserResultView, jpaEntities, contentType);
        } finally {
            this.close();
        }
    }

    @Override
    public ODataResponse readEntity(final GetEntityUriInfo uriParserResultView, final String contentType) throws ODataJPAModelException, ODataJPARuntimeException, ODataNotFoundException, EdmException {
        ODataResponse response = null;
        if (uriParserResultView.getKeyPredicates().size() > 1) {
            logger.info("READ: Entity {} called with key {} and key {}", uriParserResultView.getTargetEntitySet().getName(), uriParserResultView.getKeyPredicates().get(0).getLiteral(), uriParserResultView.getKeyPredicates().get(1).getLiteral());
        } else {
            logger.info("READ: Entity {} called with key {}", uriParserResultView.getTargetEntitySet().getName(), uriParserResultView.getKeyPredicates().get(0).getLiteral());
        }
        try {
            Object readEntity = jpaProcessor.process(uriParserResultView);
            response = responseBuilder.build(uriParserResultView, readEntity, contentType);
        } finally {
            this.close();
        }
        return response;
    }

    @Override
    public ODataResponse createEntity(final PostUriInfo uriParserResultView, final InputStream content, final String requestContentType, final String contentType) throws ODataJPAModelException, ODataJPARuntimeException, ODataNotFoundException, EdmException, EntityProviderException {
        logger.info("POST: Entity {} called", uriParserResultView.getTargetEntitySet().getName());
        ODataResponse response = null;
        try {
            Object createdEntity = jpaProcessor.process(uriParserResultView, content, requestContentType);
            if (createdEntity.getClass().equals(Child.class)) {
                response = postProcessCreateChild(createdEntity, uriParserResultView, contentType);
            } else {
                response = responseBuilder.build(uriParserResultView, createdEntity, contentType);
            }
        } finally {
            this.close();
        }
        return response;
    }


    @Override
    public ODataResponse updateEntity(final PutMergePatchUriInfo uriParserResultView, final InputStream content,
                                      final String requestContentType, final boolean merge, final String contentType) throws ODataException, ODataJPAModelException, ODataJPARuntimeException, ODataNotFoundException {
        logger.info("PUT: Entity {} called with key {}", uriParserResultView.getTargetEntitySet().getName(), uriParserResultView.getKeyPredicates().get(0).getLiteral());
        ODataResponse response = null;
        try {
            Object updatedEntity = jpaProcessor.process(uriParserResultView, content, requestContentType);
            response = responseBuilder.build(uriParserResultView, updatedEntity);
        } finally {
            this.close();
        }
        return response;
    }

    @Override
    public ODataResponse deleteEntity(DeleteUriInfo uriParserResultView, String contentType) throws ODataException {
        logger.info("DELETE: Entity {} called with key {}", uriParserResultView.getTargetEntitySet().getName(), uriParserResultView.getKeyPredicates().get(0).getLiteral());
        ODataResponse oDataResponse = null;
        try {
            this.oDataJPAContext.setODataContext(this.getContext());
            Object deletedEntity = this.jpaProcessor.process(uriParserResultView, contentType);
            oDataResponse = this.responseBuilder.build(uriParserResultView, deletedEntity);
        } finally {
            this.close();
        }
        return oDataResponse;
    }

    private ODataResponse postProcessCreateChild(Object createdEntity, PostUriInfo uriParserResultView, String contentType) throws ODataJPARuntimeException, ODataNotFoundException {
        Child child = (Child) createdEntity;
        if (child.getSurname() == null || child.getSurname().equalsIgnoreCase("")) {
            if (child.getMother().getSurname() != null && !child.getMother().getSurname().equalsIgnoreCase("")) {
                child.setSurname(child.getMother().getSurname());
            } else if (child.getMother().getSurname() != null && !child.getFather().getSurname().equalsIgnoreCase("")) {
                child.setSurname(child.getFather().getSurname());
            } else {
                child.setSurname("Gashi");
            }
        }
        return responseBuilder.build(uriParserResultView, createdEntity, contentType);
    }

}
package com.et.olingo.service;

import com.et.olingo.config.JerseyConfig;
import org.apache.olingo.odata2.api.ODataService;
import org.apache.olingo.odata2.api.ODataServiceFactory;
import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
import org.apache.olingo.odata2.api.exception.ODataException;
import org.apache.olingo.odata2.api.processor.ODataContext;
import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
import org.apache.olingo.odata2.jpa.processor.api.factory.ODataJPAAccessFactory;
import org.apache.olingo.odata2.jpa.processor.api.factory.ODataJPAFactory;

import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;

public class CustomODataServiceFactory extends ODataServiceFactory {

    private ODataJPAContext oDataJPAContext;
    private ODataContext oDataContext;

    @Override
    public final ODataService createService(final ODataContext context) throws ODataException {
        oDataContext = context;
        oDataJPAContext = initializeODataJPAContext();

        validatePreConditions();

        ODataJPAFactory factory = ODataJPAFactory.createFactory();
        ODataJPAAccessFactory accessFactory = factory.getODataJPAAccessFactory();

        if (oDataJPAContext.getODataContext() == null) {
            oDataJPAContext.setODataContext(context);
        }

        ODataSingleProcessor oDataSingleProcessor = new CustomODataJpaProcessor(
                oDataJPAContext
        );


        EdmProvider edmProvider = accessFactory.createJPAEdmProvider(oDataJPAContext);
        return createODataSingleProcessorService(edmProvider, oDataSingleProcessor);

    }

    private void validatePreConditions() throws ODataJPARuntimeException {
        if (oDataJPAContext.getEntityManager() == null) {
            throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.ENTITY_MANAGER_NOT_INITIALIZED, null);
        }
    }

    public final ODataJPAContext getODataJPAContext()
            throws ODataJPARuntimeException {
        if (oDataJPAContext == null) {
            oDataJPAContext = ODataJPAFactory.createFactory()
                    .getODataJPAAccessFactory().createODataJPAContext();
        }
        if (oDataContext != null)
            oDataJPAContext.setODataContext(oDataContext);
        return oDataJPAContext;

    }

    protected ODataJPAContext initializeODataJPAContext() throws ODataJPARuntimeException {
        ODataJPAContext oDataJPAContext = this.getODataJPAContext();
        ODataContext oDataContext = oDataJPAContext.getODataContext();


        HttpServletRequest request = (HttpServletRequest) oDataContext.getParameter(
                ODataContext.HTTP_SERVLET_REQUEST_OBJECT);
        EntityManager entityManager = (EntityManager) request
                .getAttribute(JerseyConfig.EntityManagerFilter.EM_REQUEST_ATTRIBUTE);
        oDataJPAContext.setEntityManager(entityManager);


        oDataJPAContext.setPersistenceUnitName("default");
        oDataJPAContext.setContainerManaged(true);
        return oDataJPAContext;
    }
}
package com.et.olingo.service;

import org.springframework.stereotype.Component;

@Component
public class OdataJpaServiceFactory extends CustomODataServiceFactory {
    //need this wrapper class for the spring framework, otherwise we face issues when auto wiring directly the CustomODataServiceFactory
}

application.yaml

spring.h2.console.enabled=true
spring.h2.console.path=/console

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

  • GitHub - Harries/springboot-demo: a simple springboot demo with some components for example: redis,solr,rockmq and so on.

3.测试

启动spring Boot应用

元数据查看

http://localhost:8080/odata/$metadata

138900236-f6ba4cca-c3e4-49ea-97c3-e80e5835aa7d

插入

167310946-febc1bc1-e898-4d31-aa94-efb423e69d1d

查询

167310988-142c61c2-49ab-487d-927e-0f6edd1e6376

4.引用

  • https://github.com/ECasio/olingo-spring-example
  • Apache Olingo Library
  • Spring Boot集成olingo快速入门demo | Harries Blog™

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1900017.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

不要再盲目入场啦!跨境电商入场第一步!先收集整理这些数据,看清自己该如何入场!【纯分享】

23年、24年确实无愧于“品牌出海元年”的称号&#xff0c;23年出海四小龙——速卖通、TikTokshop、Temu、Shein在海外的爆发让大家看到了海外市场的活动&#xff1b;而24年则有更多的国内品牌将目光瞄向了海外市场&#xff0c;年后开工到今天基本上每天都有客户来咨询出海相关的…

Java应用系统设计与实现--学生信息管理系统(附解决方案源码)

一、实验目的及要求 1.1实验目的 掌握Java GUI编程技术&#xff0c;了解Swing框架的使用。 掌握MySQL数据库的基本操作&#xff0c;了解如何在Java中连接和操作数据库。 掌握用户权限管理的基本概念和实现方法。 提升综合运用所学知识设计和实现一个完整应用系统的能力…

hid-ft260驱动学习笔记 1 - 驱动模块注册与注销

目录 1. ft260_driver_init初始化 1.1 tty设备 1.1.1 申请tty驱动设备 1.1.2 初始化tty驱动程序 1.1.3 注册tty设备 1.2 hid设备 2. ft260_driver_exit注销模块 3. 调试 hid-ft260.c的最底部可以看到该驱动的注册与注销接口的申明。 module_init(ft260_driver_init); …

Nifi脚本组件ExecuteScript 的使用(一)

ExecuteScript 组件的基本使用 前面已经介绍过Nifi中基本的数据流程&#xff0c;这里介绍一下最为常用的一个组件&#xff0c;ExecuteScript processor&#xff0c;顾名思义ExecuteScript组件是一组以自定义脚本为主体的组件&#xff0c;意思就是&#xff0c;可以在该组件内部…

如何使用特殊的参数和符号来改变图像的风格、质量、比例

🪂🌹 /imagine prompt: 一朵白色的花,透明的花瓣,深如海水,晶莹剔透+露珠,8K,HD,常春藤,花卉,热带植物 --v 5 --ar 2:1 --c 80 --s 500 -v 5切换模型版本5--ar 2:1宽高比例为2:1--c 80混沌值为80--s 500样式值为500🧑🏼‍🎨Midjourney 动漫和插画风格 🌹…

Java视频点播网站

作者介绍&#xff1a;计算机专业研究生&#xff0c;现企业打工人&#xff0c;从事Java全栈开发 主要内容&#xff1a;技术学习笔记、Java实战项目、项目问题解决记录、AI、简历模板、简历指导、技术交流、论文交流&#xff08;SCI论文两篇&#xff09; 上点关注下点赞 生活越过…

Redis的八种数据类型介绍

Redis 是一个高性能的键值存储&#xff0c;它支持多种丰富的数据类型。每种数据类型都有其特定的用途和底层实现。下面我将介绍 Redis 支持的主要数据类型及其背后的数据结构。 本人这里还有几篇详细的Redis用法文章&#xff0c;可以用来进阶康康&#xff01; 1. 字符串 (Stri…

Python数据分析-分子数据分析和预测

一、设计背景 分子结构设计与性质计算对研发新型高能量密度材料具有重要意义。机器学习作为一种大数据计算模型&#xff0c;可以避免复杂、危险的实验&#xff0c;大幅提高研发效率、降低设计和计算成本。本文基于机器学习的方法以及通过构建神经网络&#xff0c;实现对高能量…

网络基础:IS-IS协议

IS-IS&#xff08;Intermediate System to Intermediate System&#xff09;是一种链路状态路由协议&#xff0c;最初由 ISO&#xff08;International Organization for Standardization&#xff09;为 CLNS&#xff08;Connectionless Network Service&#xff09;网络设计。…

TP8/6 子域名绑定应用

原www.xxx.com/admin改为admincms.xxx.com config/app.php 官方文档&#xff1a;ThinkPHP官方手册

fastadmin 如何给页面添加水印

偶然发现fastadmin框架有个水印插件&#xff0c;看起来漂亮&#xff0c;就想也实现这样的功能&#xff0c;看到需要费用。但是现成的插件需要费用&#xff0c;自己动手丰衣足食。说干就干。 1. 找到watermark.js &#xff0c;放到assets/js/ 下面 2.具体页面引入 <script…

基于单片机的粉尘检测报警防护系统研究

摘要 &#xff1a; 粉尘检测是环境保护的重要环节&#xff0c;传统的粉尘检测防护系统的预防方式较为单一。本文设计了一种基于单片机的粉尘检测报警防护系统&#xff0c;能有效地检测粉尘浓度&#xff0c;进行多种方式的报警防护&#xff0c;以保证工作人员的生命健康和安全。…

平价猫粮新选择!福派斯鲜肉猫粮,让猫咪享受美味大餐!

福派斯鲜肉猫粮&#xff0c;作为一款备受铲屎官们青睐的猫粮品牌&#xff0c;凭借其卓越的品质和高性价比&#xff0c;为众多猫主带来了健康与美味的双重享受。接下来&#xff0c;我们将从多个维度对这款猫粮进行解析&#xff0c;让各位铲屎官更加全面地了解它的魅力所在。 1️…

强大的文档编辑工具——坤Tools正式版 V0.4.4【免费的Word转PDF、PDF转Word、替换内容、转换图片、合并图片工具】

在这个信息爆炸的时代&#xff0c;我们每个人都像是一名勇敢的探险家&#xff0c;在茫茫的数据海洋中寻找着属于自己的宝藏。 软件链接&#xff1a;吾爱原创 | 全功能批量处理器&#xff0c;绿色版本&#xff01; 今天给大家带来一款功能强大的文档编辑工具——坤Tools正式版…

孙溟㠭篆刻《睡片原谅一切,醒来不问过往》

孙溟㠭篆刻《睡片原谅一切&#xff0c;醒来不问过往》 佛陀言&#xff1a;睡前原谅一切&#xff0c;醒来不问过往&#xff0c;珍惜所有不期而遇&#xff0c;看淡所有不辞而别甲辰夏溟㠭于寒舍小窗下刊。

Hadoop-15-Hive 元数据管理与存储 Metadata 内嵌模式 本地模式 远程模式 集群规划配置 启动服务 3节点云服务器实测

章节内容 上一节我们完成了&#xff1a; Hive中数据导出&#xff1a;HDFSHQL操作上传内容至Hive、增删改查等操作 背景介绍 这里是三台公网云服务器&#xff0c;每台 2C4G&#xff0c;搭建一个Hadoop的学习环境&#xff0c;供我学习。 之前已经在 VM 虚拟机上搭建过一次&am…

KIVY 3D Rotating Monkey Head¶

3D Rotating Monkey Head — Kivy 2.3.0 documentation KIVY 3D Rotating Monkey Head kivy 3D 旋转猴子头 This example demonstrates using OpenGL to display a rotating monkey head. This includes loading a Blender OBJ file, shaders written in OpenGL’s Shading…

机器学习筑基篇,​Ubuntu 24.04 快速安装 PyCharm IDE 工具,无需激活!

[ 知识是人生的灯塔&#xff0c;只有不断学习&#xff0c;才能照亮前行的道路 ] Ubuntu 24.04 快速安装 PyCharm IDE 工具 描述&#xff1a;虽然在之前我们安装了VScode&#xff0c;但是其对于使用Python来写大型项目以及各类配置还是比较复杂的&#xff0c;所以这里我们还是推…

docker buildx 交叉编译设置

dockerd配置文件 /etc/docker/daemon.json设置&#xff1a; rootubuntu:/etc/docker# cat daemon.json {"insecure-registries":["localhost:5000","127.0.0.1:5000","172.16.67.111:5000"],"features": {"buildkit&…

三、数据库系统(考点篇)

1、三级模式一两级映像 内模式&#xff1a;管理如何存储物理的 数据 &#xff0c;对数据的存储方式、优化、存放等。 模式&#xff1a;又称为概念模式&#xff0c; 就是我们通常使用的表这个级别 &#xff0c;根据应用、需求将物理数据划分成一 张张表。 外模式&#xff1a;…