Spring Boot集成olingo快速入门demo
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;@Injectpublic ODataServiceRootLocator (OdataJpaServiceFactory serviceFactory) {this.serviceFactory = serviceFactory;}@Overridepublic ODataServiceFactory getServiceFactory() {return this.serviceFactory;}}@Providerpublic static class EntityManagerFilter implements ContainerRequestFilter,ContainerResponseFilter {public static final String EM_REQUEST_ATTRIBUTE =EntityManagerFilter.class.getName() + "_ENTITY_MANAGER";private final EntityManagerFactory entityManagerFactory;@Contextprivate HttpServletRequest httpRequest;public EntityManagerFilter(EntityManagerFactory entityManagerFactory) {this.entityManagerFactory = entityManagerFactory;}@Overridepublic 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();}}@Overridepublic 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 READif (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
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);}@Overridepublic 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();}}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;@Overridepublic 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
插入
查询
4.引用
- https://github.com/ECasio/olingo-spring-example
- Apache Olingo Library
- Spring Boot集成olingo快速入门demo | Harries Blog™
相关文章:

Spring Boot集成olingo快速入门demo
1.什么是olingo? Apache Olingo 是个 Java 库,用来实现 Open Data Protocol (OData)。 Apache Olingo 包括服务客户端和 OData 服务器方面。 Open Data Protocol (开放数据协议,OData) 是用来查询和更新数据的一种W…...
GPT对话代码库——HAL库下 USART 的配置及问题(STM32G431CBT6)
目录 1,问: 1,答: 示例代码 正确的HAL库初始化方式 自定义初始化方式(不推荐) 总结 2,问: 2,答: 代码详细解释 初始部分 主初始化部分 初始化调用…...
ExoPlayer架构详解与源码分析(14)——ProgressiveMediaPeriod
系列文章目录 ExoPlayer架构详解与源码分析(1)——前言 ExoPlayer架构详解与源码分析(2)——Player ExoPlayer架构详解与源码分析(3)——Timeline ExoPlayer架构详解与源码分析(4)—…...

docker部署kafka(单节点) + Springboot集成kafka
环境: 操作系统:win10 Docker:Docker Desktop 4.21.1 (114176)、Docker Engine v24.0.2 SpringBoot:2.7.15 步骤1:创建网络: docker network create --subnet172.18.0.0/16 net-kafka 步骤2:安…...

一.1.(3)半导体二极管基本电路的分析方法及常见应用电路
1.二极管基本电路的分析方法 先标正负极,再看是否理想二极管 将二极管视为断路,求两端电压 两端电压均大于导通电压,压差大的先导通(由于电源不是完全的阶跃,而是有一个电压爬升的过程) 2.常见应用电路 1.求…...

银河麒麟V10 SP1 审计工具 auditd更新
前言 银河麒麟V10 SP1 审计工具 auditd 引发的内存占用过高, 内存使用率一直在 60% 以上, 内存一直不释放 排查 可以使用ps或者top查看系统进程使用情况 ps -aux|sort -k4nr|head -n 5 发现银河麒麟审计工具 auditd 一直占用内存不释放 解决 办法一…...

JWT(Json Web Token)在.NET Core中的使用
登录成功时生成JWT字符串目录 JWT是什么? JWT的优点: JWT在.NET Core 中的使用 JWT是什么? JWT把登录信息(也称作令牌)保存在客户端为了防止客户端的数据造假,保存在客户端的令牌经过了签名处理…...

《QT从基础到进阶·四十三》QPlugin插件多线程问题和只有插件dll没有头文件和lib文件时调用插件中的方法
1、插件和多线程问题: 创建插件对象不能放到多线程执行,不然报错:ASSERT failure in QWidget: "Widgets must be created in the GUlthread. //不能放在多线程执行 QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName))…...
Android SurfaceFlinger——屏幕状态初始化(二十二)
对于开机启动动画前期准备的相关步骤,我们已经分析了前 5 个,对于第 6 步调用 eglGetDisplay() 函数对 OpenGL ES 初始化并获取默认屏幕,我们在介绍 OpenGL ES 的时候也进行了详细的分析,下一步我们我们来分析对屏幕的状态进行初始化。 1)getInternalDisplayToken:获取显…...
3101. 交替子数组计数 Medium
给你一个 二进制数组 nums 。 如果一个 子数组 中 不存在 两个 相邻 元素的值 相同 的情况,我们称这样的子数组为 交替子数组 。 返回数组 nums 中交替子数组的数量。 示例 1: 输入: nums [0,1,1,1] 输出: 5 解释&…...
Linux系统基础命令行指令——Ubuntu
基础指令 更新指令 sudo apt update sudo apt upgrade 切换超级管理员 su root 切换路径 //相对、绝对 cd 路径回上一级路径 cd ..cd ../.. 退两级路径 查看当前目录 pwd查看指定路径内容 ls //常见搭配 ls -al 创建目录 mkdir 路径 创建文件 touc…...
qt 读取配置文件
在Qt中读取配置文件,主要有以下几种方法: 使用QFile和QTextStream类: 这种方法适用于读取任意文本文件,包括配置文件。使用QFile的open()方法打开配置文件。使用QTextStream的readLine()方法逐行读取配置数据。使用QXmlStreamRea…...
拉格朗日插值法【python,算法】
拉格朗日插值是一种在数值分析中用来构建通过一系列已知数据点的多项式插值的方法。这种方法以 18 世纪的法国数学家约瑟夫拉格朗日命名。当给定一组离散的数据点(𝑥_0,𝑦_0),(𝑥_1,𝑦_1),...,(𝑥_𝑛,&…...
定个小目标之刷LeetCode热题(41)
338. 比特位计数 给你一个整数 n ,对于 0 < i < n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n 1 的数组 ans 作为答案。 今天看一下这道简单题,主要考查位运算,代码如下 class Solution {pu…...
Kotlin中的关键字
Kotlin 中的关键字可分为几个大类: 声明/定义关键字: class:用于定义类interface:用于定义接口object:用于声明对象,Kotlin中实现单例模式的关键字fun:用于声明函数var:用于声明可变…...

LabVIEW新能源汽车电池性能测试系统
新能源汽车的核心部件之一是电池,其性能直接关系到整车的续航里程、安全性和寿命。为了确保电池的性能和可靠性,测试是必不可少的环节。本文介绍了一种基于LabVIEW的新能源汽车电池性能测试系统,通过LabVIEW与数据采集设备的无缝集成…...

Elasticsearch 实现 Word、PDF,TXT 文件的全文内容提取与检索
文章目录 一、安装软件:1.通过docker安装好Es、kibana安装kibana:2.安装原文检索与分词插件:之后我们可以通过doc命令查看下载的镜像以及运行的状态:二、创建管道pipeline名称为attachment二、创建索引映射:用于存放上传文件的信息三、SpringBoot整合对于原文检索1、导入依赖…...
深度学习赋能数据分析,联蔚盘云引领业务革新
一、引言 随着大数据时代的到来,深度学习技术正逐渐成为企业数据分析的新引擎。联蔚盘云凭借其在深度学习领域的深厚积累,为企业提供高效、精准的数据分析解决方案,助力企业实现业务革新与增长。 二、深度学习与数据分析的完美结合 联蔚盘…...

Arthas实战(5)- 项目性能调优
1、接口耗时查询:trace命令 trace 命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。 1.1 准备测试应用 新建一个 SpringBoot 应用,写一耗时久的代码&…...

昇思25天学习打卡营第7天|Pix2Pix实现图像转换
文章目录 昇思MindSpore应用实践基于MindSpore的Pix2Pix图像转换1、Pix2Pix 概述2、U-Net架构定义UNet Skip Connection Block 2、生成器部分3、基于PatchGAN的判别器4、Pix2Pix的生成器和判别器初始化5、模型训练6、模型推理 Reference 昇思MindSpore应用实践 本系列文章主要…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...