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

springboot---mybatis操作事务配置的处理

目录

前言:

事务的相关问题

1、什么是事务?

2、事务的特点(ACID)

3、什么时候想到使用事务?

4、通常使用JDBC访问数据库,还是mybatis访问数据库,怎么处理事务?

5、问题中事务处理的方式有什么不足?

6、怎么解决不足?

7、处理事务,需要怎么做,做什么?

8、事务的隔离级别

9、事务的超时时间

10、事务的传播行为

spring boot中配置事务以及使用:

1、进行配置类的处理

2、创建数据资源配置类:

3、实际代码里面调用实践:

总结:


前言:

目前大多数的项目都是通过spring或者springboot来开发的,并且项目里面操作数据库常用的有mybatis\mybatis-plus等,在操作数据库的时候,经常会使用事务的处理,因为在操作数据库的时候,如果出现异常的话,所有的数据库操作都能够回滚操作,避免造成一些异常数据的问题。目前网络上搜索的都是原始的配置方式,比如说使用xml进行bean的配置,或者说直接在方法头上面进行添加注解的方式进行调用的,本文主要介绍通过配置类进行管理实务的方式,统一的管理、统一的处理方式。

事务的相关问题

1、什么是事务?

事务是指一组SQL语句的集合,集合中有多条SQL语句,可以是insert、update、select、delete,希望这些SQL语句执行是一致的,作为一个整体执行。要么都成功,要么都失败。

2、事务的特点(ACID)

原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。

一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。

隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。

持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。

3、什么时候想到使用事务?

(1)当操作设计多个表,或者是多个SQL语句的insert、update、delete。需要保证这些语句都是成功才能完成功能,或者都失败是符合要求的。(要么都成功,要么都失败)

(2)事务在java开发中如何运用?

1、事务放在service类的业务方法中,因为业务方法会调用多个dao,执行多条SQL语句

4、通常使用JDBC访问数据库,还是mybatis访问数据库,怎么处理事务?

(1)jdbc访问数据,处理事务。Connection conn;conn.commit();conn.rollback();

(2)mybatis访问数据库,处理事务。SqlSession.commit() ;SqlSession.rollback();

(3)hibernate访问数据库,处理事务,Session.commit(); Session.rollback();

5、问题中事务处理的方式有什么不足?

(1)不同数据库访问技术,处理事务的对象、方法不同。需要了解不同数据库使用事务的原理。

(2)需要掌握多种数据库事务的处理逻辑,什么时候提交事务,什么时候回滚事务。

(3)处理事务的方法种类多。

总结:就是多种数据库访问技术,不同的事务处理的机制、对象、方法。较难掌握。

6、怎么解决不足?

spring提供了处理事务的统一模型,能够使用统一的步骤、方式完成多种不同数据库访问技术的事务处理。使用spring的事务处理机制可以完成mybatis、hibernate访问数据库的事务处理。

7、处理事务,需要怎么做,做什么?

spring处理事务的模型,使用的步骤都是固定的。把事务要使用的信息都提供给spring就可以了。

(1)事务内部提交、回滚事务使用的是事务管理器对象,代替手动commit、rollback。事务管理器是一个接口和其众多的实现类。

接口:PlatformTransactionManager,定义了事务的重要方法 commit、rollback

实现类:spring把每一种数据库访问技术对应的事务处理累都创建好了。

a、mybatis访问数据库—spring创建好的是DataSourceTransactionManager

b、hibernate访问数据库—spring创建好的是HibernateTransactionManager

怎么使用?

只需告诉spring使用哪种数据库的访问技术(框架),声明数据库访问技术对应的事务管理器的实现类,在spring的配置文件中使用<bean>声明就可以了。例如使用mybatis访问数据库:

<bean id = "xxx" class = "...DataSourceTransactionManager"/>

1

(2)业务方法需要什么样的事务?说明需要事务的类型。

8、事务的隔离级别

有 5 个值,其中一个是默认。这些常量均是以ISOLATION_开头,即形如:ISOLATION_XXX。

1、DEFAULT:采用DB默认的事务隔离级别。MySQL的默认隔离级别:REPEATABLE_READ(可重复读);Oracle默认的隔离级别:READ_COMMITTED(读已提交)

2、READ_UNCOMMITTED:读未提交,未解决任何并发问题。

3、READ_COMMITTED:读已提交。解决度脏数据,存在不可重复读与幻读。

4、REPEATABLE_READ:可重复度。解决脏读、不可重复读,存在幻读。

5、SERIALIZABLE:串行化。不存在并发问题。

9、事务的超时时间

表示一个方法最长的执行时间,如果方法执行时超过了这个时间,事务就回滚。单位是秒,整数值,默认是:-1(表示没有限制最长时间)。

10、事务的传播行为

控制业务方法是不是有事务的,是什么样的事务的。共有 7 个传播行为。(标红常用需掌握)

(1)PROPAGATION_REQUIRED:指定的方法必须在事务内执行。若当前存在事务,就加入当前事务中;若当前没有事务,则创建一个新事务。这种创博行为时最常见的选择,也是spring默认的事务传播行为。

(2)PROPAGATION_REQUIRES_NEW:总是新建一个事务,若当前存在事务,就将当前事务挂起,知道新事物执行完毕。

(3)PROPAGATION_SUPPORTS:指定方法支持当前事务,但若当前没有事务,也可以以非事务的方式执行。

(4)PROPAGATION_MANDATORY

(5)PROPAGATION_NESTED

(6)PROPAGATION_NEVER

(7)PROPAGATION_NOT_SUPPORTED

spring boot中配置事务以及使用:

1、进行配置类的处理

#transaction setting###############################################
spring.transaction.aop.aop-pointcut-expression=execution(* com...*ServiceImpl.*(..))
spring.transaction.aop.tx-method-timeout=3600
spring.transaction.aop.require-rule=insert*,update*,delete*,do*
spring.transaction.aop.read-only-rule=query*
spring.transaction.aop.indep-transaction-rule=indep*

第一个配置:该方法主要是为了在操作的时候,扫描包的路径,不是所有的方法都是走事务处理的。

第二个配置:配置处理的时间大小36秒

第三个配置:为了限制规则,比如说方法的名称必须是什么开头的,只有这些方法名称开头的才会走事务的处理

第四个配置:读取的规则的方法名称开头的命名

第五个配置:事务的处理规则

2、创建数据资源配置类:

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;@Configuration
public class SpringBootDatasourceConfig {private Logger LOGGER = LoggerFactory.getLogger(SpringBootDatasourceConfig.class);@Value("${spring.transaction.aop.tx-method-timeout}")private int TX_METHOD_TIMEOUT = 60;@Value("${spring.transaction.aop.aop-pointcut-expression}")private String AOP_POINTCUT_EXPRESSION;@Value("#{'${spring.transaction.aop.require-rule}'.split(',')}")private List<String> requireRuleList;@Value("#{'${spring.transaction.aop.read-only-rule}'.split(',')}")private List<String> readOnlyRuleList;@Value("#{'${spring.transaction.aop.indep-transaction-rule}'.split(',')}")private List<String> indepTransactionRuleList;@Value("${mybatis.mapper-locations}")private String MYBATIS_MAPPER_LOCATIONS;@Value("${mybatis.config-location}")private String MYBATIS_CONFIG_LOCATION;@Value("${mybatis.jdbc.dialect.type}")private String MYBATIS_JDBC_DIALECT_TYPE;public SpringBootDatasourceConfig() {}@Primary@Bean({"db1DataSourceProperties"})@ConfigurationProperties(prefix = "spring.datasource.db1")public DataSourceProperties dataSourceProperties() {DataSourceProperties dataSourceProperties = new DataSourceProperties();return dataSourceProperties;}@Primary@Bean({"db1DataSource"})@ConfigurationProperties(prefix = "spring.datasource.db1.tomcat")public DataSource db1DataSource(@Qualifier("db1DataSourceProperties") DataSourceProperties dataSourceProperties) {DataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().build();return dataSource;}@Primary@Bean(name = {"db1SqlSessionFactory"})public SqlSessionFactory db1SqlSessionFactory(@Qualifier("db1DataSource") DataSource datasource) throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(datasource);bean.setMapperLocations((new PathMatchingResourcePatternResolver()).getResources(this.MYBATIS_MAPPER_LOCATIONS));bean.setConfigLocation((new PathMatchingResourcePatternResolver()).getResource(this.MYBATIS_CONFIG_LOCATION));PageInterceptor pageInterceptor = new PageInterceptor();Properties properties = new Properties();properties.setProperty("dialect", this.MYBATIS_JDBC_DIALECT_TYPE);pageInterceptor.setProperties(properties);Interceptor[] plugins = new Interceptor[]{pageInterceptor};bean.setPlugins(plugins);return bean.getObject();}@Bean({"sqlSessionTemplate"})public SqlSessionTemplate db1SqlsessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sessionfactory) {SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sessionfactory);if (sqlSessionTemplate != null) {Connection connection = null;try {connection = sqlSessionTemplate.getConnection();} catch (Exception var13) {this.LOGGER.error("SqlSessionTemplate初始化连接池失败", var13);} finally {if (connection != null) {try {connection.close();} catch (SQLException var12) {this.LOGGER.error("关闭连接失败", var12);}}}}return sqlSessionTemplate;}@Bean({"txmanager"})public DataSourceTransactionManager txManager(@Qualifier("db1DataSource") DataSource dataSource) {DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();dataSourceTransactionManager.setDataSource(dataSource);return dataSourceTransactionManager;}@Bean({"txAdvice"})public TransactionInterceptor txAdvice(@Qualifier("txmanager") DataSourceTransactionManager dataSourceTransactionManager) {RuleBasedTransactionAttribute readOnlyRule = new RuleBasedTransactionAttribute();readOnlyRule.setReadOnly(true);readOnlyRule.setPropagationBehavior(4);RuleBasedTransactionAttribute requireRule = new RuleBasedTransactionAttribute();requireRule.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(RuntimeException.class)));requireRule.setPropagationBehavior(0);requireRule.setIsolationLevel(2);requireRule.setTimeout(this.TX_METHOD_TIMEOUT);RuleBasedTransactionAttribute indepTransactionRule = new RuleBasedTransactionAttribute();indepTransactionRule.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(RuntimeException.class)));indepTransactionRule.setPropagationBehavior(3);indepTransactionRule.setIsolationLevel(2);indepTransactionRule.setTimeout(this.TX_METHOD_TIMEOUT);Map<String, TransactionAttribute> txMap = new HashMap();int i;String indepTransacdtionAopRule;for(i = 0; i < this.requireRuleList.size(); ++i) {indepTransacdtionAopRule = (String)this.requireRuleList.get(i);txMap.put(indepTransacdtionAopRule.trim(), requireRule);}for(i = 0; i < this.readOnlyRuleList.size(); ++i) {indepTransacdtionAopRule = (String)this.readOnlyRuleList.get(i);txMap.put(indepTransacdtionAopRule.trim(), readOnlyRule);}for(i = 0; i < this.indepTransactionRuleList.size(); ++i) {indepTransacdtionAopRule = (String)this.indepTransactionRuleList.get(i);txMap.put(indepTransacdtionAopRule.trim(), indepTransactionRule);}NameMatchTransactionAttributeSource nameMatchTransactionAttributeSource = new NameMatchTransactionAttributeSource();nameMatchTransactionAttributeSource.setNameMap(txMap);TransactionInterceptor txAdvice = new TransactionInterceptor(dataSourceTransactionManager, nameMatchTransactionAttributeSource);return txAdvice;}@Beanpublic Advisor txAdviceAdvisor(@Qualifier("txAdvice") TransactionInterceptor transactionInterceptor) {AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();pointcut.setExpression(this.AOP_POINTCUT_EXPRESSION);return new DefaultPointcutAdvisor(pointcut, transactionInterceptor);}
}

3、实际代码里面调用实践:

第一种:添加异常方法,直接调用接口,就可以看到相关的效果,只不过需要在数据库变更的后面,添加相关的异常抛出,让整个方法异常,然后看一下这个数据库的记录没有变化,已经 回滚了;

第二种:去除异常方法,让整个方法正常执行下去,通过 数据库查询一下记录,看一下数据是更新是成功落库的;

总结:

目前网络上面搜索到的都是直接使用的注解进行事务的处理,而不是根据配置文件进行配置规则、以及事务的统一管理处理,比如说方法名称进行切面的处理,那些方法是会进行mybatis(数据库的更新处理会走事务处理),比如说,目前的很多大型公司,或者说需要保持事务一致性的公司都会用到,整个的调用链比较长,如果中途出现了问题,会进行事务的回滚处理,避免了很多的问题(数据库里面存在垃圾数据的问题);

相关文章:

springboot---mybatis操作事务配置的处理

目录 前言&#xff1a; 事务的相关问题 1、什么是事务&#xff1f; 2、事务的特点&#xff08;ACID&#xff09; 3、什么时候想到使用事务&#xff1f; 4、通常使用JDBC访问数据库&#xff0c;还是mybatis访问数据库&#xff0c;怎么处理事务&#xff1f; 5、问题中事务处…...

游戏盾是什么防御DDOS攻击的

游戏盾是一种专门用于防御分布式拒绝服务&#xff08;DDoS&#xff09;攻击的安全工具。DDoS攻击是指攻击者利用大量的计算机或设备同时向目标服务器发送海量的请求&#xff0c;以使目标服务器超负荷运行&#xff0c;无法正常提供服务。游戏盾通过一系列智能的防护措施&#xf…...

java快速结束嵌套循环

java快速结束嵌套循环 快速结束for循环 out:for (int i 0; i < 5; i) {in:for (int j 0; j < 5; j) {if (j 2) {break out;}System.out.println("i " i " j " j);}}解释 将外层for循环起别名 o u t \color{red}{out} out,将内层for循环起别名…...

chatgpt赋能python:Python屏蔽一段代码

Python屏蔽一段代码 在Python编程中&#xff0c;有时我们需要屏蔽一段代码以便于调试或者测试。在很多情况下&#xff0c;我们可能不想删除这段代码&#xff0c;因为需要在将来的某个时间再次使用它。为了解决这个问题&#xff0c;我们可以使用Python中的注释语句或者条件语句…...

项目跑不起来

Sa-Token/sa-token-core/src/main/java/cn/dev33/satoken/temp/SaTempUtil.java:10:8 java: 写入cn.dev33.satoken.temp.SaTempUtil时出错: Output directory is not specified 写入cn.dev33.satoken.temp.SaTempUtil时出错: Output directory is not specified 答案&#xf…...

黑马Redis视频教程高级篇(多级缓存案例导入说明)

目录 一、安装MYSQL 1.1、准备目录 1.2、运行命令 1.3、修改配置 1.4、重启 二、导入SQL 三、导入Demo工程 3.1、分页查询商品 3.2、新增商品 3.3、修改商品 3.4、修改库存 3.5、删除商品 3.6、根据id查询商品 3.7、根据id查询库存 3.8、启动 四、导入商品查询…...

2023系统分析师下午案例分析真题

真题1 阅读以下关于软件系统分析与建模的叙述&#xff0c;在纸上回答问题1至3. 说明: 某软件公司拟开发一套汽车租赁系统&#xff0c;科学安全和方便的管理租赁公司的各项业务&#xff0c;提高公司效率&#xff0c;提升利率。注册用户在使用系统镜像车辆预约时需执行以下操作…...

【Python练习】Matplotlib数据可视化

文章目录 一、实验目标二、实验内容1. 用画布的各种设置,绘制类似如图1所示的:y1=sin(x)和y2=cos(x)的曲线图2. 某校高一3班12名同学语数外三科成绩分布情况如表5-2所示,数据值也可以自拟,适当调整。绘制折线图、纵向条形图分析这些同学单科成绩情况,绘制纵向堆叠条形图查…...

【2611. 老鼠和奶酪】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 有两只老鼠和 n 块不同类型的奶酪&#xff0c;每块奶酪都只能被其中一只老鼠吃掉。 下标为 i 处的奶酪被吃掉的得分为&#xff1a; 如果第一只老鼠吃掉&#xff0c;则得分为 reward1[i] 。如果第二…...

Reid strong baseline 代码详解

本项目是对Reid strong baseline代码的详解。项目暂未加入目标检测部分&#xff0c;后期会不定时更新&#xff0c;请持续关注。 本相比Reid所用数据集为Markt1501&#xff0c;支持Resnet系列作为训练的baseline网络。训练采用表征学习度量学习的方式。 目录 训练参数 训练代…...

宝塔面板搭建网站教程:Linux下使用宝塔一键搭建网站,内网穿透发布公网上线

文章目录 前言1. 环境安装2. 安装cpolar内网穿透3. 内网穿透4. 固定http地址5. 配置二级子域名6. 创建一个测试页面 转载自cpolar内网穿透的文章&#xff1a;使用宝塔面板快速搭建网站&#xff0c;并内网穿透实现公网远程访问 前言 宝塔面板作为简单好用的服务器运维管理面板&…...

常微分方程(ODE)求解方法总结

常微分&#xff08;ODE&#xff09;方程求解方法总结 1 常微分方程&#xff08;ODE&#xff09;介绍1.1 微分方程介绍和分类1.2 常微分方程的非计算机求解方法1.3 线性微分方程求解的推导过程 2 一阶常微分方程&#xff08;ODE&#xff09;求解方法2.1 欧拉方法2.1.1 欧拉方法2…...

【华为OD机试】区间交集【2023 B卷|200分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 给定一组闭区间,其中部分区间存在交集。 任意两个给定区间的交集,称为公共区间 (如:[1,2],[2,3]的公共区间为[2,2],[3,5],[3,6]的公共区间为[3,5])。 公共区间之间若存在交集,则需…...

Vue3 | Element Plus resetFields不生效

Vue3 | Element Plus resetFields不生效 1. 简介 先打开创建对话框没有问题&#xff0c;但只要先打开编辑对话框&#xff0c;后续在打开对话框就会有默认值&#xff0c;还无法使用resetFields()重置。 下面是用来复现问题的示例代码和示例GIF。 <script setup> import…...

机器视觉特点 机器视觉实际应用

机器视觉特点 1、机器视觉是一项综合技术&#xff0c;其中包括数字图像处理技术&#xff0c;机械工程技术&#xff0c;控制技术&#xff0c;电光源照明技术&#xff0c;光学成像技术&#xff0c;传感器技术&#xff0c;模拟与数字视频技术&#xff0c;计算机硬件技术&#xff…...

elementui大型表单校验

一般很大的表单都会被拆解开&#xff0c;校验&#xff0c;&#xff0c;不会写在一个页面&#xff0c;&#xff0c;就会有多个 el-form &#xff0c;&#xff0c;主页要集合所有el-form的数据&#xff0c;&#xff0c;所以有一个map来接收&#xff0c;传送表单数据&#xff0c;&…...

Linux+Selenium

SeleniumLinux 开源社区已无CentOS7.0以下rpm维护。升级测试机器到CentOS7.X。 Selenium安装 python环境&#xff1a;pip3 install selenium 浏览器插件&#xff1a;http://chromedriver.storage.googleapis.com/index.html yum instlal google-chrome 使用以下命令确定是…...

2023-06-01 LeetCode每日一题(礼盒的最大甜蜜度)

2023-03-29每日一题 一、题目编号 二、题目链接 点击跳转到题目位置 三、题目描述 给你一个正整数数组 price &#xff0c;其中 price[i] 表示第 i 类糖果的价格&#xff0c;另给你一个正整数 k 。 商店组合 k 类 不同 糖果打包成礼盒出售。礼盒的 甜蜜度 是礼盒中任意两…...

Spring架构篇--2.7.2 远程通信基础--Netty原理--ServerBootstrap

前言&#xff1a;已经初始化了NioEventLoopGroup 的boosGroup 和 workerGroup &#xff0c;那么ServerBootstrap的作用是干嘛的呢 &#xff0c;本文在Spring架构篇–2.7.1 远程通信基础–Netty原理–NioEventLoopGroup 之后继续进行探究 1 首先回顾下 nettt 的使用demo&#x…...

awk编辑器

文章目录 一.awk概述1.概述2.作用3.awk的工作过程4.awk 工作原理及命令格式5.awk的基本操作及其内置变量5.1 awk的-F操作5.2 awk的-v操作5.3 内置变量 二.awk 打印1.基本打印用法1.1 默认打印1.2打印文件内容 2.对行进行操作2.1 只打印行号&#xff08;有多少行&#xff09;2.2…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...