Spring事务深度学习

news2025/1/18 6:53:31

 jdbcTemp

Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作。

JdbcTemp的使用

 对应依赖

 <!-- MySQL驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>

        <!-- 数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.15</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.20</version>
        </dependency>

创建jdbc.properties属性文件

jdbc.user=root
jdbc.password=
jdbc.url=jdbc:mysql://localhost:3306/spring?characterEncoding=utf8&useSSL=false
jdbc.driver=com.mysql.cj.jdbc.Driver

创建bean.xml,配置配置文件引入和jdbctemp配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">
    <!--    引入外部的数据源配置文件-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <!--    通过数据源的文件将数据注入bean中-->
    <!--    通过${}在数据源的配置文件中进行取值-->
    <bean id="jdbcDriver" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClassName" value="${jdbc.driver}"></property>
    </bean>

    <!--    jdbcTemp配置-->
    <bean id="jdbcTemp" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="jdbcDriver"></property>
    </bean>
</beans>

创建数据库和表

CREATE DATABASE `spring`;

use `spring`;

CREATE TABLE `t_emp` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL COMMENT '姓名',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  `sex` varchar(2) DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

创建接收类

public class User {
    private Integer id;
    private String name;
    private Integer age;
    private String sex;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }
}

测试例子一(修改):

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

public class updateTest {

    //获取JdbcTemple
    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
    JdbcTemplate template = context.getBean(JdbcTemplate.class);

    //增加数据
    @org.junit.jupiter.api.Test
    public void addTest() {
        String sql = "insert into t_emp value(?, ?, ?, ?)";
        template.update(sql, null, "秃狼1", 18, "男");
    }
    //删除数据
    @org.junit.jupiter.api.Test
    public void deleteTest() {
        String sql = "delete from t_emp where id = ?";
        template.update(sql, 1);

    }
    //修改数据
    @org.junit.jupiter.api.Test
    public void updateTest() {
        String sql = "update t_emp set name = ? where id = ?";
        template.update(sql, "tolen", 2);
    }
}

测试例子二(查询):

import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

public class selectTest {

    //获取JdbcTemple
    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
    JdbcTemplate template = context.getBean(JdbcTemplate.class);
    //获取一个数据
    @Test
    public void queryForObject() {
        String sql = "select * from t_emp where id = ?";
        //BeanPropertyRowMapper自动封装数据的实现类,通过构造方法中传入的Class来确定封装类
        User user = template.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), 2);
        System.out.println(user.getName());
    }
    //获取所有数据
    @Test
    public void queryList() {
        String sql = "select * from t_emp";
        List<User> result = template.query(sql, new BeanPropertyRowMapper(User.class));
        for (int i = 0; i < result.size(); i++) {
            System.out.println(result.get(i).toString());
        }
    }
    //获取数据的个数
    @Test
    public void queryCount() {
        String sql = "select count(*) from t_emp";
        //在queryForObject中,如果第二个参数为Integer.class类型时,就是返回符合对应条件的数据的个数
        Integer integer = template.queryForObject(sql, Integer.class);
        System.out.println("所有的数据个数:" + integer);
    }
}

声明式事务

在Transactional注解中存在一下属性可以设置。 

 readOnly:默认为false,也就是不开启只读。(只读只允许select的查询操作,不能执行update操作)

timeout:表示超时时间,默认为-1,也就是永不超时。(这里的单位为Second)

rollbackForClassName/rollbackFor:表示当存在对应的类的时候就进行回滚,如果是ClassName的话,输入的值就是类的全路径,如果是For的话,就是对应类的.Class。

noRollbackForClassName/NoRollbackFor:与上述相反,就是不出现对应的类时就是进行回滚。

isolation:就是设置事务的隔离级别。用于处理脏读,不可重复读,幻读。

隔离级别脏读不可重复读幻读
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE

隔离级别一共有四种:

  • 读未提交:READ UNCOMMITTED

    允许Transaction01读取Transaction02未提交的修改。

  • 读已提交:READ COMMITTED、

    要求Transaction01只能读取Transaction02已提交的修改。

  • 可重复读:REPEATABLE READ

    确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它事务对这个字段进行更新。

  • 串行化:SERIALIZABLE

    确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其它事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。

对应的效果越好,执行效率就越低 

 propagation:设置传播行为。

常用的就是:@Transactional(propagation = Propagation.REQUIRED), 默认情况,表示如果当前线程上有已经开启的事务可用,那么就在这个事务中运行。

@Transactional(propagation = Propagation.REQUIRES_NEW),表示不管当前线程上是否有已经开启的事务,都要开启新事务。、

测试例子

在啊数据库中插入对应的数据。

CREATE TABLE `t_book` (
  `book_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `book_name` varchar(20) DEFAULT NULL COMMENT '图书名称',
  `price` int(11) DEFAULT NULL COMMENT '价格',
  `stock` int(10) unsigned DEFAULT NULL COMMENT '库存(无符号)',
  PRIMARY KEY (`book_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
insert  into `t_book`(`book_id`,`book_name`,`price`,`stock`) values (1,'斗破苍穹',80,100),(2,'斗罗大陆',50,100);
CREATE TABLE `t_user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` varchar(20) DEFAULT NULL COMMENT '用户名',
  `balance` int(10) unsigned DEFAULT NULL COMMENT '余额(无符号)',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
insert  into `t_user`(`user_id`,`username`,`balance`) values (1,'admin',50);

 配置bean.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:con="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--    引入外部的数据源配置文件-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <!--    通过数据源的文件将数据注入bean中-->
    <!--    通过${}在数据源的配置文件中进行取值-->
    <bean id="jdbcDriver" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClassName" value="${jdbc.driver}"></property>
    </bean>

    <!--    jdbcTemp配置-->
    <bean id="jdbcTemp" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="jdbcDriver"></property>
    </bean>

<!--    开启注解扫描-->
    <context:component-scan base-package="com.huang"></context:component-scan>
<!--    将事务类写入Bean容器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="jdbcDriver"></property>
    </bean>
<!--    开启事务注解驱动-->
    <tx:annotation-driven transaction-manager="transactionManager" />
</beans>

 对应的jdbc.properties文件

jdbc.user=root
jdbc.password=
jdbc.url=jdbc:mysql://localhost:3306/spring?characterEncoding=utf8&useSSL=false
jdbc.driver=com.mysql.cj.jdbc.Driver

创建三层架构

在service层中创建  BuyBookServiceImpl和CheckServiceImpl。

BuyBookServiceImpl:

import com.huang.Dao.BuyBookDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

//实现的接口就是简单的接口
@Service
public class BuyBookServiceImpl implements BuyBookService{

    @Autowired
    BuyBookDao buyBookDao;

    //添加事务
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void BuyBook(Integer bookId, Integer userId) {
        buyBookDao.setBook(bookId);
        Integer price = buyBookDao.getPrice(bookId);
        System.out.println(price);
        buyBookDao.setUser(userId, price);
    }
}

CheckServiceImpl:

package com.huang.Service;

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

@Service
public class CheckServiceImpl implements CheckService {

    @Autowired
    BuyBookService buyBookService;

    @Transactional
    @Override
    public void CheckBook(Integer[] bookIds, Integer userId) {
        for (int i = 0; i < bookIds.length; i++) {
            buyBookService.BuyBook(bookIds[i], userId);
        }
    }
}

Controller层

import com.huang.Service.BuyBookService;
import com.huang.Service.CheckService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class BuyBookController {

    @Autowired
    public BuyBookService buyBookService;
    @Autowired
    public CheckService checkService;

    public void buyBook(Integer[] bookIds, Integer userId) {
        checkService.CheckBook(bookIds, userId);
    }
}

编写测试例子

import com.huang.Controller.BuyBookController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

      ApplicationContext context =  new ClassPathXmlApplicationContext("bean.xml");

        @org.junit.jupiter.api.Test
    public void Test1() {
            BuyBookController controller = context.getBean(BuyBookController.class);
//            controller.buyBook(1,1);
            Integer[] num = new Integer[]{1,2};
            controller.buyBook(num, 1);
        }
}

进行最终测试,我们可以看到当设置为@Transactional(propagation=Propagation.REQUIRES_NEW)时,每此调用buyBookService.BuyBook方法时都会创建一个新的事务,这几个事务不会相互影响,成功和失败不会相关联,其实就是当作当前方法中没有事务,自己开一个事务

如果设置为@Transactional(propagation = Propagation.REQUIRED)时,每次调用buyBookService.BuyBook方法时都会先判断一下当前调用该方法的方法是否存在事务,如果存在事务就会将buyBookService.BuyBook方法的事务加入当前方法的事务中去,最终就能保住买书的这些操作要么都成功,要么都失败

使用全注解开发事务

 去除繁琐的bean.xml配置操作。

txConfig配置类

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@Configuration
@ComponentScan(value = "com.huang")
@EnableTransactionManagement
public class txConfig {

    //设置数据源
    @Bean
    public DataSource getDataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUrl("jdbc:mysql://localhost:3306/spring?characterEncoding=utf8&useSSL=false");
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("");
        druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        return druidDataSource;
    }

    //设置JdbcTemplate
    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
        JdbcTemplate template = new JdbcTemplate();
        template.setDataSource(dataSource);
        return template;
    }

    //设置事务
    @Bean
    public TransactionManager getTransactionManager(DataSource dataSource) {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }

}

编写测试类

import com.huang.Controller.BuyBookController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class txTest {
//全注解开发时获取ApplicationContext,要使用AnnotationConfigApplicationContext
    ApplicationContext context =  new AnnotationConfigApplicationContext(com.huang.config.txConfig.class);

    @org.junit.jupiter.api.Test
    public void Test1() {
        BuyBookController controller = context.getBean(BuyBookController.class);
//            controller.buyBook(1,1);
        Integer[] num = new Integer[]{1,2};
        controller.buyBook(num, 1);
    }
}

终达到同样效果。

使用全xml文件开发

设置bean.xml文件(使用上述同样的环境)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:con="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--    开启注解扫描-->
    <context:component-scan base-package="com.huang"></context:component-scan>

        <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <!--    通过数据源的文件将数据注入bean中-->
    <!--    通过${}在数据源的配置文件中进行取值-->
        <bean id="jdbcDriver" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="url" value="${jdbc.url}"></property>
            <property name="username" value="${jdbc.user}"></property>
            <property name="password" value="${jdbc.password}"></property>
            <property name="driverClassName" value="${jdbc.driver}"></property>
        </bean>


    <!--    jdbcTemp配置-->
    <bean id="jdbcTemp" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="jdbcDriver"></property>
    </bean>

<!--    将事务类写入Bean容器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="jdbcDriver"></property>
    </bean>

<!--手动配置事务切入点和增强事务通知-->

<!--    设置事务通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
<!--            这里就是将所有以Buy开头的方法设置非只读和传播行为设置为默认-->
            <tx:method name="Buy*" read-only="false" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
<!--设置切入点-->
    <aop:config>
<!--配置事务通知-->
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.huang.Service.*.*(..))"></aop:advisor>
    </aop:config>
</beans>

 不再需要在对应的方法上条件@Transactional。(已经完成了手动配置)

最终完成xml配置事务。

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

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

相关文章

已知相机内外参通过COLMAP进行稀疏/稠密模型重建操作过程

在https://colmap.github.io/faq.html#reconstruct-sparse-dense-model-from-known-camera-poses 中介绍了已知相机内外参如何通过COLMAP进行稀疏和稠密模型重建的过程&#xff0c;这里按照说明操作一遍&#xff1a; 在instant-ngp中&#xff0c;执行scripts/colmap2nerf.py时…

request页面代码逻辑

一. 封装请求基地址 在src目录下面建一个api文件夹 然后在文件夹里面新建一个专门放用户请求的use.js 用axios发送请求 在use.js文件夹里导入request 在src目录新建发送请求的页面并导入封装好的请求 然后把这个请求封装成一个函数&#xff0c;这个函数里需要传入两个参数。 …

Xavier或TX2配置ipv4地址

输入ifconfig查看本地ipv4地址&#xff0c;发现并没有设置&#xff0c;无法通过以太网与其他主机通信。下面来配置系统的以太网地址。 1、编辑文件/etc/network/interfaces: sudo gedit /etc/network/interfaces2、用下面的内容来替换有关eth0的行&#xff0c;并且将ip地址等信…

Java中抽象类和接口的区别,一文弄懂,图文并茂

目录 前言 1. 抽象类 1.1 定义 1.2 示例 1.3 使用 1.3.1代码-抽象类 1.3.2代码-抽象类继承类使用 1.3.3输出结果为&#xff1a; 1.4UML类图展示类间的关系 2. 接口 2.1 定义 2.2 示例 2.2.1代码-接口 2.3 使用 2.3.1代码-接口实现 2.3.2代码-接口实现类使用 2…

【Linux】驱动内核调试,没有几板斧,怎么能行?

目录 前言&#xff1a; 一、基础打印工具 &#xff08;1&#xff09;printk---最常用 ①Log Buffer: ②Console&#xff1a; ③RAM Console&#xff1a; &#xff08;2&#xff09;动态打印 ①动态打印与printk之间的区别联系 ②动态打印常用的例子 ③动态打印转为pri…

C语言实战 - 贪吃蛇(图形界面)

由于本人精力有限&#xff0c;暂时先把素材和代码放上&#xff0c;等以后有空再补教程。 目录 效果预览 准备工作 EasyX图形库 音频素材 代码编写 Transfer.h文件 game.cpp文件 main.c文件 效果预览 先来看一下最终成品效果 贪吃蛇图形界面 准备工作 EasyX图形库 这…

[230513] TPO72 | 2022年托福阅读真题第1/36篇 | 10:45

Invading Algae 目录 Invading Algae 全文 题目 Paragraph 1 P1 段落大意 问题1 Paragraph 2 P2 段落大意 问题2 *问题3* Paragraph 3 P3 段落大意 问题4 Paragraph 4 P4 段落大意 Paragraph 5 P5 段落大意 *问题5* *问题6* 问题7 问题8 问题9…

【计算机组成原理】第二章 运算方法和运算器

系列文章目录 第一章 计算系统概论 第二章 运算方法和运算器 第三章 多层次的存储器 第四章 指令系统 第五章 中央处理器 第六章 总线系统 第七章 外围设备 第八章 输入输出系统 文章目录 系列文章目录第一章 计算系统概论 **第二章 运算方法和运算器** 第三章 多层次的存储器…

C++移动构造函数

一、背景 拷贝构造函数又分为浅拷贝和深拷贝&#xff1a; 浅拷贝&#xff1a;当类中有指针时&#xff0c;直接复制&#xff0c;会使多个指针指向同一块内存&#xff0c;导致重复析构 深拷贝&#xff1a;每次都是重新赋值一份&#xff0c;这种方法内存消耗较大 因此C就提供…

一觉醒来Chat gpt就被淘汰了

目录 什么是Auto GPT&#xff1f; 与其他语言生成模型相比&#xff0c;Auto GPT具有以下优点 Auto GPT的能力 Auto GPT的能力非常强大&#xff0c;它可以应用于各种文本生成场景&#xff0c;包括但不限于以下几个方面 Auto GPT的历史 马斯克说&#xff1a;“ChatGPT 好得吓…

【C++从0到王者】第三站:类和对象(中)赋值运算符重载

文章目录 一、运算符重载1.运算符重载的使用2.运算符重载的注意事项 二、赋值运算符重载1.复制拷贝与拷贝构造2.赋值运算符重载的格式3.赋值运算符重载的实现4.赋值运算符重载的注意事项 一、运算符重载 1.运算符重载的使用 当我们实现一个日期类的时候&#xff0c;我们有时候…

一个*泰NL18-20漏电保护器的拆解

一个*泰NL18-20漏电保护器的拆解&#xff0c;购买很早了&#xff0c;损坏&#xff0c;按test按钮无动作&#xff0c;昨天用一个雷*的63A漏保替换了。 NL18-20的电流只有20A。显然不适合现在的运用了。而且是无灭弧装置&#xff0c;所以分断能力有限。 好奇&#xff0c;拆开来看…

C++PrimerPlus第四章编程题

编程题 题目总览 编程题题解 题目要求输入四次信息&#xff0c;有四次交互的输入&#xff08;in&#xff09;&#xff0c;最后在一口气列举出来。同时对于firstname与lastname进行了拼接&#xff0c;而且对于输入的成绩进行降级操作。同时对于名字name的要求是可以输入多个单词…

使用Flink MySQL cdc分别sink到ES、Kafka、Hudi

环境说明 [flink-1.13.1-bin-scala_2.11.tgz](https://archive.apache.org/dist/flink/flink-1.13.1/flink-1.13.1-bin-scala_2.11.tgz)[hadoop-2.7.3.tar.gz](https://archive.apache.org/dist/hadoop/common/hadoop-2.7.3/hadoop-2.7.3.tar.gz)[flink-cdc-connectors](https:…

【Base64】前后端图片交互(2)

使用Base64去处理前后端图片交互 一、Base64编码介绍二、java.util.Base64 介绍源码分析编码译码 三、使用 Base64 前后端图片交互&#xff08;实操&#xff09;四、效果展示五、总结 绪论&#xff1a;在此之前小编发过一次前后端交互处理的方式&#xff1a;前后端图片交互的简…

深度学习之图像分类(三):VGGNet

系列文章目录 本专栏介绍基于深度学习进行图像识别的经典和前沿模型&#xff0c;将持续更新&#xff0c;包括不仅限于&#xff1a;AlexNet&#xff0c; ZFNet&#xff0c;VGG&#xff0c;GoogLeNet&#xff0c;ResNet&#xff0c;DenseNet&#xff0c;SENet&#xff0c;Mobile…

Windows磁盘空间不够,发现DriverStore文件夹特别大

正想安装一个新的VS2022&#xff0c;但是发现C盘的空间已经不足&#xff0c; 显示为红色了&#xff0c;这样不能安装。只好找一下C盘的空间为什么不足了&#xff0c;后来发现有一个目录特别大&#xff0c;这个目录就是DriverStore文件夹。由于电脑已经运行5年了&#xff0c;也…

Java的线程

介绍线程 线程是系统调度的最小单元&#xff0c;一个进程可以包含多个线程&#xff0c;线程是负责执行二进制指令的。 每个线程有自己的程序计数器、栈&#xff08;Stack&#xff09;、寄存器&#xff08;Register&#xff09;、本地存储&#xff08;Thread Local&#xff09…

Linux的基本权限

基本权限 1.权限的概念2.Linux上的用户分类2.1. 如何切换用户&#xff1f; 3.Linux的权限管理3.1. 文件访问者的分类&#xff08;人&#xff09;3.2.文件类型和访问权限&#xff08;文件属性&#xff09;3.2.1. 文件类型3.2.2. 基本权限 3.3. 文件权限值的表示方法3.3.1. 字符表…

Mac中idea快捷键(Keymap->macOS)

背景&#xff1a; mac&#xff1a;MacBook Pro&#xff08;13英寸&#xff0c;M2&#xff0c;2022年&#xff09; 系统版本&#xff1a;12.4 idea快捷键配置&#xff1a;本文快捷键设置基于macOS&#xff08;Keymap->macOS&#xff09; 一、常用快捷键 1.commandF 在当前…