六、Spring 声明式事务

本章概要

  • 声明式事务概念
    • 编程式事务
    • 声明式事务
    • Spring事务管理器
  • 基于注解的声明式事务
    • 准备工作
    • 基本事务控制
    • 事务属性:只读
    • 事务属性:超时时间
    • 事务属性:事务异常
    • 事务属性:事务隔离级别
    • 事务属性:事务传播行为

6.1 声明式事务概念

6.1.1 编程式事务

编程式事务是指手动编写程序来管理事务,即通过编写代码的方式直接控制事务的提交和回滚。在 Java 中,通常使用事务管理器(如 Spring 中的 PlatformTransactionManager)来实现编程式事务。

编程式事务的主要优点是灵活性高,可以按照自己的需求来控制事务的粒度、模式等等。但是,编写大量的事务控制代码容易出现问题,对代码的可读性和可维护性有一定影响。

Connection conn = ...;try {// 开启事务:关闭事务的自动提交conn.setAutoCommit(false);// 核心操作// 业务代码// 提交事务conn.commit();}catch(Exception e){// 回滚事务conn.rollBack();}finally{// 释放数据库连接conn.close();}

编程式的实现方式存在缺陷:

  • 细节没有被屏蔽:具体操作过程中,所有细节都需要程序员自己来完成,比较繁琐。
  • 代码复用性不高:如果没有有效抽取出来,每次实现功能都需要自己编写代码,代码就没有得到复用。

6.1.2 声明式事务

声明式事务是指使用注解或 XML 配置的方式来控制事务的提交和回滚。

开发者只需要添加配置即可, 具体事务的实现由第三方框架实现,避免我们直接进行事务操作!

使用声明式事务可以将事务的控制和业务逻辑分离开来,提高代码的可读性和可维护性。

区别:

  • 编程式事务需要手动编写代码来管理事务
  • 而声明式事务可以通过配置文件或注解来控制事务。

6.1.3 Spring事务管理器

  1. Spring声明式事务对应依赖
  • spring-tx: 包含声明式事务实现的基本规范(事务管理器规范接口和事务增强等等)
  • spring-jdbc: 包含DataSource方式事务管理器实现类DataSourceTransactionManager
  • spring-orm: 包含其他持久层框架的事务管理器实现类例如:Hibernate/Jpa等
  1. Spring声明式事务对应事务管理器接口

在这里插入图片描述

现在要使用的事务管理器是org.springframework.jdbc.datasource.DataSourceTransactionManager,将来整合 JDBC方式、JdbcTemplate方式、Mybatis方式的事务实现!DataSourceTransactionManager类中的主要方法:

  • doBegin():开启事务
  • doSuspend():挂起事务
  • doResume():恢复挂起的事务
  • doCommit():提交事务
  • doRollback():回滚事务

6.2 基于注解的声明式事务

6.2.1 准备工作

  1. 准备项目 spring-tx-annotation
<dependencies><!--spring context依赖--><!--当你引入Spring Context依赖之后,表示将Spring的基础依赖引入了--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.6</version></dependency><!--junit5测试--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.3.1</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>6.0.6</version><scope>test</scope></dependency><dependency><groupId>jakarta.annotation</groupId><artifactId>jakarta.annotation-api</artifactId><version>2.1.1</version></dependency><!-- 数据库驱动 和 连接池--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.25</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency><!-- spring-jdbc --><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>6.0.6</version></dependency><!-- 声明式事务依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>6.0.6</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>6.0.6</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>6.0.6</version></dependency>
</dependencies>
  1. 外部配置文件 jdbc.properties
atguigu.url=jdbc:mysql://localhost:3306/studb
atguigu.driver=com.mysql.cj.jdbc.Driver
atguigu.username=root
atguigu.password=root
  1. spring配置文件
@Configuration
@ComponentScan("com.atguigu")
@PropertySource("classpath:jdbc.properties")
public class JavaConfig {@Value("${atguigu.driver}")private String driver;@Value("${atguigu.url}")private String url;@Value("${atguigu.username}")private String username;@Value("${atguigu.password}")private String password;//druid连接池@Beanpublic DataSource dataSource(){DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(driver);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}@Bean//jdbcTemplatepublic JdbcTemplate jdbcTemplate(DataSource dataSource){JdbcTemplate jdbcTemplate = new JdbcTemplate();jdbcTemplate.setDataSource(dataSource);return jdbcTemplate;}}
  1. 准备dao/service层

dao

@Repository
public class StudentDao {@Autowiredprivate JdbcTemplate jdbcTemplate;public void updateNameById(String name,Integer id){String sql = "update students set name = ? where id = ? ;";int rows = jdbcTemplate.update(sql, name, id);}public void updateAgeById(Integer age,Integer id){String sql = "update students set age = ? where id = ? ;";jdbcTemplate.update(sql,age,id);}
}

service

@Service
public class StudentService {@Autowiredprivate StudentDao studentDao;public void changeInfo(){studentDao.updateAgeById(100,1);System.out.println("-----------");studentDao.updateNameById("test1",1);}
}
  1. 测试环境搭建
/*** projectName: com.atguigu.test** description:*/
@SpringJUnitConfig(JavaConfig.class)
public class TxTest {@Autowiredprivate StudentService studentService;@Testpublic void  testTx(){studentService.changeInfo();}
}

在这里插入图片描述

6.2.2 基本事务控制

  1. 配置事务管理器数据库相关的配置
/**** description: 数据库和连接池配置类*/
@Configuration
@ComponentScan("com.atguigu")
@PropertySource(value = "classpath:jdbc.properties")
@EnableTransactionManagement
public class DataSourceConfig {/*** 实例化dataSource加入到ioc容器* @param url* @param driver* @param username* @param password* @return*/@Beanpublic DataSource dataSource(@Value("${atguigu.url}")String url,@Value("${atguigu.driver}")String driver,@Value("${atguigu.username}")String username,@Value("${atguigu.password}")String password){DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(driver);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}/*** 实例化JdbcTemplate对象,需要使用ioc中的DataSource* @param dataSource* @return*/@Beanpublic JdbcTemplate jdbcTemplate(DataSource dataSource){JdbcTemplate jdbcTemplate = new JdbcTemplate();jdbcTemplate.setDataSource(dataSource);return jdbcTemplate;}/*** 装配事务管理实现对象* @param dataSource* @return*/@Beanpublic TransactionManager transactionManager(DataSource dataSource){return new DataSourceTransactionManager(dataSource);}}
  1. 使用声明事务注解 @Transactional
@Service
public class StudentService {@Autowiredprivate StudentDao studentDao;@Transactionalpublic void changeInfo(){studentDao.updateAgeById(100,1);System.out.println("-----------");int i = 1/0;studentDao.updateNameById("test1",1);}
}
  1. 测试事务效果
/**** description:*/
//@SpringJUnitConfig(locations = "classpath:application.xml")
@SpringJUnitConfig(classes = DataSourceConfig.class)
public class TxTest {@Autowiredprivate StudentService studentService;@Testpublic void  testTx(){studentService.changeInfo();}
}

在这里插入图片描述

6.2.3 事务属性:只读

  1. 只读介绍

对一个查询操作来说,如果我们把它设置成只读,就能够明确告诉数据库,这个操作不涉及写操作。这样数据库就能够针对查询操作来进行优化。

  1. 设置方式
// readOnly = true把当前事务设置为只读 默认是false!
@Transactional(readOnly = true)
  1. 针对DML动作设置只读模式

会抛出下面异常:Caused by: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed

  1. @Transactional注解放在类上
  • 生效原则

如果一个类中每一个方法上都使用了 @Transactional 注解,那么就可以将 @Transactional 注解提取到类上。反过来说:@Transactional 注解在类级别标记,会影响到类中的每一个方法。

同时,类级别标记的 @Transactional 注解中设置的事务属性也会延续影响到方法执行时的事务属性。除非在方法上又设置了 @Transactional 注解。对一个方法来说,离它最近的 @Transactional 注解中的事务属性设置生效。

  • 用法举例

在类级别@Transactional注解中设置只读,这样类中所有的查询方法都不需要设置@Transactional注解了。因为对查询操作来说,其他属性通常不需要设置,所以使用公共设置即可。

然后在这个基础上,对增删改方法设置@Transactional注解 readOnly 属性为 false。

@Service
@Transactional(readOnly = true)
public class EmpService {// 为了便于核对数据库操作结果,不要修改同一条记录@Transactional(readOnly = false)public void updateTwice(……) {……}// readOnly = true把当前事务设置为只读// @Transactional(readOnly = true)public String getEmpName(Integer empId) {……}}

6.2.4 事务属性:超时时间

  1. 需求

事务在执行过程中,有可能因为遇到某些问题,导致程序卡住,从而长时间占用数据库资源。而长时间占用资源,大概率是因为程序运行出现了问题(可能是Java程序或MySQL数据库或网络连接等等)。

此时这个很可能出问题的程序应该被回滚,撤销它已做的操作,事务结束,把资源让出来,让其他正常程序可以执行。概括来说就是一句话:超时回滚,释放资源。

  1. 设置超时时间
@Service
public class StudentService {@Autowiredprivate StudentDao studentDao;/*** timeout设置事务超时时间,单位秒! 默认: -1 永不超时,不限制事务时间!*/@Transactional(readOnly = false,timeout = 3)public void changeInfo(){studentDao.updateAgeById(100,1);//休眠4秒,等待方法超时!try {Thread.sleep(4000);} catch (InterruptedException e) {throw new RuntimeException(e);}studentDao.updateNameById("test1",1);}
}
  1. 测试超时效果

执行抛出事务超时异常

在这里插入图片描述

6.2.5 事务属性:事务异常

  1. 默认情况

默认只针对运行时异常回滚,编译时异常不回滚。情景模拟代码如下:

@Service
public class StudentService {@Autowiredprivate StudentDao studentDao;/*** timeout设置事务超时时间,单位秒! 默认: -1 永不超时,不限制事务时间!* rollbackFor = 指定哪些异常才会回滚,默认是 RuntimeException and Error 异常方可回滚!* noRollbackFor = 指定哪些异常不会回滚, 默认没有指定,如果指定,应该在rollbackFor的范围内!*/@Transactional(readOnly = false,timeout = 3)public void changeInfo() throws FileNotFoundException {studentDao.updateAgeById(100,1);//主动抛出一个检查异常,测试! 发现不会回滚,因为不在rollbackFor的默认范围内! new FileInputStream("xxxx");studentDao.updateNameById("test1",1);}
}

在这里插入图片描述

  1. 设置回滚异常

rollbackFor属性:指定哪些异常类才会回滚,默认是 RuntimeException and Error 异常方可回滚!

/*** timeout设置事务超时时间,单位秒! 默认: -1 永不超时,不限制事务时间!* rollbackFor = 指定哪些异常才会回滚,默认是 RuntimeException and Error 异常方可回滚!* noRollbackFor = 指定哪些异常不会回滚, 默认没有指定,如果指定,应该在rollbackFor的范围内!*/
@Transactional(readOnly = false, timeout = 3, rollbackFor = Exception.class)
public void changeInfo() throws FileNotFoundException {studentDao.updateAgeById(100, 1);// 主动抛出一个检查异常,测试! 发现不会回滚,因为不在rollbackFor的默认范围内! new FileInputStream("xxxx");studentDao.updateNameById("test1", 1);
}

在这里插入图片描述

  1. 设置不回滚的异常

在默认设置和已有设置的基础上,再指定一个异常类型,碰到它不回滚。

noRollbackFor属性:指定哪些异常不会回滚, 默认没有指定,如果指定,应该在rollbackFor的范围内!

@Service
public class StudentService {@Autowiredprivate StudentDao studentDao;/*** timeout设置事务超时时间,单位秒! 默认: -1 永不超时,不限制事务时间!* rollbackFor = 指定哪些异常才会回滚,默认是 RuntimeException and Error 异常方可回滚!* noRollbackFor = 指定哪些异常不会回滚, 默认没有指定,如果指定,应该在rollbackFor的范围内!*/@Transactional(readOnly = false,timeout = 3,rollbackFor = Exception.class,noRollbackFor = FileNotFoundException.class)public void changeInfo() throws FileNotFoundException {studentDao.updateAgeById(100,1);//主动抛出一个检查异常,测试! 发现不会回滚,因为不在rollbackFor的默认范围内!new FileInputStream("xxxx");studentDao.updateNameById("test1",1);}
}

在这里插入图片描述

6.2.6 事务属性:事务隔离级别

  1. 事务隔离级别

数据库事务的隔离级别是指在多个事务并发执行时,数据库系统为了保证数据一致性所遵循的规定。常见的隔离级别包括:

  • 读未提交(Read Uncommitted):事务可以读取未被提交的数据,容易产生脏读、不可重复读和幻读等问题。实现简单但不太安全,一般不用。
  • 读已提交(Read Committed):事务只能读取已经提交的数据,可以避免脏读问题,但可能引发不可重复读和幻读。
  • 可重复读(Repeatable Read):在一个事务中,相同的查询将返回相同的结果集,不管其他事务对数据做了什么修改。可以避免脏读和不可重复读,但仍有幻读的问题。
  • 串行化(Serializable):最高的隔离级别,完全禁止了并发,只允许一个事务执行完毕之后才能执行另一个事务。可以避免以上所有问题,但效率较低,不适用于高并发场景。不同的隔离级别适用于不同的场景,需要根据实际业务需求进行选择和调整。
  1. 事务隔离级别设置
package com.atguigu.service;import com.atguigu.dao.StudentDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;import java.io.FileInputStream;
import java.io.FileNotFoundException;@Service
public class StudentService {@Autowiredprivate StudentDao studentDao;/*** timeout设置事务超时时间,单位秒! 默认: -1 永不超时,不限制事务时间!* rollbackFor = 指定哪些异常才会回滚,默认是 RuntimeException and Error 异常方可回滚!* noRollbackFor = 指定哪些异常不会回滚, 默认没有指定,如果指定,应该在rollbackFor的范围内!* isolation = 设置事务的隔离级别,mysql默认是repeatable read!*/@Transactional(readOnly = false,timeout = 3,rollbackFor = Exception.class,noRollbackFor = FileNotFoundException.class,isolation = Isolation.REPEATABLE_READ)public void changeInfo() throws FileNotFoundException {studentDao.updateAgeById(100,1);//主动抛出一个检查异常,测试! 发现不会回滚,因为不在rollbackFor的默认范围内!new FileInputStream("xxxx");studentDao.updateNameById("test1",1);}
}

在这里插入图片描述

6.2.7 事务属性:事务传播行为

  1. 事务传播行为要研究的问题

在这里插入图片描述

举例代码:

@Transactional
public void MethodA(){// ...MethodB();// ...
}//在被调用的子方法中设置传播行为,代表如何处理调用的事务! 是加入,还是新事务等!
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void MethodB(){// ...
}
  1. propagation属性

@Transactional 注解通过 propagation 属性设置事务的传播行为。它的默认值是:

Propagation propagation() default Propagation.REQUIRED;

propagation 属性的可选值由 org.springframework.transaction.annotation.Propagation 枚举类提供:

名称含义
REQUIRED 默认值如果父方法有事务,就加入,如果没有就新建自己独立!
REQUIRES_NEW不管父方法是否有事务,我都新建事务,都是独立的!
  1. 测试
  • 声明两个业务方法
@Service
public class StudentService {@Autowiredprivate StudentDao studentDao;/*** timeout设置事务超时时间,单位秒! 默认: -1 永不超时,不限制事务时间!* rollbackFor = 指定哪些异常才会回滚,默认是 RuntimeException and Error 异常方可回滚!* noRollbackFor = 指定哪些异常不会回滚, 默认没有指定,如果指定,应该在rollbackFor的范围内!* isolation = 设置事务的隔离级别,mysql默认是repeatable read!*/@Transactional(readOnly = false,timeout = 3,rollbackFor = Exception.class,noRollbackFor = FileNotFoundException.class,isolation = Isolation.REPEATABLE_READ)public void changeInfo() throws FileNotFoundException {studentDao.updateAgeById(100,1);//主动抛出一个检查异常,测试! 发现不会回滚,因为不在rollbackFor的默认范围内!new FileInputStream("xxxx");studentDao.updateNameById("test1",1);}/*** 声明两个独立修改数据库的事务业务方法*/@Transactional(propagation = Propagation.REQUIRED)public void changeAge(){studentDao.updateAgeById(99,1);}@Transactional(propagation = Propagation.REQUIRED)public void changeName(){studentDao.updateNameById("test2",1);int i = 1/0;}}
  • 声明一个整合业务方法
@Service
public class TopService {@Autowiredprivate StudentService studentService;@Transactionalpublic void  topService(){studentService.changeAge();studentService.changeName();}
}
  • 添加传播行为测试
@SpringJUnitConfig(JavaConfig.class)
public class TxTest {@Autowiredprivate StudentService studentService;@Autowiredprivate TopService topService;@Testpublic void  testTx() throws FileNotFoundException {topService.topService();}
}

在这里插入图片描述

注意:
在同一个类中,对于@Transactional注解的方法调用,事务传播行为不会生效。这是因为Spring框架中使用代理模式实现了事务机制,在同一个类中的方法调用并不经过代理,而是通过对象的方法调用,因此@Transactional注解的设置不会被代理捕获,也就不会产生任何事务传播行为的效果。

  1. 其他传播行为值(了解)
  • Propagation.REQUIRED:如果当前存在事务,则加入当前事务,否则创建一个新事务。
  • Propagation.REQUIRES_NEW:创建一个新事务,并在新事务中执行。如果当前存在事务,则挂起当前事务,即使新事务抛出异常,也不会影响当前事务。
  • Propagation.NESTED:如果当前存在事务,则在该事务中嵌套一个新事务,如果没有事务,则与Propagation.REQUIRED一样。
  • Propagation.SUPPORTS:如果当前存在事务,则加入该事务,否则以非事务方式执行。
  • Propagation.NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,挂起该事务。
  • Propagation.MANDATORY:必须在一个已有的事务中执行,否则抛出异常。
  • Propagation.NEVER:必须在没有事务的情况下执行,否则抛出异常。

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

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

相关文章

使用 Ubuntu 20.04 进行初始服务器设置

前些天发现了一个人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;最重要的屌图甚多&#xff0c;忍不住分享一下给大家。点击跳转到网站。 使用 Ubuntu 20.04 进行初始服务器设置 介绍 首次创建新的 Ubuntu 20.04 服务器时&#xff0c;应该执行一些重…

RKE安装k8s及部署高可用rancher之证书在外面的7层LB(nginx中) 7层负载均衡

一 了解 Rancher 1 推荐架构 安装 Rancher 的方式有两种&#xff1a;单节点安装和高可用集群安装。因为单节点安装只适用于测试和 demo 环境&#xff0c;而且单节点安装和高可用集群安装之间不能进行数据迁移&#xff0c;所以推荐从一开始就使用高可用集群安装的方式安装 Ran…

正则表达式解析与应用:深度剖析正则表达式的威力

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

前端页面锚点跳转

一&#xff0c;页面 二&#xff0c;获取需要跳转的标签class或者id 三&#xff0c;调用跳转方法 如果你的标签有唯一的ID&#xff0c;那么用getElementById方法更好 点击即可跳转锚点

柯桥职场英语中千万别把英文邮件中的“OOO”理解成“哦哦哦”!不然可就尴尬了!

有的同学工作中跟老外打交道比较多 尤其是写邮件&#xff0c;除了要把事情交代清楚 还有一些缩写我们也必须掌握 就拿发邮件时老外最爱用到的“OOO”来说 千万不要把“OOO”理解成“噢噢噢” 今天给大家分享几个关于邮件的常用表达 它们真正的意思你都知道吗 01 “OOO”可…

移动通信原理与关键技术学习(2)

1.多径信道滤波器表示&#xff0c;多径信道可以认为是线性时变滤波器&#xff0c;接收信号为发送信号与信道冲激响应的卷积。 2.调制就是对信号源的信息进行处理加到载波上&#xff0c;使其变为适合于信道传输的形式的过程&#xff0c;就是使载波随信号而改变的技术。 3.进行调…

java程序是如何执行的

我们开发的.java文件也就是源文件在经过了java编译器的编译之后变成了.class文件也就是字节码文件&#xff0c;当jvm在执行过程中用到某个类&#xff0c;而这个类还未被加载到内存中时&#xff0c;会由类加载器负责这个类的加载&#xff0c;整个的加载过程分成五步&#xff1a;…

Databend 的安装配置和使用

介绍 Databend 是一个内置在 Rust 中的开源、弹性和工作负载感知的云数据仓库&#xff0c;为 Snowflake 提供了具有成本效益的替代方案&#xff0c;专门对最大的数据集进行复杂分析而设计。 性能&#xff1a; 在存储对象上&#xff0c;能快速进行数据分析。没有索引和分区&a…

linux系统颜色的设置

颜色 颜色控制码 颜色 echo -e "\033[字背景颜色;文字颜色m字符串\033[0m" //设置文本颜色 echo -e "\033[0;32m字符串\033[0m" //设置文本为绿色&#xff0c;背景没有颜色 echo -e "\033[0;$(($RANDOM%730))m字符串\033[0m" //随机生…

【PythonRS】栅格数据/图片位深度(bit)转换

关于栅格数据/图片的位深度&#xff08;eg.8bit、16bit、32bit&#xff09;转换之前我就发过一篇文章&#xff0c;【Python&RS】基于GDAL栅格数据/图片位深度&#xff08;bit&#xff09;转换。但是最近在使用的时候发现好像效果不行&#xff0c;有时候转换不成功&#xff…

批量转换QQ音乐音频文件格式:从FLAC、OGG到MP3

目录 工具和库批量转换脚本结语 我们经常需要将音频文件从一种格式转换为另一种以满足不同的需求。例如&#xff0c;从QQ音乐中下载的 FLAC格式虽然提供了无损的音质&#xff0c;但文件大小较大&#xff0c;不适合在所有设备上播放。而MP3格式由于其较小的文件大小和广泛的兼容…

创意无限:火星文和变异字体的魅力世界

在互联网的浩瀚星空里&#xff0c;火星文和变异字体如同璀璨的繁星&#xff0c;照亮了网络世界的角落。它们以独特的创意和视觉冲击力&#xff0c;吸引着无数网友的目光。让我们一起走进这个充满创意和想象力的世界&#xff0c;感受火星文和变异字体的无限魅力。 火星文生成器…

软件测试|SQL中的LIKE模糊匹配该怎么用?

简介 在SQL&#xff08;Structured Query Language&#xff09;中&#xff0c;LIKE是一种用于模糊匹配的操作符。通过使用LIKE&#xff0c;我们可以根据模式匹配的方式进行数据检索&#xff0c;而不仅仅局限于完全匹配。本文将详细介绍SQL中LIKE操作符的语法、用法以及一些示例…

全志F1C100s Linux 系统编译出错:不能连接 github

环境 Ubuntu 20.04 LTS 64 位虚拟机 开发板:Lichee Pi Nano 源代码:GitHub - florpor/licheepi-nano 问题描述 该源码库使用了 git 子模块的概念,一个库中包含了 u-boot、Linux等代码库。不需要分别编译,一个 make 全搞定 编译时提示错误: >>> linux-hea…

Halcon根据特征值选择区域select_shape

Halcon根据特征值选择区域 关于提取图像的特征&#xff0c;比较常用的一个算子是select_shape算子&#xff0c;它能高效地根据特征提取出符合条件的区域。该算子的原型如下&#xff1a; select_shape (Regions : SelectedRegions : Features, Operation, Min, Max :)参数1和参…

win和linux打印tree命令目录结构命令

win 输入tree: cmd: tree 显示文件夹不显示文件 可以用相对路径&#xff1a;tree .\test_pipreqs 省略.\也可以&#xff1a;tree test_pipreqs 显示文件 上面只显示文件夹未能显示文件。我们继续看下面&#xff1a; cmd: tree [path] [/f] [/a] ----------/f 显示每个文件中文件…

修改 Git 仓库的远程地址

要修改 Git 仓库的远程地址&#xff0c;你可以使用以下命令&#xff1a; 首先&#xff0c;查看当前的远程地址列表&#xff0c;使用命令 git remote -v。如果你想修改已存在的远程地址&#xff0c;可以使用命令 git remote set-url <remote_name> <new_url>。在这…

【论文阅读笔记】Mip-NeRF 360: Unbounded Anti-Aliased Neural Radiance Fields

目录 概述摘要引言参数化效率歧义性 mip-NeRF场景和光线参数化从粗到细的在线蒸馏基于区间的模型的正则化实现细节实验限制总结&#xff1a;附录退火膨胀采样背景颜色 paper&#xff1a;https://arxiv.org/abs/2111.12077 code&#xff1a;https://github.com/google-research/…

【LeetCode】601. 体育馆的人流量

表&#xff1a;Stadium ------------------------ | Column Name | Type | ------------------------ | id | int | | visit_date | date | | people | int | ------------------------ visit_date 是该表中具有唯一值的列。 每日人流量…

Android 项目工程配置签名文件

1. Android签名证书(.keystore) Android平台打包发布apk应用&#xff0c;需要使用数字证书&#xff08;.keystore文件&#xff09;进行签名&#xff0c;用于表明开发者身份。   Android证书的生成是自助和免费的&#xff0c;不需要审批或付费。   可以使用JRE环境中的keyto…