Java事务入门:从基础概念到初步实践

news2024/11/8 18:06:03

在这里插入图片描述

Java事务入门:从基础概念到初步实践

  • 引言
  • 1. Java事务基础概念
    • 1.1 什么是事务?
    • 1.2 为什么需要事务?
  • 2. Java事务管理
    • 2.1 JDBC 的事务管理
    • 2.2 Spring 事务管理
      • 2.2.1 Spring + JDBC
        • 2.2.1.1 添加 Spring 配置
        • 2.2.1.2 添加业务代码并测试验证
      • 2.2.2 Spring + JPA
        • 2.2.2.1 JPA相关依赖
        • 2.2.2.2 添加 JPA 配置
        • 2.2.2.3 添加 Spring 配置
        • 2.2.2.4 添加实体类
        • 2.2.2.5 添加业务代码并测试验证
      • 2.2.3 Spring + Mybatis Plus
        • 2.2.3.1 涉及依赖
        • 2.2.3.2 添加 Spring 配置
        • 2.2.3.3 添加实体类
        • 2.2.2.4 添加业务代码并测试验证
  • 示例
  • 总结

引言

Java 语言相关的应用开发中,事务(Transaction)是其中一个核心概念,尤其是在涉及数据库操作时。理解并正确使用事务,可以确保应用系统数据的完整性和一致性。本文 Huazie 将带您从 Java 事务的基础概念出发,通过不同场景的事物管理实操,帮助您快速入门 Java 事务。

1. Java事务基础概念

1.1 什么是事务?

事务是数据库操作的基本执行单元,它要么完全地执行,要么完全地不执行。

事务作为一个逻辑工作单位,其关键特性【数据的完整性和一致性】就体现在其 ACID 属性上,如下:

  • 原子性(Atomicity):事务是一个原子操作单元,其对数据的修改要么全都执行,要么全都不执行。
  • 一致性(Consistency):事务必须使数据库从一个一致性状态变换到另一个一致性状态。
  • 隔离性(Isolation):事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  • 持久性(Durability):持久性是指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其执行结果有任何影响。

1.2 为什么需要事务?

我们先来想一下如下的场景:

多个数据库操作之间,有部分操作成功,部分操作失败,会咋样?

显然这个时候,应用系统的数据就会处于不一致的状态。这种不一致可能会带来非常严重的后果,包括但不限于如下:

  • 数据错误:由于某些操作成功而某些操作失败,数据可能处于一个中间状态,既不完全符合操作前的状态,也不符合操作后预期的状态。
  • 业务逻辑错误:当数据出现不一致时,基于这些数据执行的业务逻辑可能会出现错误。例如,在一个订单系统中,如果订单的创建和库存的减少操作没有同时成功,那么可能会导致订单状态与库存状态不匹配,从而影响整个业务流程。
  • 系统可靠性降低:一个不可靠的数据系统可能会导致更多的错误和故障,需要更多的维护和支持,从而增加运营成本。

因此,为了避免这种情况,在多个数据库操作之间,我们就需要一种机制来确保这些操作要么全部成功,要么全部失败。而事务正是为了解决这个问题而存在的。

2. Java事务管理

Java 中,我们可以使用 JDBCSpringJPAMyBatis(MyBatis Plus) 等框架来管理数据库事务。这些框架提供了丰富的 API 和工具,使我们能够轻松地管理事务。

2.1 JDBC 的事务管理

JDBC 中,我们可以通过设置 Connection 对象的 autoCommit 属性来开启或关闭事务。

  • autoCommittrue 时,每次执行 SQL 语句都会自动提交事务;
  • autoCommitfalse 时,我们需要手动调用 commit()rollback() 方法来提交或回滚事务。

我们来看一个简单的 JDBC 事务管理示例:

	@Test
    public void testJDBCTransaction() throws Exception {
        // flea-config.xml 中配置
        FleaJDBCConfig.init(DBSystemEnum.MySQL.getName(), "fleajpatest");

        Connection conn = null;
        PreparedStatement pstmt1 = null;
        PreparedStatement pstmt2 = null;
        try {
            conn = FleaJDBCConfig.getConfig().getConnection();
            // 关闭自动提交
            conn.setAutoCommit(false);

            // 执行第一条SQL语句
            String sql1 = "UPDATE student SET stu_age = stu_age-10 WHERE stu_name='huazie'";
            pstmt1 = conn.prepareStatement(sql1);
            pstmt1.executeUpdate();

            LOGGER.debug("执行第一条SQL语句");
            // 模拟异常
            throwEx();

            // 执行第二条SQL语句
            String sql2 = "UPDATE student SET stu_age = stu_age+12 WHERE stu_name='huazie'";
            pstmt2 = conn.prepareStatement(sql2);
            pstmt2.executeUpdate();

            LOGGER.debug("执行第二条SQL语句");
            // 提交事务
            conn.commit();

            LOGGER.debug("提交事物");
        } catch (SQLException e) {
            if (null != conn) {
                try {
                    // 回滚事务
                    conn.rollback();
                    LOGGER.debug("回滚事物");
                } catch (SQLException ex) {
                }
            }
        } finally {
            // 关闭资源
            if (null != pstmt2) pstmt2.close();
            if (null != pstmt1) pstmt1.close();
            if (null != conn) conn.close();
        }

    }

    private void throwEx() throws SQLException {
        throw new SQLException("Test Exception");
    }

在开始测试之前,先来看看要操作的数据【如下红框所示】:

在这里插入图片描述

上述示例中,执行完第一条语句之后,模拟抛出异常,我们来运行一下,可以看到如下结果:

在这里插入图片描述

同时检查数据库中发现数据没变,说明第一条 SQL 语句也没有执行成功,可见已经被回滚了。

现在,我们将模拟异常的代码去除,然后断点调试下看下两条语句执行完,但还没有提交的情况,如下:

在这里插入图片描述

从上述截图,可知连接在提交之前,数据还是原来的。

继续执行,连接被提交,我们可以看到 stu_age 已经被更改为 22,可见示例中的两条 SQL 语句已经执行成功。

在这里插入图片描述

2.2 Spring 事务管理

Spring 提供了强大的声明式事务管理功能,我们可以将事务管理与业务逻辑分离,在不修改业务代码的情况下,为业务方法添加事务支持。

Spring 事务管理的核心接口是 PlatformTransactionManager,它是所有事务管理器的抽象。Spring 提供了多种事务管理器的实现。我们可以通过配置来选择合适的事务管理器,以便于 Spring 结合 JDBCJPAMyBatis(Mybatis Plus) 等框架来管理事物。

2.2.1 Spring + JDBC

2.2.1.1 添加 Spring 配置

在 Spring 配置文件中,我们需要配置数据源,如下:

	<bean id="jdbcDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/fleajpatest?useUnicode=true&amp;characterEncoding=UTF-8" />
        <property name="username" value="替换成你的MySQL用户名" />
        <property name="password" value="替换成你的MySQL用户密码" />
    </bean>

配置 JdbcTemplate,用于使用 JDBC 操作数据库,如下:

	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="jdbcDataSource"/>
    </bean>

配置事物管理器 DataSourceTransactionManager,如下:

	<bean id="jdbcTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="jdbcDataSource" />
    </bean>

最后,在 Spring 配置文件中,我们需要开启对应的事务管理功能,如下:

    <tx:annotation-driven transaction-manager="jdbcTransactionManager"/>
2.2.1.2 添加业务代码并测试验证

下面让我们添加业务代码,来演示下具体的事物管理,如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class StudentService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Transactional("jdbcTransactionManager")
    public void service() throws SQLException {

        // 插入一条记录
        String sql = "insert into student(stu_name, stu_age, stu_sex, stu_state) values(?, ?, ?, ?)";
        jdbcTemplate.update(sql, "LGH", "18", 1, 1);

        sql = "update student set stu_state = ? where stu_name = ?";
        jdbcTemplate.update(sql, 0, "LGH");

        throwEx();
    }

    private void throwEx() throws SQLException {
        throw new SQLException("Test Exception");
    }
}

需要注意的是,这里抛出的异常还是 SQLException,它是 java.lang.Exception 的子类。

继续添加测试代码如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class StudentSpringJDBCTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(StudentSpringJDBCTest.class);

    @Resource(name = "studentService")
    private StudentService studentService;

    @Test
    public void testSpringJDBCTransaction() throws Exception {
        studentService.service();
    }
}

现在运行上述测试代码,结果如下:

在这里插入图片描述

从上图可知,虽然这里抛出了一场,但是实际数据还是提交成功了。

那这里是什么原因呢?

这就要提到刚才抛出的异常了【即 SQLException】,Spring 事物管理能处理的异常一定要是RuntimeException及其子类 或者 Error及其子类,否则事物无法回滚。

可见如下截图【这块后续有时间展开讲解下】:

在这里插入图片描述
在这里插入图片描述

我们重新来修改一下业务代码,抛出 RuntimeException 异常 :

 @Transactional("jdbcTransactionManager")
    public void service() throws RuntimeException {

        // 省略。。。

        throwEx();
    }

    private void throwEx() throws RuntimeException {
        throw new RuntimeException("Test Exception");
    }

继续运行测试代码,执行结果如下:

在这里插入图片描述

可以看到,除了之前新增的,本次要处理的 SQL 并没有执行到数据库。

现在,让我们把抛出异常的代码去掉,运行结果如下:

在这里插入图片描述

从上截图中可知,要处理的 SQL 都已经成功执行。

2.2.2 Spring + JPA

2.2.2.1 JPA相关依赖

Spring Data JPA 依赖

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
    <version>2.5.0</version>
</dependency>

EclipseLink 的 JPA 实现依赖

<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>eclipselink</artifactId>
    <version>2.5.0</version>
</dependency>
2.2.2.2 添加 JPA 配置

在资源文件夹的 META-INF 目录下添加 fleajpa-persistence.xml,配置持久化单元的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

	<persistence-unit name="fleajpa" transaction-type="RESOURCE_LOCAL">
		<!-- provider -->
		<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
		<!-- Connection JDBC -->
		<class>com.huazie.fleadbtest.jpa.common.entity.Student</class>
		<exclude-unlisted-classes>true</exclude-unlisted-classes>

		<properties>
			<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
			<property name="javax.persistence.jdbc.url"
				value="jdbc:mysql://localhost:3306/fleajpatest?useUnicode=true&amp;characterEncoding=UTF-8" />
			<property name="javax.persistence.jdbc.user" value="替换成你的MySQL用户名" />
			<property name="javax.persistence.jdbc.password" value="替换成你的MySQL用户密码" />
		</properties>
	</persistence-unit>

</persistence>

2.2.2.3 添加 Spring 配置

Spring 配置文件中,添加 JPA 相关的默认 Bean,用来初始化 LocalContainerEntityManagerFactoryBean,如下:

	<bean id="defaultPersistenceManager"
          class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
        <property name="persistenceXmlLocations">
            <!-- 可以配置多个持久单元 -->
            <list>
                <value>classpath:META-INF/fleajpa-persistence.xml</value>
            </list>
        </property>
    </bean>

    <bean id="defaultPersistenceProvider" class="org.eclipse.persistence.jpa.PersistenceProvider"/>

    <!--<bean id="defaultLoadTimeWeaver" class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>-->

    <bean id="defaultVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
        <property name="showSql" value="true"/>
    </bean>

    <bean id="defaultJpaDialect" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect"/>

配置 LocalContainerEntityManagerFactoryBean,它是 Spring Data JPA 中用于创建和管理 EntityManagerFactory 的一个核心类,如下所示:

	<bean id="fleaJpaEntityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitManager" ref="defaultPersistenceManager"/>
        <property name="persistenceUnitName" value="fleajpa"/>
        <property name="persistenceProvider" ref="defaultPersistenceProvider"/>
        <property name="jpaVendorAdapter" ref="defaultVendorAdapter"/>
        <property name="jpaDialect" ref="defaultJpaDialect"/>
        <property name="jpaPropertyMap">
            <map>
                <entry key="eclipselink.weaving" value="false"/>
                <entry key="eclipselink.logging.thread" value="true"/>
            </map>
        </property>
    </bean>

配置 JPA 事物管理器 JpaTransactionManager,如下:

	<bean id="fleaJpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="fleaJpaEntityManagerFactory"/>
    </bean>

启用 Spring Data JPA 仓库扫描,如下:

    <jpa:repositories base-package="com.huazie.fleadbtest.jpa.repository"
                      entity-manager-factory-ref="fleaJpaEntityManagerFactory"
                      transaction-manager-ref="fleaJpaTransactionManager"/>

最后,在 Spring 配置文件中,还需要开启对应的事务管理功能,如下:

    <tx:annotation-driven transaction-manager="fleaJpaTransactionManager"/>
2.2.2.4 添加实体类

新建如下实体类 Student,对应测试表 student

@Entity
@Table(name = "student")
public class Student implements FleaEntity {

    private static final long serialVersionUID = 1267943552214677159L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "STUDENT_SEQ")
    @SequenceGenerator(name = "STUDENT_SEQ")
    @Column(name = "stu_id", unique = true, nullable = false)
    private Long stuId; // 学生编号

    @Column(name = "stu_name", nullable = false)
    private String stuName; // 学生姓名

    @Column(name = "stu_age", nullable = false)
    private Integer stuAge; // 学生年龄

    @Column(name = "stu_sex", nullable = false)
    private Integer stuSex; // 学生性别(1:男 2:女)

    @Column(name = "stu_state", nullable = false)
    private Integer stuState; // 学生状态(0:删除 1:在用)

	// ... 省略get和set方法
    
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
}
2.2.2.5 添加业务代码并测试验证

首先,添加 StudentRepository,用于访问 Student 实体相关的数据库操作的接口

public interface StudentRepository extends JpaRepository<Student, Long> {
}

接着,添加如下业务代码:

@Service
public class StudentService {

    @Autowired
    private StudentRepository studentRepository;

    @Transactional("fleaJpaTransactionManager")
    public void service() throws RuntimeException {

        Student student = new Student();
        student.setStuName("杜甫");
        student.setStuAge(35);
        student.setStuSex(1);
        student.setStuState(1);

        studentRepository.save(student);

        student.setStuState(0);
        studentRepository.save(student);

        throwEx();
    }

    private void throwEx() throws RuntimeException {
        throw new RuntimeException("Test Exception");
    }
}

最后,添加自测类,如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class StudentSpringJPATest {

    @Resource(name = "studentService")
    private StudentService studentService;

    @Test
    public void testSpringJDBCTransaction() throws Exception {
        studentService.service();
    }
}

一切准备就绪,我们来运行上述自测类,结果如下:

在这里插入图片描述

从上述截图可见,业务代码抛出了异常,相关的数据库操作并未执行成功。【注意: 这里抛出的异常也一定要是RuntimeException及其子类 或者 Error及其子类

将抛出异常的代码注释掉,再来运行一下看看,如下:

在这里插入图片描述

从上图中,我们可以看出业务代码的数据操作已经成功执行到了数据库中。

2.2.3 Spring + Mybatis Plus

2.2.3.1 涉及依赖

alibaba 的数据库连接池 druid 依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.0</version>
</dependency>

mybatis 依赖:

<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
	<version>3.5.9</version>
</dependency>

Mybatis Plus 依赖:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>3.5.1</version>
</dependency>
2.2.3.2 添加 Spring 配置

在 Spring 配置文件中,添加数据源配置,如下:

	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/fleajpatest?useUnicode=true&amp;characterEncoding=UTF-8" />
        <property name="username" value="替换成你的MySQL用户名" />
        <property name="password" value="替换成你的MySQL用户密码" />
    </bean>

配置 SqlSessionFactory,如下所示:

	<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="typeAliasesPackage" value="com.huazie.fleadbtest.mybatisplus.entity"/>
    </bean>

配置 MapperScan,如下所示:

	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.huazie.fleadbtest.mybatisplus.mapper"/>
    </bean>

配置事物管理器 DataSourceTransactionManager,如下:

	<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

最后,在 Spring 配置文件中,还需要开启对应的事务管理功能,如下:

    <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
2.2.3.3 添加实体类

新建如下实体类 Student,对应测试表 student

@Data
@TableName("student")
public class Student {

    @TableId(value = "stu_id", type = IdType.AUTO)
    private Long stuId; // 学生编号

    @TableField(value = "stu_name")
    private String stuName; // 学生姓名

    @TableField(value = "stu_age")
    private Integer stuAge; // 学生年龄

    @TableField(value = "stu_sex")
    private Integer stuSex; // 学生性别(1:男 2:女)

    @TableField(value = "stu_state")
    private Integer stuState; // 学生状态(0:删除 1:在用)

}
2.2.2.4 添加业务代码并测试验证

添加学生服务层接口类,如下:

public interface IStudentService extends IService<Student> {
    void service() throws RuntimeException;
}

添加学生服务层实现类,如下:

@Service("studentServiceImpl")
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements IStudentService {

    @Override
    @Transactional("dataSourceTransactionManager")
    public void service() throws RuntimeException {
        Student student = new Student();
        student.setStuName("李白");
        student.setStuAge(25);
        student.setStuSex(1);
        student.setStuState(1);

        baseMapper.insert(student);

        student.setStuState(0);

        baseMapper.updateById(student);

        throwEx();
    }

    private void throwEx() throws RuntimeException {
        throw new RuntimeException("Test Exception");
    }

}

最后,添加自测类,如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class StudentServiceSpringTest {

    @Resource(name = "studentServiceImpl")
    private IStudentService studentService;

    @Test
    public void testSpringMybatisPlusTransaction() throws RuntimeException {
        studentService.service();
    }
}

现在,我们可以运行上述自测类,结果如下:

在这里插入图片描述

从上述截图可见,自定义异常已经被抛出,并且数据库中也没有执行成功,说明事物已经回滚了。

现在将抛出异常的代码注释掉,再来运行看看,如下:

在这里插入图片描述

从上图可知,相关数据库操作已经成功执行。

示例

相关演示示例请查看 GitHub 上的 flea-db-test 测试项目。

总结

本文 HuazieJava 事物的基础概念出发,带大家通过不同的事物管理方式进行实践,进一步加深了对 Java 事物的理解。

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

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

相关文章

在做题中学习(62):矩阵区域和

1314. 矩阵区域和 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a;二维前缀和 思路&#xff1a;读题画图才能理解意思&#xff1a;dun点点的是mat中的一个数&#xff0c;而要求的answer同位置的数 以点为中心上下左右延长 k 个单位所围成长方形的和。 因为最后answ…

拷贝构造、移动构造、拷贝赋值、移动赋值

最近在学习C的拷贝构造函数时发现一个问题&#xff1a;在函数中返回局部的类对象时&#xff0c;并没有调用拷贝构造函数。针对这个问题&#xff0c;查阅了一些资料&#xff0c;这里记录整理一下。 调用拷贝构造函数的三种情况&#xff1a; ① 用一个类去初始化另一个对象时&a…

PLC自动化行业的发展前景好吗?

第一先说plc的薪资&#xff1a; 整体的平均薪资还是非常可观的&#xff0c;在1.3w/月左右。 当然PLC是需要经验积累的&#xff0c;尤其需要拥有大型的系统设计经验&#xff0c;那将会在PLC以至于自动化行业都会吃的开。所以待遇是与自身的经验&#xff0c;能力&#xff0c;所在…

Java设计模式:享元模式实现高效对象共享与内存优化(十一)

码到三十五 &#xff1a; 个人主页 目录 一、引言二、享元设计模式的概念1. 对象状态的划分2. 共享机制 三、享元设计模式的组成四、享元设计模式的工作原理五、享元模式的使用六、享元设计模式的优点和适用场景结语 [参见]&#xff1a; Java设计模式&#xff1a;核心概述&…

GDPU Java 天码行空13

&#xff08;一&#xff09;实验目的 1、掌握JAVA中与网络程序开发相关的知识点&#xff1b; 2、理解并掌握网络编程开发思想及方法&#xff1b; 3、熟悉项目开发的分包方法和依据&#xff1b; 4、实现聊天室中客服端和服务器端的实现方法&#xff1b; 5、熟悉多线程程序开发方…

第五届武汉纺织大学ACM程序设计竞赛 个人题解(待补完)

前言&#xff1a; 上周周日教练要求打的一场重现赛&#xff0c;时长五个小时&#xff0c;题目难度还行&#xff0c;除了部分题目前我还写不出来之外&#xff0c;大部分题都写完或补完了&#xff0c;这边给出比赛链接和我的代码&#xff08;有些是队友的&#xff09;和题解。 正…

工作中有哪些超级好用的C/C++程序库?

视频和讲义发布在这里&#xff1a; B站链接

Spring框架温习

Spring Spring是一个全面的、企业应用开发一站式的解决方案&#xff0c;贯穿表现层、业务层、持久层。但是 Spring仍然可以和其他的框架无缝整合。 Spring 特点&#xff1a; 轻量级、控制反转、面向切面、容器、框架集合 Spring 核心组件&#xff1a; Spring 常用模块&…

Leecode热题100---二分查找--4:寻找两个正序数组的中位数

题目&#xff1a; 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 解法1、暴力解法&#xff08;归并&#xff09; 思路&#xff1a; 合并 nums1&#xff0c;nums2 为第三个数组 排序第三个数…

亚马逊VC账号产品热销,在美国哪些智能小家电产品最好卖?

亚马逊VC账号产品在美国市场的热销&#xff0c;反映了消费者对于特定智能小家电产品的强烈需求。智能小家电产品因其实用性、便捷性和科技感&#xff0c;近年来在美国市场备受追捧。 以下是一些在亚马逊VC账号上热销的智能小家电产品&#xff1a; 智能扫地机器人 这类产品在美…

【传知代码】自监督高效图像去噪(论文复现)

前言&#xff1a;在数字化时代&#xff0c;图像已成为我们生活、工作和学习的重要组成部分。然而&#xff0c;随着图像获取方式的多样化&#xff0c;图像质量问题也逐渐凸显出来。噪声&#xff0c;作为影响图像质量的关键因素之一&#xff0c;不仅会降低图像的视觉效果&#xf…

STM32读写内部FLASH读取芯片id

文章目录 读写内部Flash接线程序编写测试效果补充 读取芯片id代码编写 读写内部Flash 接线 程序编写 首先使用ThisFlash.c来写入flash的基本操作&#xff0c;写入、读取、擦除&#xff0c;然后使用Store.c配合数组来进行主存与flash的交互 ThisFlash.c #include "stm32…

Spring Cloud Gateway 集成 Nacos、Knife4j

目录 1、gateway网关配置1.1 pom 配置2.2 配置文件1.3 yaml 配置 2、其他服务配置2.1 pom 配置2.2 配置文件2.3 yaml 配置 3、界面访问4、其他 官方文档地址&#xff1a;Spring Cloud Gateway集成Knife4j 官方完整源码&#xff1a;https://gitee.com/xiaoym/swagger-bootstrap-…

Redis篇 哈希表在redis中的命令

哈希命令 一.哈希表的基本认识二. 哈希表在redis中的命令1.hset,hget2.hdel3.hkeys,hvals4.hexists5.hgetall6.hmget7.hlen8.hincrby和hincrbyfloat 一.哈希表的基本认识 在JAVA数据结构中&#xff0c;我们就已经接触到了哈希表&#xff0c; 在当时&#xff0c;我们主要用到的哈…

第16章-超声波跟随功能 基于STM32的三路超声波自动跟随小车 毕业设计 课程设计

第16章-超声波跟随功能 无PID跟随功能 //超声波跟随if(HC_SR04_Read() > 25){motorForward();//前进HAL_Delay(100);}if(HC_SR04_Read() < 20){motorBackward();//后退HAL_Delay(100);}PID跟随功能 在pid.c中定义一组PID参数 tPid pidFollow; //定距离跟随PIDpidFol…

CISP难度将加大?还考不考啊...

最新消息&#xff1a;CISP即将调整知识体系大纲&#xff0c;更新题库&#xff0c;后续考试难度加大。 最近几年&#xff0c;CISP改版地比较频繁&#xff0c;难度也在不断上升&#xff0c;因此各位小伙伴有考CISP想法的尽早考。 随着《网络安全法》、《网络空间安全战略》、《…

牛客NC324 下一个更大的数(三)【中等 双指针 Java/Go/PHP/C++】参考lintcode 52 · 下一个排列

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/475da0d4e37a481bacf9a09b5a059199 思路 第一步&#xff1a;获取数字上每一个数&#xff0c;组成数组arr 第二步&#xff1a;利用“下一个排列” 问题解题方法来继续作答&#xff0c;步骤&#xff1a;利用lintc…

oracle12.1 rac 静默dbca教程(百分之百创建成功)

修改原响应文件 [oracleprimary1 database]$ cd response/ [oracleprimary1 response]$ ls dbca.rsp db_install.rsp netca.rsp [oracleprimary1 response]$ vi dbca.rsp 默认即可 数据库类型内存占比按需选择 运行静默创建实例脚本 [oracleprimary1 response]$ dbca -silen…

虚拟机改IP地址

使用场景&#xff1a;当你从另一台电脑复制一个VMware虚拟机过来&#xff0c;就是遇到一个问题&#xff0c;虚拟的IP地址不一样&#xff08;比如&#xff0c;一个是192.168.1.3&#xff0c;另一个是192.168.2.4&#xff0c;由于‘1’和‘2’不同&#xff0c;不是同一网段&#…

探索自动发邮件的奥秘:从配置到实现

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;邮件自动化的魅力 二、配置环境&#xff1a;选择适合的SMTP服务器 示…