当前位置: 首页 > news >正文

redisson常用APi-Example

中文文档目录

redisson中文文档目录

分布式对象

package com.example.redissondemo.test;import com.example.redissondemo.RedissonDemoApplication;
import com.example.redissondemo.test.domain.Order;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;/*** 测试学习redisson 对象 api*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = RedissonDemoApplication.class)
@Slf4j
public class RedissonObjectExampleTests {@Autowiredprivate RedissonClient redissonClient;/*** 直接存储对象,无需强制类型转换 (支持异步操作)*/@Testpublic void bucketTest() {RBucket<Order> orderBucket = redissonClient.getBucket("myOrder");System.out.println("init : " + orderBucket.get());// 设置orderBucket.set(new Order(10L, "OR001"), 1, TimeUnit.MINUTES);System.out.println("设置 : " + orderBucket.get());// 删除System.out.println("删除状态:" + orderBucket.delete() + "当前" + orderBucket.get());// 重新设置orderBucket.set(new Order(10L, "OR001"), 1, TimeUnit.MINUTES);System.out.println("重新设置 : " + orderBucket.get());// 如果是or1 改为or2orderBucket.compareAndSet(new Order(10L, "OR001"), new Order(10L, "OR002"));System.out.println("存在or1 改为or2 : " + orderBucket.get());// 如果是or1 改为or3orderBucket.compareAndSet(new Order(10L, "OR001"), new Order(10L, "OR003"));System.out.println("存在or1 改为or3 : " + orderBucket.get());// 存在bucket对象就修改为OR3orderBucket.setIfExists(new Order(10L, "OR003"), 1, TimeUnit.MINUTES);System.out.println("存在bucket对象就修改为OR3 : " + orderBucket.get());orderBucket.isExists();orderBucket.delete();}/*** 数字操作,计数器 原子类操作 等等 (支持异步操作)** @throws ExecutionException* @throws InterruptedException* @throws TimeoutException*/@Testpublic void numberTest() throws ExecutionException, InterruptedException, TimeoutException {// 存在精度丢失RDoubleAdder doubleAdder = redissonClient.getDoubleAdder("doubleAdder");doubleAdder.add(1.9999);doubleAdder.add(2.0001);doubleAdder.add(3.0000000000000001);RFuture<Double> future = doubleAdder.sumAsync();Double sum = future.get(1000, TimeUnit.MILLISECONDS);System.out.println(sum);doubleAdder.delete();RLongAdder longAdder = redissonClient.getLongAdder("longAdder");longAdder.add(100);longAdder.increment();longAdder.increment();long longSum = longAdder.sum();System.out.println(longSum);longAdder.delete();longAdder.destroy();// 当不再使用整长型累加器对象的时候应该自行手动销毁,如果Redisson对象被关闭(shutdown)了,则不用手动销毁// 支持CAS设置RAtomicDouble atomicDouble = redissonClient.getAtomicDouble("atoDouble");double v = atomicDouble.incrementAndGet();System.out.println(v);atomicDouble.compareAndSet(v, 2.0);System.out.println(atomicDouble.get());atomicDouble.delete();RLongAdder atoLong = redissonClient.getLongAdder("atoLong");atoLong.increment();System.out.println(atoLong.sum());atoLong.delete();}/*** 限流**/@Testpublic void rateLimiterTest() {RRateLimiter limiter = redissonClient.getRateLimiter("orderImport");// 初始化// 最大流速 = 每1秒钟产生10个令牌// tryAcquire 尝试获取令牌// 如果令牌足够 则扣减令牌 返回true// 如果令牌不够 则不扣减  返回false// acquire 直接获取令牌 如果获取不到令牌 就阻塞等新的令牌产生// 如果令牌足够 则扣减对应的令牌// 如果令牌不够 则扣减令牌数量为0limiter.trySetRate(RateType.OVERALL, 10, 1, RateIntervalUnit.HOURS);boolean b = limiter.tryAcquire(1);System.out.println(" tryAcquire 1  availablePermits : " + limiter.availablePermits());b = limiter.tryAcquire(10);System.out.println(" tryAcquire 10 availablePermits : " + limiter.availablePermits());limiter.acquire(3);System.out.println("acquire 3 availablePermits : " + limiter.availablePermits());new Thread(() -> {limiter.acquire(2);System.out.println(" acquire 2 availablePermits : " + limiter.availablePermits());}).start();limiter.acquire(7);System.out.println(" acquire 7 availablePermits : " + limiter.availablePermits());//        long start = System.currentTimeMillis();limiter.acquire(1);
//        System.out.println(System.currentTimeMillis() - start);System.out.println(" acquire 1 availablePermits : " + limiter.availablePermits());try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}limiter.acquire(7);System.out.println(" acquire 7 availablePermits : " + limiter.availablePermits());limiter.delete();}@Testpublic void mapDemo() {
//        RMap<String, String> test = redissonClient.getMap("test", MapOptions.defaults());
//        test.put("testKey", "testValue");
//        test.fastPut("fastTestKey", "testValue");
//        String testKey = test.get("testKey");
//        test.remove("testKey");
//        test.get("testKey");RBucket<MyBucket> myBucket = redissonClient.getBucket("myBucket");myBucket.set(new MyBucket(), 1, TimeUnit.MINUTES);System.out.println(myBucket.get());myBucket.rename("myBucket1");RBucket<MyBucket> myBucket1 = redissonClient.getBucket("myBucket");System.out.println(myBucket1.get());RBucket<MyBucket> myBucket2 = redissonClient.getBucket("myBucket1");System.out.println(myBucket2.get());}@Datapublic static class MyBucket {private String name = "test";private int age = 10;}}

分布式集合

package com.example.redissondemo.test;import com.alibaba.fastjson.JSONObject;
import com.example.redissondemo.RedissonDemoApplication;
import com.example.redissondemo.test.domain.Order;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;/*** 测试学习redisson 集合 api*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = RedissonDemoApplication.class)
@Slf4j
public class RedissonCollectionsExampleTests {@Autowiredprivate RedissonClient redissonClient;/***  Java对象实现了java.util.concurrent.ConcurrentMap接口和java.util.Map接口。与HashMap不同的是,RMap保持了元素的插入顺序。*  还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口**/@Testpublic void mapTest() throws ExecutionException, InterruptedException {String key = "user";RMap<String, String> map = redissonClient.getMap(key);map.put("name", "zhangsan");map.put("age", "18");String name = map.get("name");System.out.println ("user name : " + name);boolean b = map.containsKey("age");System.out.println("has age ? : " + b);Set<Map.Entry<String, String>> entries = map.entrySet();System.out.println(Arrays.toString(entries.toArray()));map.remove("age");// fastPut 和 put 的区别就是 put会发回之前该索引位置的值(如果存在) 而fastPut 只会返回插入成功与否map.fastPut("like", "eat");System.out.println(JSONObject.toJSONString(map));// 同理map.fastRemove("like");// 异步操作 提高操作效率RFuture<String> putAsyncFuture = map.putAsync("321","");RFuture<Boolean> booleanRFuture = map.fastPutAsync("123", "");putAsyncFuture.get();booleanRFuture.get();System.out.println(JSONObject.toJSONString(map));}/*** 多值映射 一对多映射关系的存储* 基于list  set*/@Testpublic void myMultimapTest(){// 基于set 基于Set的Multimap不允许一个字段值包含有重复的元素。RSetMultimap<String, String> map = redissonClient.getSetMultimap("RSetMultimap");map.put("age", "19");map.put("age", "20");map.put("name", "zhangsan");Set<String> allValues = map.get("age");System.out.println(allValues);List<String> newValues = Arrays.asList("17", "16", "15");Set<String> oldValues = map.replaceValues("age", newValues);System.out.println(oldValues);Set<String> removedValues = map.removeAll("age");System.out.println(removedValues);map.put("carCount", "2");Set<Map.Entry<String, String>> entries = map.entries();System.out.println(JSONObject.toJSONString(entries));map.delete();// 基于list 同理 基于List的Multimap在保持插入顺序的同时允许一个字段下包含重复的元素。redissonClient.getListMultimap("myListMultimap");//  Multimap对象的淘汰机制是通过不同的接口来实现的。它们是RSetMultimapCache接口和RListMultimapCache接口,分别对应的是Set和List的Multimaps。RListMultimapCache<Object, Object> myListMultimap2 = redissonClient.getListMultimapCache("myListMultimap2");myListMultimap2.expireKey("2", 10, TimeUnit.MINUTES);RSetMultimapCache<Object, Object> getSetMultimapCache = redissonClient.getSetMultimapCache("getSetMultimapCache");getSetMultimapCache.expireKey("2", 10, TimeUnit.MINUTES);}/*** 基于Redis的Redisson的分布式Set结构的RSet Java对象实现了java.util.Set接口。*/@Testpublic void baseSet(){RSet<Order> set1 = redissonClient.getSet("anySet");set1.add(new Order());set1.remove(new Order());// 基于Redis的Redisson的分布式RSetCache Java对象在基于RSet的前提下实现了针对单个元素的淘汰机制/*** 目前的Redis自身并不支持Set当中的元素淘汰,因此所有过期元素都是通过org.redisson.EvictionScheduler实例来实现定期清理的。* 为了保证资源的有效利用,每次运行最多清理100个过期元素。* 任务的启动时间将根据上次实际清理数量自动调整,间隔时间趋于1秒到2小时之间。* 比如该次清理时删除了100条元素,那么下次执行清理的时间将在1秒以后(最小间隔时间)。* 一旦该次清理数量少于上次清理数量,时间间隔将增加1.5倍。*/RSetCache<Object> set2 = redissonClient.getSetCache("anySet2");// ttl = 10 secondsset2.add(new Order(), 10, TimeUnit.SECONDS);// 基于Redis的Redisson的分布式RSortedSet Java对象实现了java.util.SortedSet接口。在保证元素唯一性的前提下,通过比较器(Comparator)接口实现了对元素的排序。RSortedSet<Integer> set = redissonClient.getSortedSet("anySet");set.trySetComparator(Comparator.comparingInt(a -> a)); // 配置元素比较器set.add(3);set.add(1);set.add(2);set.removeAsync(0);set.addAsync(5);}@Testpublic void baseListAndQueue(){// 基于Redis的Redisson分布式列表(List)结构的RList Java对象在实现了java.util.List接口的同时,确保了元素插入时的顺序。RList<Order> list = redissonClient.getList("anyList");list.add(new Order());Order order = list.get(0);list.remove(new Order());// 队列RQueue<Order> queue1 = redissonClient.getQueue("anyQueue");// 双端队列(DequeRDeque<Order> queue2 = redissonClient.getDeque("anyDeque");// 阻塞队列(Blocking Queue)RBlockingQueue<Order> queue3= redissonClient.getBlockingQueue("anyQueue");// 有界阻塞队列(Bounded Blocking Queue)RBoundedBlockingQueue<Order> queue4 = redissonClient.getBoundedBlockingQueue("anyQueue");// 延迟队列(Delayed Queue)// 基于Redis的Redisson分布式延迟队列(Delayed Queue)结构的RDelayedQueue Java对象在实现了RQueue接口的基础上提供了向队列按要求延迟添加项目的功能。// 该功能可以用来实现消息传送延迟按几何增长或几何衰减的发送策略。RDelayedQueue<Order> delayedQueue = redissonClient.getDelayedQueue(queue1);// 优先队列(Priority Queue)RPriorityQueue<Integer> queue = redissonClient.getPriorityQueue("anyQueue");}}

分布式锁

redisson分布式锁学习

private void redissonDoc() throws InterruptedException {//1. 普通的可重入锁RLock lock = redissonClient.getLock("generalLock");// 拿锁失败时会不停的重试// 具有Watch Dog 自动延期机制 默认续30s 每隔30/3=10 秒续到30slock.lock();// 尝试拿锁10s后停止重试,返回false// 具有Watch Dog 自动延期机制 默认续30sboolean res1 = lock.tryLock(10, TimeUnit.SECONDS);// 拿锁失败时会不停的重试// 没有Watch Dog ,10s后自动释放lock.lock(10, TimeUnit.SECONDS);// 尝试拿锁100s后停止重试,返回false// 没有Watch Dog ,10s后自动释放boolean res2 = lock.tryLock(100, 10, TimeUnit.SECONDS);//2. 公平锁 保证 Redisson 客户端线程将以其请求的顺序获得锁RLock fairLock = redissonClient.getFairLock("fairLock");//3. 读写锁 没错与JDK中ReentrantLock的读写锁效果一样RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("readWriteLock");readWriteLock.readLock().lock();readWriteLock.writeLock().lock();
}

相关文章:

redisson常用APi-Example

中文文档目录 redisson中文文档目录 分布式对象 package com.example.redissondemo.test;import com.example.redissondemo.RedissonDemoApplication; import com.example.redissondemo.test.domain.Order; import lombok.Data; import lombok.extern.slf4j.Slf4j; import o…...

小程序学习(四):WXML模板语法

WXML模板语法-数据绑定 1.数据绑定的基本原则 ①在data中定义数据 ②在WXML中使用数据 2.动态绑定属性 WXML模板语法-事件绑定 3.什么是事件 4.小程序中常用的事件 5.事件对象的属性列表 6.target和currentTarget的区别 7.bindtap的语法格式 8.在事件处理函数中为data中的数据…...

IDEA好用的插件总结

IdeaVim 这个看个人喜好&#xff0c;我比较喜欢用vim&#xff0c;并且支持自定义修改按键绑定alibaba java code guidelines alibaba的java编程规范plantUML 绘制UML&#xff0c;支持语言显示plantUML integration 能够直接将代码转化为UML图&#xff0c;非常方便rainbow brack…...

如何在Linux系统中安装ActiveMQ

1、环境 ActiveMQ是一个纯Java程序&#xff0c;这里安装5.18.2版ActiveMQ&#xff0c;该版MQ运行在JDK 11环境内&#xff0c;为此需要先搭建JDK 11环境&#xff0c;这里安装JDK 15。 1.1、卸载 卸载开源JDK软件包&#xff0c;如下所示&#xff1a; [rootlocalhost ~]# rpm -…...

【Latex】常用公式编辑与符号:公式换行,标号居中、常用符号等

【Latex】常用公式编辑与符号 文章目录 【Latex】常用公式编辑与符号1. 公式换行&#xff0c;且标号居中2. 常用符号3. 常用的希腊字母 1. 公式换行&#xff0c;且标号居中 \begin{equation}\label{eq14} \begin{aligned}a & b/c, \\d & e/f \end{aligned} \end{equ…...

【ArcGIS Pro二次开发】(55):给多个要素或表批量添加字段

在工作中可能会遇到这样的场景&#xff1a;有多个GDB要素、表格&#xff0c;或者是SHP文件&#xff0c;需要给这个要素或表添加相同的多个字段。 在这种情况下&#xff0c;手动添加就变得很繁琐&#xff0c;于是就做了这个工具。 需求具体如下图&#xff1a; 左图是待处理数据…...

CentOS7.3 安装 docker

亲测、截图 阿里云服务器 文章目录 更新源2345 启动开机自启 更新源 sudo yum update -y2 sudo yum install -y yum-utils device-mapper-persistent-data lvm23 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo4 sudo yum …...

代码随想录算法训练营第五十二天 | 300.最长递增子序列、674.最长连续递增序列、718.最长重复子数组

文章目录 一、300.最长递增子序列二、674.最长连续递增序列三、718.最长重复子数组 一、300.最长递增子序列 题目链接 代码如下&#xff1a; class Solution { public:int lengthOfLIS(vector<int>& nums) {if (nums.size() < 1) return nums.size();vector<…...

1、Tomcat

java介绍 Java语言和平台由以下几个主要部分组成&#xff1a; 1、Java编程语言(Java Language)&#xff1a;这是Java的核心部分&#xff0c;包括Java语法、关键字、数据类型、运算符、控制结构等。程序员使用Java语言来编写应用程序的源代码。 2、Java开发工具包(Java Developm…...

centos 内网实现mail发送

文章目录 1、frp 穿透公网和内网2、邮件 配置2.1、mail配置文件 3、测试 1、frp 穿透公网和内网 参考地址&#xff1a;https://zhaosongbin.blog.csdn.net/article/details/88865890 frps端部署在内网&#xff0c;frpc端部署在外网 frps端配置和上面文章中的一样&#xff0c…...

【雕爷学编程】MicroPython动手做(25)——语音合成与语音识别2

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…...

如何用C#实现上位机与下位机之间的Wi-Fi通信?

有IP协议支持的话用UDP报文或者TCP直接发IP地址和端口不行么&#xff1f;你说的WiFi难道是2.4GHz频率模块那种东东&#xff1f; 你既然用了wifi&#xff0c;那么只要上位机和下位机的对应wifi网卡都具有ip地址以及其协议支持&#xff0c;那么和网络编程没啥子明显区别的吧………...

学习笔记|大模型优质Prompt开发与应用课(二)|第五节:只需3步,优质Prompt秒变应用软件

原作者&#xff1a;依依│百度飞桨产品经理 一乔│飞桨开发者技术专家 分享内容 01:大模型应用简介 02:LLM应用开发范式 03: Al Studio大模型社区 04:AI对话类应用开发技巧 大模型技术爆发&#xff0c;各类应用产品涌现 文心产业级知识增强大模型 工作中的“超级助手”—…...

VB客运中心汽车售票管理系统设计与实现

摘 要:该系统是信息管理系统在售票管理方面的一个分支和具体运用,是为长治客运中心而设计的管理售票、车次、票价及客票收入统计等日常事物的系统。此系统选择Visual Basic 6.0作为开发工具来实现客运中心汽车售票所要求的各种功能。本文主要介绍了开发此管理系统的背景、必要…...

计算机网络——学习笔记

付费版&#xff1a;直接在上面的CSDN资源下载 免费版&#xff1a;https://wwsk.lanzouk.com/ijkcj13tqmyb 有疑问或者错误的地方可以在评论区指出&#xff0c;我会尽快回复 示例图&#xff1a;...

JSON对象

目录 简介 创建对象 ​编辑json对象作为属性值 json用于交换数据 简介 json&#xff1a;javascript object notation(js标记对象)是一种轻量化的数据交换模式&#xff0c;特点&#xff1a;体积小&#xff0c;数据量大 在js中&#xff0c;json是以对象的形式存在的&#x…...

26 用lsqnonlin求解最小二乘问题(matlab程序)

1.简述 函数语法 x lsqnonlin(fun,x0) 函数用于&#xff1a; 解决非线性最小二乘(非线性数据拟合)问题 解决非线性最小二乘曲线拟合问题的形式 变量x的约束上下限为ub和lb&#xff0c; x lsqnonlin(fun,x0)从x0点开始&#xff0c;找到fun中描述的函数的最小平方和。函数fu…...

Verilog语法学习——LV6_多功能数据处理器

LV6_多功能数据处理器 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 描述 根据指示信号select的不同&#xff0c;对输入信号a,b实现不同的运算。输入信号a…...

发送信息----策略模式

发送信息----策略模式 发送信息 发送信息 发送信息到手机、邮箱等&#xff0c;可扩展 package mainimport ("errors""fmt" )type PushContext struct {Phone, Email, Message stringTage int }type PaymentStrategy interface {Push(*P…...

PySpark介绍与安装

Spark是什么 定义&#xff1a;Apache Spark是用于大规模数据&#xff08;large-scala data&#xff09;处理的统一&#xff08;unified&#xff09;分析引擎。 简单来说&#xff0c;Spark是一款分布式的计算框架&#xff0c;用于调度成百上千的服务器集群&#xff0c;计算TB、…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...