9、MyBatis框架——使用注解开发实现数据库增删改查操作、一级缓存、二级缓存、MyBatis实现分页
目录
一、使用注解开发实现数据库增删改查操作
1、搭建项目
2、使用注解开发操作数据库
二、一级缓存
1、一级缓存失效的情况
三、二级缓存
1、手动开启二级缓存cacheEnabled
2、二级缓存机制
四、MyBatis实现分页
1、配置环境
2、startPage()开启分页
3、PageInfo查询分页信息
(1)PageInfo对象
(2) getList()方法
(3)getTotal()方法
一、使用注解开发实现数据库增删改查操作
不通过mapper配置文件,通过注解实现数据库增删改查操作
1、搭建项目
(1)创建数据库表admin
CREATE DATABASE mybatisdatabase;
USE mybatisdatabase;
CREATE TABLE IF NOT EXISTS `admin`(
`uid` INT PRIMARY KEY AUTO_INCREMENT,
`username` VARCHAR(20),
`upassword` VARCHAR(20) NOT NULL,
`phone` VARCHAR(11) UNIQUE NOT NULL,
`address` VARCHAR(10) NOT NULL
);INSERT INTO `admin`(`username`,`upassword`,`phone`,`address`) VALUES
('张三','123456','15689609560','安徽合肥包河区'),
('王二','666666','13395581841','安徽合肥蜀山区'),
('李四','456789','18144172517','安徽合肥高新区');
(2)新建module--->java框架Maven工程--->完善工程目录

(3) 在pom.xml中添加需要使用的依赖
<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"><modelVersion>4.0.0</modelVersion><groupId>com.mybatis</groupId><artifactId>mybayis06</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><name>mybayis06</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.11</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.48</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies>
</project>
(4)创建实体类和Mapper接口
package com.mybatis.entity;import lombok.Data;@Data
public class Admin {private long uid;private String username;private String upassword;private String phone;private String address;}
(5)在resources目录下新建config文件,存放mybatis全局配置文件和外部数据源
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 引入外部数据源参数--><properties resource="config/jdbc.properties"></properties><settings><!-- 开启驼峰映射--><setting name="mapUnderscoreToCamelCase" value="true"/><!-- 开启日志打印--><setting name="logImpl" value="LOG4J"/></settings><!-- 给表起别名--><typeAliases><package name="com.mybatis.entity"/></typeAliases><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><mappers><package name="com.mybatis.mapper"/></mappers>
</configuration>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatisdatabase
jdbc.username=root
jdbc.password=123456
(6)在resources目录下新建与Mapper接口层级相同的文件夹存放Mapper映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.AdminMapper"></mapper>
(7)在resources目录下添加日志配置文件log4j.properties
#打印日志的级别:可控制打印信息,哪些打印,哪些不打印
#Console:打印窗口
log4j.rootLogger=DEBUG,Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
#设置打印格式
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
#设置打印信息
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
#打印日志级别:设置打印级别只要不是ERROR级别就不打印
log4j.logger.org.apache=ERROR
log4j.logger.org.mybatis=ERROR
log4j.logger.org.springframework=ERROR
#这个需要
log4j.logger.log4jdbc.debug=ERROR
log4j.logger.com.gk.mapper=ERROR
log4j.logger.jdbc.audit=ERROR
log4j.logger.jdbc.resultset=ERROR
#这个打印SQL语句非常重要
log4j.logger.jdbc.sqlonly=DEBUG
log4j.logger.jdbc.sqltiming=ERROR
log4j.logger.jdbc.connection=FATAL
2、使用注解开发操作数据库
在Mapper接口的方法上直接使用相应的注解来完成对数据库的操作
package com.mybatis.mapper;import com.mybatis.entity.Admin;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;import java.util.List;public interface AdminMapper {@Select("select * from admin where uid = #{uid}")public Admin selectByUid(int uid);@Select("select * from admin")public List<Admin> selectAll();@Insert("insert into admin(username,upassword,phone,address) values (#{username},#{upassword},#{phone},#{address})")public Integer insert(Admin admin);@Delete("delete from admin where uid = #{uid}")public Integer delete(int uid);@Update("update admin set username = #{username},upassword = #{upassword},phone = #{phone},address = #{address} where uid = #{uid}")public Integer update(Admin admin);
}
package com.mybatis.mapper;import com.mybatis.entity.Admin;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;import java.io.IOException;
import java.io.InputStream;
import java.util.List;import static org.junit.Assert.*;public class AdminMapperTest {SqlSessionFactory sqlSessionFactory = null;@Beforepublic void init(){InputStream resourceAsStream = null;try {resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");} catch (IOException e) {e.printStackTrace();}sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);}@Testpublic void selectByUid() {//创建sqlSession会话SqlSession sqlSession = sqlSessionFactory.openSession();//获取AdminMapper接口动态代理对象AdminMapper mapper = sqlSession.getMapper(AdminMapper.class);//通过接口调用方法Admin admin = mapper.selectByUid(1);System.out.println("admin = " + admin);//关闭资源sqlSession.close();}@Testpublic void selectAll() {//创建sqlSession会话SqlSession sqlSession = sqlSessionFactory.openSession();//获取AdminMapper接口动态代理对象AdminMapper mapper = sqlSession.getMapper(AdminMapper.class);//通过接口调用方法List<Admin> adminList = mapper.selectAll();for (Admin admin : adminList) {System.out.println("admin = " + admin);}//关闭资源sqlSession.close();}@Testpublic void insert() {//创建sqlSession会话,开启事务自动提交SqlSession sqlSession = sqlSessionFactory.openSession(true);//获取AdminMapper接口动态代理对象AdminMapper mapper = sqlSession.getMapper(AdminMapper.class);//创建Admin对象Admin admin = new Admin();admin.setUsername("老六");admin.setUpassword("666666");admin.setPhone("19144756263");admin.setAddress("老北京");//通过接口调用方法Integer line = mapper.insert(admin);System.out.println("line = " + line);//关闭资源sqlSession.close();}@Testpublic void delete() {//创建sqlSession会话,开启事务自动提交SqlSession sqlSession = sqlSessionFactory.openSession(true);//获取AdminMapper接口动态代理对象AdminMapper mapper = sqlSession.getMapper(AdminMapper.class);//通过家口调用方法Integer line = mapper.delete(2);System.out.println("line = " + line);//关闭资源sqlSession.close();}@Testpublic void update() {//创建sqlSession会话,开启事务自动提交SqlSession sqlSession = sqlSessionFactory.openSession(true);//获取AdminMapper接口动态代理对象AdminMapper mapper = sqlSession.getMapper(AdminMapper.class);//创建Admin对象Admin admin = new Admin();admin.setUsername("老马");admin.setUpassword("666666");admin.setPhone("18874151577");admin.setAddress("安徽芜湖");admin.setUid(3);//通过接口调用方法Integer line = mapper.update(admin);System.out.println("line = " + line);//关闭资源sqlSession.close();}
}
二、一级缓存
MyBatis一级缓存是默认开启的,在一次SqlSession会话下有效。执行两次相同查询时,为了缓解服务器的压力,第二次的查询结果来自MyBatis的缓存,不再将查询指向数据库
package com.mybatis.mapper;import com.mybatis.entity.Admin;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;import java.io.IOException;
import java.io.InputStream;
import java.util.List;public class SelectTest {SqlSessionFactory sqlSessionFactory = null;@Beforepublic void init(){InputStream resourceAsStream = null;try {resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");} catch (IOException e) {e.printStackTrace();}sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);}@Testpublic void selectAll() {//创建sqlSession会话SqlSession sqlSession = sqlSessionFactory.openSession();//获取AdminMapper接口动态代理对象AdminMapper mapper = sqlSession.getMapper(AdminMapper.class);//通过接口调用方法//第一次查询List<Admin> adminList = mapper.selectAll();for (Admin admin : adminList) {System.out.println("admin = " + admin);}//第二次查询List<Admin> adminList1 = mapper.selectAll();System.out.println("adminList1 = " + adminList1);//关闭资源sqlSession.close();}
}
在程序中调用了两次selectAll()方法,却只执行了一次SQL语句
1、一级缓存失效的情况
(1)执行的查询条件不同,或者SQL语句不同;
(2)两次相同的SQL语句查询之间,做了增删改的操作
(3)手动提交事务也会清空一级缓存;
(4)手动清空缓存:clearCache()


三、二级缓存
一级缓存只在一次SqlSession会话有效,为进一步扩大数据共享的范围,缓解数据库的压力,可手动开启MyBatis二级缓存
写入二级缓存的实例对象需要实现序列化接口
1、手动开启二级缓存cacheEnabled
在MyBatis全局配置文件中,设置<setting>标签
cacheEnabled:全局性地开启或关闭所有映射器配置文件中已配置的任何缓存
<!-- 全局开启二级缓存--><setting name="cacheEnabled" value="true"/>
在mapper映射文件中添加cache标签

2、二级缓存机制
(1)手动提交事务,会将一级缓存写入二级缓存;
(2)SqlSession会话对象关闭时,会将一级缓存写入二级缓存。
四、MyBatis实现分页
1、配置环境
(1)在pom.xml中引入pagehelper依赖
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.3.2</version></dependency>
(2)在mybatis全局配置文件中添加plugins标签
<plugins><plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin></plugins>
2、startPage()开启分页
在调用方法查询记录之前,调用PageHelper类中的startPage()方法开启分页:
pageNum:当前页码;
pageSize:每页显示的数量

3、PageInfo查询分页信息
(1)PageInfo对象
创建PageInfo对象,PageInfo有参构造的参数为查询获取的集合,直接输出PageInfo对象为分页信息导航

(2) getList()方法
获取当前页面的分页信息

(3)getTotal()方法
总记录数
package com.mybatis.mapper;import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mybatis.entity.Admin;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;import java.io.IOException;
import java.io.InputStream;
import java.util.List;public class SelectTest {SqlSessionFactory sqlSessionFactory = null;@Beforepublic void init(){InputStream resourceAsStream = null;try {resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");} catch (IOException e) {e.printStackTrace();}sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);}@Testpublic void selectAll() {//创建sqlSession会话SqlSession sqlSession = sqlSessionFactory.openSession();//获取AdminMapper接口动态代理对象AdminMapper mapper = sqlSession.getMapper(AdminMapper.class);//开启分页//pageNum:当前页码;pageSize:每页显示数量PageHelper.startPage(1,5);//通过接口调用方法List<Admin> adminList = mapper.selectAll();for (Admin admin : adminList) {System.out.println("admin = " + admin);}PageInfo<Admin> adminPageInfo = new PageInfo<>(adminList);System.out.println("adminPageInfo = " + adminPageInfo);long total = adminPageInfo.getTotal();System.out.println("total = " + total);List<Admin> list = adminPageInfo.getList();System.out.println("list = " + list);//关闭资源sqlSession.close();}
}
相关文章:
9、MyBatis框架——使用注解开发实现数据库增删改查操作、一级缓存、二级缓存、MyBatis实现分页
目录 一、使用注解开发实现数据库增删改查操作 1、搭建项目 2、使用注解开发操作数据库 二、一级缓存 1、一级缓存失效的情况 三、二级缓存 1、手动开启二级缓存cacheEnabled 2、二级缓存机制 四、MyBatis实现分页 1、配置环境 2、startPage()开启分页 3、PageInfo…...
C++STL剖析(六)—— set和multiset的概念和使用
文章目录🌟 前言🍑 树型结构和哈希结构🍑 键值对1. set的介绍和使用🍑 set的模板参数列表🍑 set的构造🍑 set的使用🍅 insert🍅 find🍅 erase🍅 swap…...
SpringColud第四讲 Nacos的Windows安装方式和Linux的安装方式
在Nacos的GitHub页面,提供有下载链接,可以下载编译好的Nacos服务端或者源代码: 目录 1.Windows安装Nacos 1.1.下载 1.2.解压 1.3.修改相关配置: 1.4.启动: 1.5.登录: 2.Linux的安装方式Nacos 2.1.…...
微服务项目【网关服务限流熔断降级分布式事务】
网关服务限流熔断降级 第1步:启动sentinel-dashboard控制台和Nacos注册中心服务 第2步:在网关服务中引入sentinel依赖 <!-- sentinel --> <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-…...
【情人节用Compose给女神写个爱心动画APP】
情人节用Compose给女神写个爱心动画APP前言涉及知识点实现思路实现过程绘制爱心创建动画效果Preview预览效果完整源码彩蛋前言 前一阵子看电视里的学霸用代码写了个炫酷的爱心,网上有很多js和python的源码,复制粘贴就能拥有,但是Android的好…...
GUI swing和awt
GUI(Graphical User Interface,简称 GUI,图形用户界面)是指采用图形方式显示的计算机操作用户界面,与早期计算机使用的命令行界面相比,图形界面对于用户来说在视觉上更易于接受。Java GUI主要有两个核心库&…...
速通Spring
尚硅谷2023最新版Spring6课程_bilibili 1 Spring 【强制】Spring是什么? 1) Spring是一款主流的Java EE轻量级开源框架。 轻量级:体积很小,且不需要依赖于其他组件。 2) 狭义的Spring。 Spring Framework。 3) 广义的Spring。 以Spring F…...
【C++】C++入门
一、 C关键字(C98) C有63个关键字(C语言有32个),如下: asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcaseenummutabl…...
Linux网络技术学习(五)—— 网络设备初始化(I)
文章目录什么时候进行的设备初始化?设备注册和初始化NIC(网卡 Network Interface Card)初始化的基本目标设备与内核之间的交互硬件中断中断类型传送节流方式为了改善效率中断共享IRQ处理函数映射的组织irqaction结构体存储方式什么时候进行的…...
[技术选型] ClickHouse和StarRocks的介绍
文章目录1.ClickHouse介绍2.StarRocks介绍1.ClickHouse介绍 ClickHouse是面向联机分析处理(OLAP)的开源分析引擎。最初由俄罗斯第一搜索引擎Yandex开发,于2016年开源,开发语言为C。由于其优良的查询性能,PB级的数据规…...
算法刷题打卡第90天:表现良好的最长时间段
表现良好的最长时间段 难度:中等 给你一份工作时间表 hours,上面记录着某一位员工每天的工作小时数。 我们认为当员工一天中的工作小时数大于 8 小时的时候,那么这一天就是「劳累的一天」。 所谓「表现良好的时间段」,意味在这…...
Python语言零基础入门教程(十七)
Python 文件I/O 本章只讲述所有基本的 I/O 函数,更多函数请参考Python标准文档。 #### 打印到屏幕 最简单的输出方法是用print语句,你可以给它传递零个或多个用逗号隔开的表达式。此函数把你传递的表达式转换成一个字符串表达式,并将结果写…...
C语言中大小端问题
目录 一、什么是大小端 二、 举个例子 三、大小端演示 四、解释"二"中举例的问题 五、怎么判断是大端还是小端 六、一个题目 一、什么是大小端 大端模式(大端字节序存储):就是高位字节数据存放在内存的低地址端ÿ…...
vue2+微前端qiankun从搭建到部署的实践(主子应用切换;集成vue3+vite3子应用)
一、最终效果 二、微前端(qiankun)介绍及为什么选择用微前端,可以看官网 三、目录结构如下 四、具体配置 一、主应用配置 1、主应用技术栈 Vue-cli4搭建项目Vue2Element-Uiqiankun;Vue2Element-Uiqiankun 2、搭建好主项目&…...
怎么代理微信小程序创业?
随着微信的兴起,小程序已经成为了人们生活中不可或缺的一部分。如果你想要创业的话,那么代理微信小程序是一个不错的选择。本文将为大家介绍怎么代理微信小程序创业。 一、什么是微信小程序 微信小程序是一款专为移动设备使用者而设计的应用。它通过扫…...
今天是情人节呐,我利用Python制作了好多表白的东西,快来吧~
今天是情人节那,有没有现在没有对象的宝子,评论里扣个111哈哈 目录 玫瑰 爱心树 丘比特 多彩气球 阿玥的小课堂 一、情人节的由来 二、情人节的来历和意义 玫瑰 局部代码实现如下: # 花瓣1 turtle.left(150) turtle.circle(-90, 70) …...
【Linux】-- 进程信号(处理、内核)
上篇:【Linux】-- 进程信号(认识、应用)_川入的博客-CSDN博客 目录 信号其他相关常见概念 pending handler block 信号处理的过程 sigset_t sigset_t使用 系统接口 sigpending sigprocmask 捕捉方法 sigaction struct sigactio …...
C/【静态通讯录】
🌱博客主页:大寄一场. 🌱系列专栏:C语言学习笔记 😘博客制作不易欢迎各位👍点赞⭐收藏➕关注 前言 往期回顾: C/扫雷 C/N子棋 通讯录作为通讯录地址的书本,当今的通讯录可以涵盖多项…...
万卷书 - 让孩子对自己负责 [The Self-Driven Child]
让孩子对自己负责 The Self-Driven Child - 让你的孩子更加科学合理的掌控自己的生活 简介 《The Self-Driven Child》(2018)解释了我们对孩子的习惯性控制欲,它导致了孩子压力过大、难以合作,以及主观能动性差。本书不提倡这种做法,而是认为我们应该帮助孩子自己做出合适…...
Postman中cookie的操作
在接口测试中,某些接口的调用,需要带入已有Cookie,比如有些接口需要登陆后才能访问。 Postman接口请求使用Cookie有如下两种方式: 1、直接在头域中添加Cookie头域,适用于已经知道请求所用Cookie数据的情况。 2、使用…...
编写程序让智能洗手液机检测手部靠近,自动出液,无需按压。
🧼 项目实战:基于红外测距的智能洗手液机控制系统一、实际应用场景描述 (Scenario)在机场、医院、办公楼等公共场所,传统的按压式洗手液机存在卫生隐患——每个人都需要接触同一个泵头,容易造成细菌交叉感染。目标:通过…...
Qwen3.5-35B-A3B-AWQ-4bit开源镜像实战:法律合同关键条款图示定位与文本提取
Qwen3.5-35B-A3B-AWQ-4bit开源镜像实战:法律合同关键条款图示定位与文本提取 1. 引言:当AI遇到法律合同 想象一下,你是一位法务人员,面前摆着一份长达50页的PDF合同。老板急着要你找出所有关于“违约责任”的条款,并…...
避坑指南:JRTPLIB交叉编译时容易忽略的3个CMAKE参数(附实测解决方案)
避坑指南:JRTPLIB交叉编译时容易忽略的3个CMAKE参数(附实测解决方案) 在嵌入式开发领域,跨平台编译开源库是每个工程师的必修课。JRTPLIB作为实时传输协议(RTP)的经典实现,其ARM架构下的编译问题却常让开发者陷入"…...
VSCode党必看!用轻量级方案玩转LaTeX:2024年TexLive+VSCode配置全攻略
VSCode党必看!用轻量级方案玩转LaTeX:2024年TexLiveVSCode配置全攻略 对于习惯在VSCode中高效编码的开发者而言,切换到传统LaTeX编辑器往往意味着要放弃熟悉的快捷键、扩展生态和流畅的代码体验。本文将带你用完全基于VSCode的轻量级方案构建…...
Uvicorn性能调优:异步I/O模型选择与配置指南
Uvicorn性能调优:异步I/O模型选择与配置指南 【免费下载链接】uvicorn An ASGI web server, for Python. 🦄 项目地址: https://gitcode.com/GitHub_Trending/uv/uvicorn Uvicorn作为Python生态中最受欢迎的ASGI服务器,其性能表现直接…...
利用快马平台快速构建高清乱码生成器:编码错误可视化原型开发指南
最近在调试一个多语言网站时,遇到了各种编码问题导致的乱码现象。为了更直观地理解不同编码错误的表现形式,我尝试用InsCode(快马)平台快速搭建了一个高清乱码生成器,效果出乎意料地好。下面分享下这个项目的实现思路和具体操作: …...
手把手教你用深信服备份系统做整机恢复:从PXE到U盘启动的保姆级避坑指南
深信服整机恢复实战:PXE与U盘启动的深度避坑手册 当服务器突然宕机,硬盘彻底损坏时,整机恢复能力就是IT工程师的救命稻草。深信服备份系统的裸机恢复功能,能在没有操作系统的"裸机"上直接还原整个系统环境——但实际操作…...
如何突破Cursor试用限制?3种创新方案全解析
如何突破Cursor试用限制?3种创新方案全解析 【免费下载链接】go-cursor-help 解决Cursor在免费订阅期间出现以下提示的问题: Youve reached your trial request limit. / Too many free trial accounts used on this machine. Please upgrade to pro. We have this …...
CnDataSeed发布:中国科研工作者跳槽研究数据库(CAMRD)
一、数据简介 追踪学术流动,解析科研人才动力机制! 在中国科研生态快速演化的背景下,科研人才流动是科研创新与学术产出的关键驱动力。但跳槽相关研究在高教研究中一直较为稀缺,系统化、可量化的科研工作者跳槽数据长期缺失&…...
从 POST 到落库回写:彻底讲透 SAP Gateway 中 Create Operation 的实现
在经典的 SAP Gateway 开发里,Create Operation 看上去只是一次新增动作,真正落到运行时,却牵涉到一条非常完整的链路:客户端发起 HTTP POST 请求,请求体里的 OData 数据被 Gateway 运行时反序列化成 ABAP 结构,开发者在对应的 <Entity Set>_CREATE_ENTITY 方法里接…...

