Spring framework day 03:Spring 整合 Mybatis(分页)

news2024/11/18 19:28:19

前言

在当今快速发展的软件开发领域,Java作为一种广泛使用的编程语言,以其强大的生态系统和丰富的框架而备受推崇。而在Java开发中,Spring框架几乎成为了事实上的标准,它为开发者提供了一种优雅且高效的方式来构建企业级应用程序。

而对于数据持久化方面,MyBatis作为一种流行的ORM(Object-Relational Mapping)框架,也成为了Java开发者的首选之一。它不仅提供了简单易用的SQL映射功能,还具备动态SQL、一级缓存、延迟加载等高级特性。

然而,在实际项目中,我们通常需要实现分页查询以处理大量数据。而Spring和MyBatis共同配合,可以实现简单而强大的分页功能。本文将介绍如何在Spring框架中整合MyBatis,并使用MyBatis的分页插件来实现分页查询功能。

在接下来的内容中,我们将逐步讲解如何设置环境、配置数据源和整合MyBatis。然后,我们将介绍如何使用MyBatis分页插件来实现分页查询,并提供实例演示。最后,我们将总结所学内容,并讨论一些可能遇到的常见问题和解决方案。

通过本文的学习,您将了解到使用Spring整合MyBatis(分页)的基本步骤和技巧,以及如何在实际项目中应用它们。希望本文能够帮助您更好地理解和使用这两个优秀的框架,并加快您的开发效率。

请继续阅读下文,我们将一步步引导您完成整合过程。

 一、使用 pagehelper 插件

PageHelper是一个开源的MyBatis分页插件,可以轻松地在MyBatis应用中实现分页查询功能。它提供了丰富的分页参数配置项,支持多种数据库(包括MySQL、Oracle、SqlServer等)和多种分页方式(包括普通分页、滚动分页、局部分页等),同时也提供了与Spring框架和SpringBoot框架的无缝集成。使用PageHelper可以大大简化分页查询的编写,提高代码的可读性和可维护性。

二、新建项目,结构如下

1、导入 spring 依赖
  <dependencies>
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.15</version>
        </dependency>
 
 
        <!-- spring 的核心依赖 -->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.23</version>
        </dependency>
 
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.23</version>
        </dependency>
 
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.5</version>
        </dependency>
 
 
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
 
 <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>
 
      <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
 
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <!-- Mybatis 依赖 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>
 
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>

           <!-- pagehelper 分页插件 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.3.2</version>
        </dependency>
 
 
 
    </dependencies>
 3、在 dao 包下的 CityDao 接口中添加一个方法
public interface CityDao {


    /**
     * 分页查询
     * @param pageNum
     * @param pageSize
     * @return
     */
    List<City> page(@Param("pageNum") Integer pageNum, @Param("pageSize") Integer pageSize);


}
4、在 service 包下的 CityService 接口中,添加一个方法
public interface CityService {


    PageInfo<City> page(Integer pageNum, Integer pageSize);

}
5、在 CityServiceImpl 实现类中添加一个方法

@Service
@Slf4j
@RequiredArgsConstructor
public class CityServiceImpl implements CityService {

    /**
     * 这里注入的是代理对象
     */
    private final CityDao cityDao;


    @Override
    public PageInfo<City> page(Integer pageNum, Integer pageSize) {
        List<City> list = cityDao.page(pageNum, pageSize);

        return new PageInfo<>(list);
    }

}

 在该示例中,CityServiceImpl类的主要逻辑如下:

  1. 使用@Service注解将CityServiceImpl类标识为一个Spring的服务组件。

  2. 使用@Slf4j注解引入lombok库提供的日志功能,可以通过log对象输出日志信息。

  3. 使用@RequiredArgsConstructor注解,通过Lombok生成带有final字段的构造函数。这里用于注入CityDao的代理对象。

  4. 实现page方法,该方法接收两个参数:pageNumpageSize,用于指定当前页码和每页的数据量。

  5. page方法中调用cityDao对象的page方法进行分页查询,传入pageNumpageSize作为参数。

  6. 将查询结果列表封装为PageInfo对象,并返回。

需要注意的是,CityDao的注入是通过构造函数注入的,而且注入的是代理对象,这是使用Spring整合MyBatis后的一种常见配置方案。

三、xml 配置

1、在 resources 包下新建一个 beans.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:mybatis="http://mybatis.org/schema/mybatis-spring"
       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://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 启用扫描 -->
    <context:component-scan base-package="edu.nf.ch02"/>

    <!-- 整合 druid 数据源连接池,其中将 DruidDataSource 核心类纳入
        spring 容器中管理,并指定相关的初始化方法以及销毁方法
    -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!-- 注入相关的连接属性 -->
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/psm"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <!-- 注入连接池的相关配置属性 -->
        <!-- 最大连接池数量 -->
        <property name="maxActive" value="200"/>
        <!-- 预先初始化 5 个连接放入连接池 -->
        <property name="initialSize" value="5"/>
        <!-- 最小空闲连接数 -->
        <property name="minIdle" value="5"/>
        <!-- 获取连接的最大等待时间,单位:毫秒 -->
        <property name="maxWait" value="2000"/>
        <!-- 连接保持空闲而不被驱逐出连接池的最小时间,单位:毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000"/>
        <!-- 检测连接的间隔时间,单位:毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000"/>
        <!-- 检测连接是否有效 -->
        <property name="testWhileIdle" value="true"/>
        <!-- 放回连接池时是否检查连接的有效性 -->
        <property name="testOnReturn" value="false"/>
        <!-- 定义一条伪 SQL,用于检查连接时是否可用 -->
        <property name="validationQuery" value="select 1"/>
        <!-- 是否缓存 PreparedStatements,MySQL 建议关闭 -->
        <property name="poolPreparedStatements" value="false"/>
    </bean>

    <!-- 装配 sqlSessionFactory ,也就是整合 mybatis 到 spring
         关键点在于将 mybatis 的相关配置放在 spring 中设置,并由
         容器来管理 sqlSessionFactory
     -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- SqlSessionFactoryBean 需要注入 DataSource -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 注入其他配置属性值 -->
        <!-- 指定实体类的包,用于创建别名 -->
        <property name="typeAliasesPackage" value="edu.nf.ch02"/>
        <!-- mapper 映射配置文件的路径 -->
        <property name="mapperLocations" value="classpath:mappers/*.xml"/>
        <!-- 设置分页插件 -->
        <property name="plugins">
            <!-- 装配分页拦截器 -->
            <bean class="com.github.pagehelper.PageInterceptor">
                <!-- 给分页拦截器注入相关的属性值 -->
                <property name="properties">
                    <props>
                        <!-- 设置数据库方言-->
                        <prop key="helperDialect">mysql</prop>
                        <!-- 启用分页参数注解支持 -->
                        <prop key="supportMethodsArguments">true</prop>
                        <!-- 分页合理化 -->
                        <prop key="reasonable">true</prop>
                    </props>
                </property>
            </bean>
        </property>
    </bean>

    <!-- 配置扫描 dao 接口所在的包,这样会利用动态代理在
         运行时创建所有 dao 接口的实现类 ,并自动注册到 spring 容器中
         -->
    <mybatis:scan base-package="edu.nf.ch02.dao"/>

</beans>

这是完整的 xml 配置,数据源、分页都在这里面交给容器管理。

以上是一个整合MyBatis和Spring的配置示例。主要包括以下几个关键点:

  1. 配置SqlSessionFactoryBean:通过该配置将MyBatis和Spring进行整合。需要注入DataSource,并设置其他属性值,比如实体类的包、mapper映射文件的路径等。

  2. 设置分页插件:在SqlSessionFactoryBean中配置分页插件。使用PageInterceptor作为分页拦截器,并注入相关属性值。可以设置数据库方言(如mysql)、启用分页参数注解支持和分页合理化等。

  3. 配置扫描dao接口包:通过mybatis:scan配置,指定扫描dao接口所在的包路径。这样会利用动态代理在运行时创建所有dao接口的实现类,并自动注册到Spring容器中。

通过以上配置,就可以完成MyBatis和Spring的整合,并且使用PageHelper插件实现方便的分页查询功能。

我们再来详细的分析每一个属性是干嘛的吧!

  1. dataSource:指定SqlSessionFactory所需的数据源。

  2. typeAliasesPackage:指定实体类(对应数据库表的映射类)的包路径,用于创建别名。

  3. mapperLocations:指定mapper XML文件所在的路径(可以是文件系统路径或者classpath路径)。

  4. plugins:设置MyBatis插件。可以配置多个插件,例如分页插件等。在该示例中,使用的是PageHelper分页插件。

  5. PageInterceptor:PageHelper分页插件提供了一个名为PageInterceptor的分页拦截器。该拦截器会在执行SQL语句前,自动将分页参数封装为Page对象,并且在SQL语句后自动进行分页处理。

  6. helperDialect:指定数据库方言(如mysql、oracle等),PageHelper根据不同的数据库方言自动选择相应的分页方法。

  7. supportMethodsArguments:启用分页参数注解支持。在service层的方法(dao接口对应的方法)上添加@Param注解,并使用PageHelper.startPage(pageNum, pageSize)方法即可完成分页功能。

  8. reasonable:分页合理化。如果该属性设置为true,则会在查询总记录数时,先判断当前查询是否是一个简单的查询(没有含有排序、聚合、子查询等特殊操作),如果是,则不进行count查询总记录数,直接返回limit查询结果。这样可以避免多余的count查询操作,提升性能。

  9. base-package:指定dao接口所在的包路径,用于自动扫描并注册dao接口。

 完整的 xml 配置已经完成了,现在我们来测试一下吧!

2、测试
@Slf4j
public class Main {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        // 从容器中获取动态创建的 CityDao 的代理对象
        CityService cityDao = context.getBean(CityService.class);
        PageInfo<City> list = cityDao.page(1,10);
        list.getList().forEach(page -> log.info(page.getCityName()));

    }

}

page(1,10):大家是不是很疑惑,我们调用的这个方法并不是 CityService 的方法,而是 CityDao 接口的实现类的方法,那这个实现类是怎么来的呢?我们并没有实现呀,这个实现类是动态代理帮我们动态生成的,不用我们自己实现,这就是使用框架的好处,帮我们节省了很多的重复操作。

运行结果

四、使用 Java 配置类配置(推荐)

1、在 resources 包下新建一个 db.properties 文件
driver = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:3306/psm
username= root
password = 123456
maxActive = 200
initialSize = 5
minIdle = 5
maxWait = 2000
minEvictableIdleTimeMillis = 300000
timeBetweenEvictionRunsMillis = 60000
testWhileIdle = true
testOnReturn = false
validationQuery = select 1
poolPreparedStatements = false
2、在 config 包下新建一个 AppConfig 类
@Configuration
// 扫描 dao 接口的包,动态生成 dao 接口的代理实现
// 等效于 xml 中的 <mybatis:scan>
@MapperScan(basePackages = "edu.nf.ch02.dao")
@ComponentScan(basePackages = "edu.nf.ch02")
public class AppConfig {

    /**
     * 装配 dataSource 数据源
     *
     * @return
     * @throws Exception
     */
    @Bean(initMethod = "init", destroyMethod = "close")
    public DruidDataSource dateSource() throws Exception {

        // 创建 Properties 对象
        Properties prop = new Properties();

        // 获取一个输入流来读取 properties 文件
        InputStream input = AppConfig.class.getClassLoader().getResourceAsStream("db.properties");

        // 将输入流加载到 properties 对象中
        prop.load(input);

        // 通过 DruidDataSourceFactory 来创建 DruidDataSource 实例
        DruidDataSource ds = (DruidDataSource) DruidDataSourceFactory.createDataSource(prop);

        return ds;
    }

    /**
     * 整合 mybatis ,装配 SqlSessionFactory
     *
     * @return
     */
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws Exception {
        // 创建 SqlSessionFactoryBean
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 注入数据源
        sqlSessionFactoryBean.setDataSource(dataSource);
        // 注入 mybatis 其他属性
        // 设置包的别名
        sqlSessionFactoryBean.setTypeAliasesPackage("edu.nf.ch02.entity");
        // mapper 映射配置文件的路径
        // 先创建一个资源路径解析器来查找源文件
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resolver.getResources("classpath:mappers/*.xml");
        sqlSessionFactoryBean.setMapperLocations(resources);

        // 设置分页插件
        PageInterceptor interceptor = new PageInterceptor();
        // 设置属性
        Properties properties = new Properties();
        properties.setProperty("helperDialect","mysql");
        properties.setProperty("supportMethodsArguments","true");
        properties.setProperty("reasonable","true");
        // 将分页属性设置到分页拦截器中
        interceptor.setProperties(properties);

        // 最后将分页拦截器设置到 SqlSessionFactoryBean 插件中
        sqlSessionFactoryBean.setPlugins(interceptor);

        // 返回 SqlSessionFactoryBean 给容器
        return sqlSessionFactoryBean;

    }

}

 我们来注重讲解一些分页的属性:

在这段代码中,首先创建了一个PageInterceptor对象,作为PageHelper分页插件的拦截器。然后,通过Properties对象设置了一些属性:

  1. helperDialect:指定数据库方言,这里设置为mysql

  2. supportMethodsArguments:启用分页参数注解支持,设置为true

  3. reasonable:分页合理化,设置为true

接下来,将这些分页属性设置到PageInterceptor对象中,使用interceptor.setProperties(properties)语句。

最后,通过sqlSessionFactoryBean.setPlugins(interceptor)将分页拦截器设置到SqlSessionFactoryBean中,以便在MyBatis的执行过程中应用分页插件。

通过这样的配置,就可以实现在MyBatis中使用PageHelper进行分页查询了。

 3、测试
@Slf4j
public class Main {

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        // 从容器中获取动态创建的 CityDao 的代理对象
        CityService cityDao = context.getBean(CityService.class);
        PageInfo<City> list = cityDao.page(1,10);
        list.getList().forEach(page -> log.info(page.getCityName()));

    }

}

运行结果

五、xml 配置和 Java配置类,配置分页属性的区别 

在配置分页属性时,可以使用两种方式:XML配置和Java配置类。下面是它们之间的区别:

  1. XML配置:

    • 在XML配置文件中,可以通过<plugins>元素来配置分页插件以及其属性。
    • 使用XML配置时,需要手动编写XML配置文件,并指定插件的相关属性。
    • 配置文件中的内容相对独立,可单独管理和维护。
  2. Java配置类:

    • 在Java配置类中,可以通过实例化分页插件对象并设置属性来配置分页插件。
    • 使用Java配置类时,可以直接在代码中进行配置和设置,无需单独的配置文件。
    • 配置类可以与其他配置类一起进行管理,方便集中管理和维护。

总体来说,XML配置适合于对配置文件进行统一管理的项目,而Java配置类适合于将配置与代码结合在一起的项目。选择使用哪种方式主要取决于项目的需求和个人偏好。无论选择哪种方式,配置的具体内容都是相同的,只是配置方式不同。

大家在开发中,根据自己的需求选择即可。

六、gitee 案例

完整代码地址:ch02 · qiuqiu/conformity-study - 码云 - 开源中国 (gitee.com)

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

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

相关文章

CVE-2019-0708漏洞实战

使用命令&#xff1a;search 0708搜索exp脚本 搜索网段中主机漏洞 use auxiliary/scanner/rdp/cve_2019_0708_bluekeep 照例&#xff0c;show options 看一下配置 设置网段set RHOSTS x.x.x.x run运行就行了 使用攻击模块 use exploit/windows/rdp/cve_2019_0708_bluekee…

PAM从入门到精通(十八)

接前一篇文章&#xff1a;PAM从入门到精通&#xff08;十七&#xff09; 本文参考&#xff1a; 《The Linux-PAM Application Developers Guide》 PAM 的应用开发和内部实现源码分析 先再来重温一下PAM系统架构&#xff1a; 更加形象的形式&#xff1a; 六、整体流程示例 2.…

Java学习笔记(五)——数组、排序和查找

一、数组 数组可以存放多个同一类型的数据。数组也是一种数据类型&#xff0c;是引用类型。即数组就是一组数据。 &#xff08;一&#xff09;数组的使用 1、使用方式1——动态初始化 &#xff08;1&#xff09;数组的定义&#xff1a; 数据类型 数组名[] new 数据类型…

ubuntu安装rust教程

参考【Rust】Linux上安装Rust开发环境 sudo apt-get install curl# 注意&#xff0c;不开代理很可能下不到&#xff0c;一直报403 export RUSTUP_DIST_SERVERhttps://mirrors.ustc.edu.cn/rust-static export RUSTUP_UPDATE_ROOThttps://mirrors.ustc.edu.cn/rust-static/rustu…

【软考-中级】系统集成项目管理工程师 【19 项目收尾管理】

持续更新。。。。。。。。。。。。。。。 【第十九章】收尾管理 &#xff08;选择题1分&#xff09; 19.1 项目验收19.2 项目总结19.3系统维护19.3.1软件项目的后续工作19.3.2系统集成项目的后续工作 19.4 项目后评价1. 信息系统目标评价2. 信息系统过程评价3. 信息系统效益评价…

带温度的softmax

用pytorch写一下使用带有温度的softmax的demo import torch import torch.nn.functional as F# 定义带有温度的softmax函数 def temperature_softmax(logits, temperature1.0):return F.softmax(logits / temperature, dim-1)# 输入logits logits torch.tensor([[1.0, 2.0, 3.…

专题二:滑动窗口【优选算法】

滑动窗口&#xff1a; 什么时候用&#xff1f; 同向双指针&#xff08;找单调性&#xff09; 怎么用&#xff1f; 1&#xff09;用left、right指针维护窗口 2&#xff09;进窗口&#xff08;right指针&#xff0c;更新窗口内的值&#xff09; 3&#xff09;判断 出窗口&#xf…

LeetCode13——罗马数字转整数

解题思想&#xff1a; 前后指针 左边比右边小 做减法 左边比右边大 做加法 最后一个数字直接加。 package keepcoding.leetcode.leetcode13;public class Result02 {public static void main(String[] args) {int result romanToInt("XIV");System.out.println(re…

基于springboot实现java学习平台项目【项目源码+论文说明】

基于springboot实现java学习平台演示 摘要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括学习平台的网络应用&#xff0c;在外国学习平台已经是很普遍的方式&#xff0c;不过国内的管理平台可能还处于起步阶段。学习平台具…

链表收尾(8.2)

例题解析 138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 1.拷贝节点插入原节点的后面&#xff08;核心&#xff09; 这样做的目的是方便找 random 节点&#xff0c;知道原节点可以找 random&#xff0c;知道上一个 random 可以找下一个 random 。 struct Node…

四、基本组件

1. Designer设计师 Designer程序是Qt官方推出的专为设计人员使用的UI设计工具&#xff0c;程序员可以使用此工具大幅降低UI设计的代码量。 Designer设计文件的格式是.ui&#xff0c;需要配合同名的头文件与源文件使用。.ui文件通常被称为界面文件&#xff0c;其内部是xml语法的…

(2023|ICML,LLM,标记掩蔽,并行解码)Muse:使用掩蔽生成 Transformer 的文本到图像生成

Muse: Text-To-Image Generation via Masked Generative Transformers 公众号&#xff1a;EDPJ&#xff08;添加 VX&#xff1a;CV_EDPJ 或直接进 Q 交流群&#xff1a;922230617 获取资料&#xff09; 目录 0. 摘要 1. 简介 2. 模型 2.1. 预训练文本编码器 2.2. 使用 V…

RabbitMQ队列及交换机的使用

目录 一、简单模型 1、首先控制台创建一个队列 2、父工程导入依赖 3、生产者配置文件 4、写测试类 5、消费者配置文件 6、消费者接收消息 二、WorkQueues模型 1、在控制台创建一个新的队列 2、生产者生产消息 3、创建两个消费者接收消息 4、能者多劳充分利用每一个消…

Power BI 傻瓜入门 2. Power BI的人员、方式和内容

本章内容包括&#xff1a; 识别潜在的企业Power BI用户使用Power BI解决数据生命周期问题区分使用Power BI生产的分析产品的类型 企业商业智能&#xff08;BI&#xff09;解决方案并非一刀切&#xff0c;这就是为什么像微软这样的供应商在Power BI利基市场的产品营销和分销中…

unity NPR 卡通渲染

文章目录 一、 介绍二、 素材准备三、 步骤四、 shader代码五、工程链接 一、 介绍 NPR是计算机图形学中的一类&#xff0c;即非真实感绘制(Non-photorealistic rendering)&#xff0c;主要用于模拟艺术式的绘制风格&#xff0c;也用于发展新绘制风格&#xff0c;形式一般是卡…

零基础Linux_20(进程信号)内核态和用户态+处理信号+不可重入函数+volatile

目录 1. 内核态和用户态 1.1 内核态和用户态概念 1.2 内核态和用户态转化 2. 处理信号 2.2 捕捉信号 2.2 系统调用sigaction 3. 不可重入函数 4. volatile关键字 5. SIGCHLD信号&#xff08;了解&#xff09; 6. 笔试选择题 答案及解析 本篇完。 1. 内核态和用户态…

气象台使用vr模拟仿真实训教学降低成本投入

气候仿真实验室用于模拟高低温、高湿、干燥、阳光光照、降雨、降雪、覆冰、雾天与强风等多种环境适应性试验等气候和环境条件&#xff0c;在环境试验中&#xff0c;温度、湿度、光照、降雨这些常见的仿真环境都很容易实现。而比较少见的雾天、强风、降雪等环境就比较难。因此为…

《动手学深度学习 Pytorch版》 9.8 束搜索

本节将介绍几大&#xff1a; 贪心搜索&#xff08;greedy search&#xff09;策略 穷举搜索&#xff08;exhaustive search&#xff09; 束搜索&#xff08;beam search&#xff09; 9.8.1 贪心搜索 贪心搜索已用于上一节的序列预测。对于输出序列的每一时间步 t ′ t t′…

【FPGA零基础学习之旅#16】嵌入式块RAM-双口ram的使用

&#x1f389;欢迎来到FPGA专栏~双口ram的使用 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;FPGA学习之旅 文章作者技术和水平有限&#xff0c;如果文中出现错误&#xff0c;希望大家能指正…

SystemVerilog学习(3)——数组

一、定宽数组 相比于Verilog-1995中的一维定宽数组&#xff0c;SV提供了更加多样的数组类型&#xff0c;功能上也大大增强。 1.1 定宽数组的声明与初始化 Verliog要求在声明中必须给出数组的上下界。因为几乎所有的数组都使用0作为索引下届&#xff0c;所以SV允许只给出数组的…