spring-事务

news2024/11/26 19:52:07

spring-事务

事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成,它具有ACID特性。

为了在spring中更好的使用事务处理,首先介绍Spring中用于数据库操作的核心模板类JDBCTemplate

JDBCTemplate

JdbcTemplate是Spring框架中用于数据库操作的核心模板类。它封装了JDBC API,简化了数据库操作,并且提供了异常处理等功能。

使用步骤

1、依赖引入

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>6.0.6</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>6.0.9</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.16</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>6.0.6</version>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.10.0-M1</version>
    <scope>compile</scope>
</dependency>

2、创建jdbc.properties文件

jdbc.username=root
jdbc.password=zkpk
jdbc.url=jdbc:mysql://localhost:3306/spring
jdbc.driver=com.mysql.cj.jdbc.Driver

3、创建spring配置文件

<?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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--引入外部属性文件,创建数据源对象-->
    <context:property  erty-placeholder>
<!--创建Druid连接池的数据源-->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="${jdbc.url}"></property>
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
<!--创建jdbcTemplate对象,注入数据源-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="druidDataSource"></property>
    </bean>
</beans>

4、创建表并加入数据

DROP TABLE IF EXISTS `t_emp`;
CREATE TABLE `t_emp`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '姓名',
  `age` int NULL DEFAULT NULL COMMENT '年龄',
  `sex` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

5、实现CRUD

增删改操作
@SpringJUnitConfig(locations = "classpath:bean.xml")
public class JDBCTemplateTest {
    @Autowired
    private JdbcTemplate jdbcTemplate;


    //添加、修改和删除
    @Test
    public void testUpdate(){
       /* //1、添加操作
        //①编写sql
        String sql = "insert into t_emp values(null, ?, ?, ?)";
        //②调用jdbcTemplate中的方法,传入相关的参数
//        Object[] params = {"小明", 23, "男"};
        int effect = jdbcTemplate.update(sql, params);
        int effect1 = jdbcTemplate.update(sql, "小明", 23, "男");
        int effect2 = jdbcTemplate.update(sql, "louie", 24, "男");
        int effect3 = jdbcTemplate.update(sql, "Alex", 22, "男");
//        System.out.println("effect = " + effect1);
        /*effect = 1*/
        /*effect1 = 1*/
       
       /* //2、修改操作
        String sql = "update t_emp set name = ? where id = ?";
        int row = jdbcTemplate.update(sql, "Khan", 2);
        System.out.println("row = " + row);    
        /*row = 1*/
        
        //3、删除
        String sql = "delete from t_emp where id = ?";
        int delete = jdbcTemplate.update(sql, 2);
        System.out.println("delete = " + delete);
        /*delete = 1*/
    }
}
查询操作
//查询返回一个对象
@Test
public void testSelectObject(){
    String sql = "select * from t_emp where id = ?";
    /*//写法一
    //RowMapper用来对象封装
    Emp empResult = jdbcTemplate.queryForObject(sql,
            (rs, rowNum) -> {
                Emp emp = new Emp();
                emp.setId(rs.getInt("id"));
                emp.setName(rs.getString("name"));
                emp.setAge(rs.getInt("age"));
                emp.setSex(rs.getString("sex"));
                return emp;
            }, 1);
    System.out.println("empResult = " + empResult);*/
    /*empResult = Emp{id=1, name='小明', age=23, sex='男'}*/
    //写法二
    Emp result = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(Emp.class), 1);
    System.out.println(result);
    /*Emp{id=1, name='小明', age=23, sex='男'}*/
}
//查询返回list集合
@Test
public void testSelectList(){
    String sql = "select * from t_emp";
    List<Emp> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Emp.class));
    for (Emp emp : list) {
        System.out.println("emp = " + emp);
    }
    /*
    emp = Emp{id=1, name='小明', age=23, sex='男'}
    emp = Emp{id=3, name='louie', age=24, sex='男'}
    emp = Emp{id=4, name='Alex', age=22, sex='男'}
    * */
}
//返回单个值
@Test
public void testSelectOne(){
    String sql = "select count(1) from t_emp";
    Integer sum = jdbcTemplate.queryForObject(sql, Integer.class);
    System.out.println("sum = " + sum);
    /*sum = 3*/
}

事务的概念及Spring事务的管理模式

事务的基本概念

数据库事务(transaction)是访问并可能操作各个数据项的一个数据库操作序列,这些操作要么全部执行,要么都不执行,是一个不可分割的单位。事务由事务开始与事务结束事件执行的全部数据库操作组成。

特性(ACID)

原子性(atomicity):一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。
一致性(consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
隔离性(isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability):持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

Spring事务的管理模式

在Spring体系中,关于事务的管理有两种模式,分别是编程式事务和声明式事务。

编程式事务

事务功能的相关操作全部通过自己编写代码实现。

缺点

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

声明式事务

将固定功能的代码进行封装,使用者只需要在配置文件中进行简单的配置即可完成操作。

优点
  • 高开发效率
  • 消除了冗余代码
  • 框架会综合考虑相关领域中在实际开发环境下有可能遇到的各种问题,进行健壮性、性能等各个方面的优化。

基于注解的声明式事务

情景:用户买书过程

在这里插入图片描述

实现步骤
1、添加配置
<?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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--组件扫描-->
    <context:component-scan base-package="com.louis.affair"></context:component-scan>
<!--引入外部属性文件,创建数据源对象-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--创建Druid连接池的数据源-->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="${jdbc.url}"></property>
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
<!--创建jdbcTemplate对象,注入数据源-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="druidDataSource"></property>
    </bean>
</beans>
2、创建表

t_book

DROP TABLE IF EXISTS `t_book`;
CREATE TABLE `t_book`  (
  `book_id` int NOT NULL COMMENT '主键',
  `book_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '图书名称',
  `price` int NULL DEFAULT NULL COMMENT '价格',
  `stock` int UNSIGNED NULL DEFAULT NULL COMMENT '库存(无符号)',
  PRIMARY KEY (`book_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;


INSERT INTO `t_book` VALUES (1, '机器学习', 120, 100);
INSERT INTO `t_book` VALUES (2, 'KAfka', 80, 100);

t_user

DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user`  (
  `user_id` int NOT NULL COMMENT '主键',
  `username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户名',
  `balance` int UNSIGNED NULL DEFAULT NULL COMMENT '余额(无符号)',
  PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO `t_user` VALUES (1, 'Louie', 500);
3、创建controller、service和dao层

controller

@Controller
public class BookController {
    @Autowired
    private BookService bookService;

    //买书的方法:图书id和用户id
    public void buyBook(Integer bookId, Integer userId){
        //调用service方法
        bookService.buyBook(bookId, userId);
    }
}

service

@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookDao bookDao;

    @Override
    public void buyBook(Integer bookId, Integer userId) {
        //根据图书id查询图书价格
        Integer price = bookDao.selectBookById(bookId);
        //更新图书库存
        bookDao.updateBookById(bookId);
        //更新用户表余额
        bookDao.updateUserBalance(userId, price);
    }
}

dao

@Repository
public class BookDaoImpl implements BookDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public int selectBookById(Integer bookId) {
        String sql = "select price from t_book where book_id = ?";
        Integer price = jdbcTemplate.queryForObject(sql, Integer.class, bookId);
        return price;
    }

    @Override
    public void updateBookById(Integer bookId) {
        String sql = "update t_book set stock = stock - 1 where book_id = ?";
        jdbcTemplate.update(sql, bookId);
    }

    @Override
    public void updateUserBalance(Integer userId, Integer price) {
        String sql = "update t_user set balance = balance - ? where user_id = ?";
        jdbcTemplate.update(sql, price, userId);
    }
}
4、测试
@SpringJUnitConfig(locations = "classpath:bean.xml")
public class TestAffair {

    @Autowired
    private BookController controller;
    @Test
    public void testAffair(){
        controller.buyBook(1, 1);
    }
}

在这里插入图片描述

在这里插入图片描述

但是当用户余额不足时:(设置用户余额为50, 设置图书库存均为100)
再次运行会出现类似下面的异常情况。

Data truncation: BIGINT UNSIGNED value is out of range in '(`spring`.`t_user`.`balance` - xxx)'

在这里插入图片描述

在这里插入图片描述

可以使用添加事务的方式解决上面出现的问题。

步骤
1、添加事务配置

在spring配置文件中添加

<!--事务控制的配置-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="druidDataSource"></property>
    </bean>
<!--
开启事务的注解驱动
通过注解@Transactional所标识的方法或标识的类中所由的方法,都会被事务管理器管理事务
-->
<!--transaction-manager属性的默认值时transactionManager,如果事务管理器bean的id正好就是这个默认值,则可以省略这个属性-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
2、添加事务注解

因为service层标识业务逻辑层,一个方法标识一个完整的功能,因此处理事务一般在service层处理,在相关业务操作上添加注解@Transactional。

@Override
@Transactional
public void buyBook(Integer bookId, Integer userId) {
    //根据图书id查询图书价格
    Integer price = bookDao.selectBookById(bookId);
    //更新图书库存
    bookDao.updateBookById(bookId);
    //更新用户表余额
    bookDao.updateUserBalance(userId, price);
}

@Transactional注解标识的位置:标识在方法上,则只会影响该方法,标识在类上,则会影响类中所有的方法。

3、测试(恢复库存条件下)

在数据异常情况下同样会报相同错误,但表中数据不会被修改。

Data truncation: BIGINT UNSIGNED value is out of range in '(`spring`.`t_user`.`balance` - xxx)'

在这里插入图片描述

@Transactional属性

在这里插入图片描述

readOnly:只读,设置为true的时候,只能查询、不能修改和删除。
当数据库进行改、写操作会抛出异常。
timeout:超时,在设置的超时时间之内没有完成,抛出异常并回滚。
回滚策略,设置哪些异常回滚。
rollbackFor:需要设置一个异常的Class类型的对象
rollbackForClassName:需要设置一个字符串类型的全类名
noRollbackFor:需要设置一个Class类型的对象
norollbackForClassName:需要设置一个字符串类型的全类名
isolation:设置隔离级别,解决读的问题。

propagation:传播行为,事务方法之间的调用,事务如何使用。

传播行为(propagation)

Spring定义了一个枚举,一共有七种传播行为

REQUIRED:spring默认的事务传播行为,A方法调用B方法,如果A方法有事务,则B方法加入到A方法中的事务中,否则B方法自己开启一个新事务。

SUPPORTS:A方法调用B方法,如果A方法有事务,则B方法加入到A方法中的事务中,否则B方法自己使用非事务方式执行。

MANDATORY:只能在存在事务的方法中被调用,A方法调用B方法,如果A方法没事务,则B方法会抛出异常。

REQUIRES_NEW:A方法调用B方法,如果A方法有事务,则B方法把A方法的事务挂起,B方法自己重新开启一个新事务。

NOT_SUPPORTED:A方法调用B方法,如果A方法有事务,则B方法挂起A方法中的事务中,否则B方法自己使用非事务方式执行。

NEVER:不支持事务,A方法调用B方法,如果A方法有事务,则B方法会抛出异常

NESTED:同 Propagation.REQUIRED ,不过此传播属性还可以 保存状态节点,从而避免所有嵌套事务都回滚。

事务传播

添加用户多购买类CheckoutServiceImpl

@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookDao bookDao;

    @Override
    @Transactional()
    public void buyBook(Integer bookId, Integer userId) {
        //根据图书id查询图书价格
        Integer price = bookDao.selectBookById(bookId);
        //更新图书库存
        bookDao.updateBookById(bookId);
        //更新用户表余额
        bookDao.updateUserBalance(userId, price);
    }
}

添加Service实现

@Service
public class CheckoutServiceImpl implements CheckoutService {
    @Autowired
    private BookService bookService;
    /**
     * 顾客买多本书
     * @param bookIds
     * @param userId
     */
    @Transactional
    @Override
    public void checkout(Integer[] bookIds, Integer userId) {
        for(Integer bookId:bookIds){
            //调用业务逻辑层的方法
            bookService.buyBook(bookId, userId);
        }
    }
}

测试

@SpringJUnitConfig(locations = "classpath:bean.xml")
public class TestAffair {

    @Autowired
    private BookController controller;
//    @Test
//    public void testAffair(){
//        controller.buyBook(1, 1);
//    }
    @Test
    public void testTransaction(){
        Integer[] bookIds = {1, 2};
        controller.checkout(bookIds, 1);
    }
}

在这里插入图片描述

在这里插入图片描述

设置用户余额为150,设置事务传播属性为默认值去购买两本书,但是当前的余额只够买一本书的时候会报错,并且进行了回滚操作。如果设置事务传播属性为REQUIRES_NEW,则第一本书会成功购买。

全注解配置事务

配置类

@Configuration//表示这是一个配置类
@ComponentScan("com.louis.affair")
@EnableTransactionManagement//表示开启事务管理
public class SpringConfig {
    //连接池
    @Bean
    public DataSource getDataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/spring");
        dataSource.setUsername("root");
        dataSource.setPassword("zkpk");
        return dataSource;
    }

    //jdbcTemplate部分
    @Bean(name = "jdbcTemplate")
    public JdbcTemplate getJdbcTemplate(DataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }

    //事务管理器
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
    }
}

测试

@Test
public void testAllAnnotation(){
    AnnotationConfigApplicationContext annotationConfig = new AnnotationConfigApplicationContext(SpringConfig.class);
    BookController bookController = annotationConfig.getBean(BookController.class);
    Integer[] bookIds = {1,2};
    bookController.checkout(bookIds, 1);
}

基于XML的声明式事务(具体实现)

步骤

1、环境准备

创建模块,导入相关的依赖

2、创建spring配置文件

①开启组件扫描
②创建数据源
③创建JdbcTemplate,注入数据源
④创建事务管理器,注入数据源
⑤配置事务通知
⑥配置切入点表达式,把事务添加到方法上。

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--开启组件扫描-->
    <context:component-scan base-package="com.louis.affair.xmltx"></context:component-scan>
    <!--创建数据源对象-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
    </bean>
    <!--创建JdbcTemplate对象-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入数据源-->
        <property name="dataSource" ref="druidDataSource"></property>
    </bean>
    <!--创建事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="druidDataSource"></property>
    </bean>
    <!--配置事务增强(通知)-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--设置方法的规则. 例:表示以get开头的方法-->
            <tx:method name="buy*" read-only="true"/>
            <tx:method name="update*" read-only="false" propagation="REQUIRED"></tx:method>
        </tx:attributes>
    </tx:advice>
    <!--配置切入点和通知使用的方法-->
    <aop:config>
        <aop:pointcut id="pt" expression="execution(* com.louis.affair.xmltx.service.impl.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"></aop:advisor>
    </aop:config>
</beans>

设置用户余额为50,书库存均为100,(要记得添加aspectJ的依赖。)

3、测试
@SpringJUnitConfig(locations = "classpath:bean-xml.xml")
public class TestXmlTx {
    @Autowired
    private BookController bookController;

    @Test
    public void testXml(){
        bookController.buyBook(1,1);
    }
}

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

UE特效案例 —— 骷髅爆点

一&#xff0c;环境配置 创建默认地形Landscape&#xff0c;如给地形上材质需确定比例&#xff1b;添加环境主光源DirectionalLight&#xff0c;设置相应的强度和颜色&#xff1b;添加天光反射SkyLight&#xff0c;用于天空反射&#xff1b;添加指数级高度雾ExponentialHeightF…

C++笔记之循环引用与环状引用

C笔记之循环引用与环状引用 code review! 文章目录 C笔记之循环引用与环状引用1.C循环引用和环状引用描述的是同一种现象吗?2.环状引用3.环状引用现象举例——常见环状引用4.解决环状引用——使用前向声明5.环状引用现象举例——使用对象本身可能造成环状引用 1.C循环引用和…

MySQL_4

目录 一、日志 1、错误日志 2、二进制日志 2.1 介绍 2.2 格式 2.3 删除 3、查询日志 4、慢查询日志 二、主从复制 1、概述 2、原理 3、搭建 三、分库分表 1、介绍 1.1背景 1.2拆分策略 1.3垂直拆分 1.4水平拆分 1.5实现技术 2、Mycat概述 2.1 介绍 2.2 安装 2.3…

每日一题2023.7.22|链表的基本操作

链表的基本操作 题目描述 考察链表的基本操作 输入 输入数据只有一组&#xff0c;第一行有n1个整数&#xff0c;第一个整数是这行余下的整数数目n&#xff0c;后面是n个整数。这一行整数用来初始化列表的&#xff0c;并且输入的顺序与列表中的顺序相反&#xff0c;也就是说如果…

htmlCSS-----浮动

目录 前言&#xff1a; 浮动 1.浮动的效果 2.浮动的特点 3.浮动的写法 4.浮动的原理 5.浮动的作用 6.案例 7.浮动的缺陷与解决方式 浮动问题 解决方式 8.补充说明 前言&#xff1a; 浮动是html里面重要的一部分&#xff0c;前面我们学习了三种元素的类型&#xff08;…

element中table的表格更新数据之后保留原来的勾选状态

reserve-selection: 仅对 typeselection 的列有效&#xff0c;类型为 Boolean&#xff0c;为 true 则会在数据更新之后保留之前选中的数据&#xff08;需指定 row-key&#xff09; <el-table ref"table" :data"DataList" :row-key"rowKey"&g…

使用rknn-toolkit2把YOLOV5部署到OK3588上

使用rknn-toolkit2把YOLOV5部署到OK3588上 虚拟环境搭建软件包安装在PC机上运行yolov5目标检测 虚拟环境搭建 首先在PC的ubuntu系统安装虚拟环境&#xff1a; 我的服务器是ubuntu18.04版本&#xff0c;所以安装python3.6 conda create -n ok3588 python3.6 需要键盘输入y&…

【博客681】k8s list机制与resourceVersion语义

k8s list机制与resourceVersion语义 K8s 架构&#xff1a;环形层次视图 对于 K8s 集群&#xff0c;从内到外的几个组件和功能&#xff1a; etcd&#xff1a;持久化 KV 存储&#xff0c;集群资源&#xff08;pods/services/networkpolicies/…&#xff09;的唯一的权威数据&…

实例023 建立字体形状窗体

实例说明 大家都见过不规则形状的窗体吧&#xff0c;那么如何制作一个文字形的窗体呢&#xff1f;文字形窗体一般应用在屏幕提示中&#xff0c;如收款机屏幕等。运行本例&#xff0c;效果如图1.23所示。 技术要点 以前&#xff0c;创建字体形窗体是一个既费时又费人力的过程&…

K8S初级入门系列之七-控制器(Job/CronJob/Daemonset)

一、前言 前一章节我们介绍了RC&#xff0c;RS控制器&#xff0c;其主要针对在线业务Pod部署&#xff0c;比如nginx&#xff0c;这些业务是需要确保7*24持续运行的&#xff0c;还有一类离线业务&#xff0c;比如定时任务&#xff0c;大数据离线计算等&#xff0c;在有任务的才需…

在命令行模式、eclipse console下执行Java程序输入中文的几种情况尝试

介绍 在命令行模式下执行Java程序&#xff0c;如果输入中文&#xff0c;经常会出现和代码中的解码字符集不匹配的情况&#xff0c;导致结果不正确。 在命令行模式下执行Java程序&#xff0c;输入中文&#xff0c;其实是用某种字符集编码成字节流&#xff0c;Java程序读取该字节…

rk3588 双HDMI冲突问题与HDMI不能热插拔问题

问题一:HDMI不能热插拔问题 现象 rk3588在开发时现在发现只能在插入HDMI时上电才能输出信号,而当开机之后,再插入HDMI显示器则无信号。 分析 通过kernel显示,在开机后,插拔HMDI是有log提示的,说明内核能够检测到HDMI的插拔动作。 首先先排查软件问题,尝试重启显示进…

ssm项目配置,不再支持源选项 5。请使用 6 或更高版本。 不再支持目标选项 1.5。请使用 1.6 或更高版本。

ssm项目启动报错&#xff1a; 不再支持源选项 5。请使用 6 或更高版本。 不再支持目标选项 1.5。请使用 1.6 或更高版本 1.模块语言级别 2.设置模块目标字节码版本 3.pom文件指定jdk版本 <properties><project.build.soutceEncoding>UTF-8</project.build.sout…

SpringBoot3自动配置流程 SPI机制 核心注解 自定义starter

1. 自动配置流程 导入starter依赖导入autoconfigure寻找类路径下 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件启动&#xff0c;加载所有 自动配置类 xxxAutoConfiguration 给容器中配置功能组件组件参数绑定到 属性类中。xxxPrope…

运维高级学习---MySQL主从复制

MySQL内建的复制功能是构建大型&#xff0c;高性能应用程序的基础 通过将MySQL的某一台主机 (master)的数据复制到其他主机(slaves)上&#xff0c;并重新执行一遍来执行复制过程中一台服务器充当主服务器&#xff0c;而其他一个或多个其他服务器充当从服务器 为什么要做主从复…

用eNSP搭建一个最简单的网络系统

要求搭建如下网络系统&#xff1a; 相关知识&#xff1a; 路由器命令界面&#xff1a; 所有的设备进入后均名字为Huawai&#xff1b; < >代表了当下所在的配置模式&#xff1b; 不同模式具有不同的管理权限&#xff0c;可以完成不同的配置要求&#xff1b; 第一级模式 …

Excel 端口操作指南

通过将 EDI 报文可视化为 Excel&#xff0c;企业可以更好地了解和处理数据&#xff0c;提高工作效率&#xff0c;减少错误率。在未实现 EDI 系统和内部业务系统集成之前&#xff0c;Excel 方案则是一项可供选择的临时替代方案。 Excel方案的优点在于&#xff0c;无需对业务系统…

【深度学习笔记】随机梯度下降法

本专栏是网易云课堂人工智能课程《神经网络与深度学习》的学习笔记&#xff0c;视频由网易云课堂与 deeplearning.ai 联合出品&#xff0c;主讲人是吴恩达 Andrew Ng 教授。感兴趣的网友可以观看网易云课堂的视频进行深入学习&#xff0c;视频的链接如下&#xff1a; 神经网络和…

Qt图片编辑 - 在直线添加文字

在绘制一条直线时&#xff0c;比如说在直线中间输出文字&#xff0c;如下图所示 本质上不难&#xff0c;定位到位置&#xff0c;然后drawText就可以了 难就难在 文字要跟随线的斜率&#xff0c;例如 还有&#xff0c;文字最好保证在线的“上方” 首先是角度问题 这个角度跟线…

C#WinForm获取当前活动子窗体使用鼠标滚轮事件改变窗体大小

获取当前活动子窗体使用鼠标滚轮事件改变窗体大小&#xff0c;实例在文末&#xff0c;可下载。 这个主要分三个重点 第一步 我们需要让子窗体显示在父窗体中 Form22 new Form2(); Form22.TopLevel false; // 不是顶级窗体 //Form22.Parent this;// 设置父窗体 一定不要…