Spring framework day 02:Spring 整合 Mybatis

news2024/11/18 23:50:08

前言

在现代软件开发中,数据持久化是一个重要的环节。为了高效、可维护地管理和操作数据库,许多开发者采用了Spring框架和Mybatis持久化框架的组合。Spring提供了依赖注入和面向切面编程等特性,而Mybatis则是一个优秀的对象关系映射(ORM)框架,能够有效地管理数据库与Java对象之间的转换。

本文将介绍如何使用Spring整合Mybatis来简化数据持久化的过程。首先,我们将简单介绍Spring框架和Mybatis框架的基本概念和原理,接着详细探讨Spring和Mybatis整合的步骤以及如何配置和使用它们。

通过阅读本文,您将了解到Spring整合Mybatis的优势和核心功能,以及如何利用它们来提高开发效率和降低代码的复杂度。无论您是初学者还是有一定经验的开发者,本文都会为您提供实用的指导和最佳实践。

一、为什么要使用 Spring 整合 Mybatis 

使用Spring整合Mybatis有以下几个重要原因:

  1. 简化配置和管理:Spring框架提供了依赖注入和控制反转(IoC)的机制,将对象的创建和依赖关系的管理交给Spring容器处理。通过Spring的配置文件,我们可以轻松地配置Mybatis的数据源、事务管理器等,并将Mapper对象注入到Spring容器中。这样一来,我们不再需要手动管理对象的创建和依赖关系,大大简化了配置和管理的工作。

  2. 提供声明式事务管理:Spring框架为数据库事务管理提供了强大的支持。通过Spring整合Mybatis,我们可以使用Spring的事务管理器来管理数据库事务,实现对数据的一致性和完整性的保护。通过声明式的方式,我们可以以简洁、可维护的方式定义事务的边界,而无需手动编写繁琐的事务管理代码。

  3. 实现面向切面编程:Spring框架的另一个重要特性是面向切面编程(AOP)。通过AOP,我们可以在系统的不同层次上进行横切关注点的处理,如日志记录、异常处理、性能监控等。Spring整合Mybatis使得我们可以利用AOP机制来实现对持久层的横切关注点处理,例如对SQL语句的日志记录和缓存管理等,极大地提高了系统的灵活性和可维护性。

  4. 促进代码的模块化和可重用性:通过Spring整合Mybatis,我们可以将数据访问层的逻辑封装在Mapper接口中,并使用Spring的依赖注入将Mapper对象注入到服务层中。这样一来,我们可以更好地实现代码的模块化和组件化,进一步提高代码的可重用性和可测试性。此外,Mybatis本身也提供了很多数据库操作的常用功能,如条件查询、分页查询、动态SQL等,可以让我们更加高效地编写数据访问层的代码。

综上所述,使用Spring整合Mybatis可以简化配置和管理、提供声明式事务管理、实现面向切面编程,同时也促进了代码的模块化和可重用性。这使得开发人员可以更加专注于业务逻辑的实现,提高开发效率和软件质量。

在后面我也会通过一个 spring 整合 Mybatis 的案例来加入事务管理!

二、开始学习

1、新建项目,结构如下

2、添加依赖
  <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>

 
 
    </dependencies>

这些依赖主要是用于构建一个基于Spring和Mybatis的Java项目,实现与数据库的交互和管理。

  1. com.alibaba:druid:Druid是一种开源的关系型数据库连接池,提供了比传统连接池更强大的功能和性能监控。通过引入这个依赖,我们可以使用Druid来管理数据库连接。

  2. org.springframework:spring-context:Spring框架的核心依赖之一,提供了IoC(控制反转)和DI(依赖注入)等核心功能。通过引入这个依赖,我们可以使用Spring来管理应用程序的组件和依赖关系。

  3. org.springframework:spring-jdbc:Spring框架提供的数据访问层的依赖,包含了与JDBC相关的类和接口。通过引入这个依赖,我们可以使用Spring提供的JDBC支持进行数据库访问和操作。

  4. ch.qos.logback:logback-classic:Logback是一个灵活的日志框架,可以替代传统的Log4j。logback-classic是Logback的经典实现,提供了日志记录的功能。通过引入这个依赖,我们可以使用Logback来记录应用程序的日志。

  5. mysql:mysql-connector-java:MySQL数据库的Java驱动程序,通过引入这个依赖,我们可以连接和操作MySQL数据库。

  6. org.projectlombok:lombok:Lombok是一个Java库,可以通过注解来自动生成代码,减少重复的样板代码。通过引入这个依赖,我们可以简化Java类的定义和编写。

  7. junit:junit:JUnit是一个用于编写单元测试的框架。通过引入这个依赖(scope设置为test),我们可以使用JUnit来编写和运行单元测试。

  8. org.mybatis:mybatis:MyBatis框架的核心依赖,用于数据库访问和映射。详细信息请参考前面的回答。

  9. org.mybatis:mybatis-spring:MyBatis与Spring框架整合的依赖,提供了MyBatis与Spring集成的支持。详细信息请参考前面的回答。

这些依赖一起使用,可以构建一个基于Spring和MyBatis的Java项目,并实现数据库访问和管理的功能。请注意检查版本号,确保使用的版本兼容并与其他相关依赖项一致。

3、创建数据库表

 链接: 百度网盘 请输入提取码 提取码: fmq9 复制这段内容后打开百度网盘手机App,操作更方便哦

由于数据量太大了,只能上传到网盘上,大家去拷贝就可以了。

4、在 entity 包下新建一个实体类 City
@Data
public class City {

    private String cityId;
    private String cityName;
    private String cityCode;
    private String province;

}
5、在 dao 包下新建一个 CityDao 接口
public interface CityDao {

    /**
     * 根据省份查询
     * @param province
     * @return
     */
    List<City> list(String province);

}

这次演示的案例是,根据条件查询城市信息。

6、在 service 包下新建一个 CityService 接口,在 impl 包下新建一个 CityServiceImpl 实现类

CtiytService 接口 

public interface CityService {

    List<City> listCity(String province);


}

 CityServiceImpl 实现类

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

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

    @Override
    public List<City> listCity(String province) {
        return cityDao.list(province);
    }



}

这段代码是一个基于Spring框架的Java类,其中@Service注解表示这个类是一个服务组件,会被Spring容器管理。@Slf4j注解则表示引入了Lombok库,可以使用log对象进行日志记录。

@RequiredArgsConstructor注解是Lombok库提供的注解,它会自动生成一个构造方法,参数为类中已经声明的final成员变量,对于这段代码中的cityDao,它会在构造方法中被赋值。

CityServiceImpl类实现了CityService接口,并覆写了listCity方法。在这个方法中,调用cityDao.list(province)方法获取数据并返回。这个方法实际上是委托给另一个组件CityDao来完成的,因为cityDao是通过构造函数注入进来的。

由于cityDao是一个代理对象,而非CityDao接口原本的实现类,在运行时会动态生成一个代理实现,实现了对CityDao接口的方法调用拦截和增强等功能,以便实现事务管理、缓存等功能。

 

7、在 resources 包下新建一个db.properties文件,在mappers包下新建一个CityMapper.xml

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

 

 这些属性是用于配置Druid连接池的相关参数,具体含义如下:

  1. driver:数据库驱动类的全限定名,这里指定使用MySQL数据库的驱动。
  2. url:数据库连接的URL地址,指向本地MySQL数据库。设置了useUnicode=true和characterEncoding=utf-8,表示使用UTF-8字符集编码。
  3. name:连接数据库所需的用户名,这里设置为"root"。注意:这里本来是 username ,为什么要改成 name 呢?因为写 username 的话会识别成本机的用户名,所以这里要改成 name.
  4. password:连接数据库所需的密码,这里设置为"123456"。
  5. maxActive:连接池中同时可从数据源获取的最大活跃连接数,这里设置为200,即同时最多容纳200个连接。
  6. initialSize:初始化时创建的连接数,这里设置为5。
  7. minIdle:连接池中保持的最小空闲连接数,这里设置为5。
  8. maxWait:当连接池没有可用连接时,等待获取连接的最大时间(单位:毫秒),这里设置为2000毫秒。
  9. minEvictableIdleTimeMillis:连接在池中最小空闲时间(单位:毫秒),这里设置为300000毫秒(即5分钟)。
  10. timeBetweenEvictionRunsMillis:间隔多久进行一次空闲连接的检测(单位:毫秒),这里设置为60000毫秒(即1分钟)。
  11. testWhileIdle:在连接空闲时,是否执行validationQuery检测连接是否有效,这里设置为true。
  12. testOnReturn:在归还连接到连接池时,是否执行validationQuery检测连接是否有效,这里设置为false。
  13. validationQuery:用于检测连接是否有效的SQL查询语句,这里设置为"select 1"。
  14. poolPreparedStatements:是否缓存PreparedStatement(预编译的SQL语句),这里设置为false。

通过配置这些属性,可以更好地管理和优化Druid连接池的使用。可以指定数据库连接的URL、用户名和密码,设置连接池的大小、最大活跃连接数、空闲连接数等参数,以及进行连接的有效性校验和空闲连接的检测等。

注意:这些属性不能写错,写错了就不会生效了,会报错。

CityMapper.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="edu.nf.ch02.dao.CityDao">

    <resultMap id="cityMap" type="edu.nf.ch02.entity.City">
        <id property="cityId" column="city_id"/>
        <result property="cityName" column="city_name"/>
        <result property="cityCode" column="city_code"/>
        <result property="province" column="province"/>
    </resultMap>

    <select id="list" parameterType="string" resultMap="cityMap">
        select city_id,city_name,city_code,province
         from city_info where province = #{province}
    </select>


</mapper>

这是一个MyBatis的映射文件(mapper),用于定义数据库操作的SQL语句和结果映射规则。

在这个映射文件中,首先声明了一个命名空间 namespaceedu.nf.ch02.dao.CityDao,这个命名空间和Java接口 CityDao 对应。这个接口定义了与数据库交互的方法。

接着定义了一个 resultMap 标签,id 为 cityMap,type 为 edu.nf.ch02.entity.City,表示将查询结果映射到 City 类。在 resultMap 中定义了四个属性映射关系,分别为 cityIdcityNamecityCodeprovince,对应数据库表中的列名。

最后是一个 select 标签,id 为 list,参数类型为 String,结果映射使用了之前定义的 cityMap。SQL语句为 select city_id, city_name, city_code, province from city_info where province = #{province},其中 #{province} 是一个占位符,表示传入的参数值。

通过这个映射文件,MyBatis 就知道如何执行查询操作,并将查询结果映射到 City 类的对象中。这样,在使用 CityDao 接口中的方法时,Mybatis会根据映射文件中的定义来执行相应的SQL语句并返回结果。

 8、在 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);


        // 返回 SqlSessionFactoryBean 给容器
        return sqlSessionFactoryBean;

    }

}

这是一个Spring的配置类 AppConfig,用于配置整合 MyBatis 和数据源。

首先使用注解 @MapperScan 扫描包 edu.nf.ch02.dao 下的接口,动态生成接口的代理实现类。相当于在XML中使用 <mybatis:scan> 配置。

然后使用注解 @ComponentScan 扫描包 edu.nf.ch02,将标有 @Component@Service@Repository@Controller 等注解的类纳入Spring容器管理。

下面定义了一个名为 dataSource 的Bean方法,返回一个 DruidDataSource 实例,该方法通过读取 db.properties 文件中的配置来创建数据源。使用了 @Bean 注解,同时指定了初始化方法 init 和销毁方法 close

接着定义了一个名为 sqlSessionFactory 的Bean方法,返回一个 SqlSessionFactoryBean 实例。该方法需要传入数据源 dataSource。在方法中,创建了 SqlSessionFactoryBean 对象,并设置了数据源和其他一些属性,比如设置了实体类的别名包路径和映射文件的位置。使用了 @Bean 注解。

这样,在Spring容器启动时,会根据配置生成数据源和SqlSessionFactory,并注册到容器中供其他组件使用。

9、测试

@Slf4j
public class Main {

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        // 从容器中获取动态创建的 CityDao 的代理对象
        CityService cityDao = context.getBean(CityService.class);
        List<City> list = cityDao.listCity("广东");
        list.forEach(city -> log.info(city.getCityName()));
    }

}

 运行结果

 在 main 方法中,创建了一个 ApplicationContext 对象,并指定使用 AnnotationConfigApplicationContext 类来加载应用程序配置类 AppConfig。这样就会根据 AppConfig 中的配置信息创建并配置Spring容器。

接下来,通过容器对象 contextgetBean 方法,传入 CityService.class 参数来获取动态生成的 CityDao 的代理对象。这里假设 CityServiceCityDao 接口的实现类。

然后,调用 cityDao 的方法 listCity("广东") 查询城市列表,并将结果保存到 list 集合中。

最后,使用 forEach 方法遍历 list 集合中的每个城市对象,并使用日志记录器 log 打印城市名称。

这样,运行程序时,就会通过Spring容器获取CityDao的代理对象,并使用它查询并打印城市列表的名称。

 

三、总结

以前我们操作数据库是不是没有这么方便,以前我们要写大量的 dao 实现类的代码去操作(CRUD)数据库,现在使用 spring 整合 Mybatis 是不是不用写 dao 实现类了,是不是很方便。大大节省了开发时间和开发效率,使用框架的好处就体现出来了。

这个案例还没有完全讲完,我将在下一篇博客中继续讲解 spring 整合 Mybatis,下一章讲的就是 spring 整合 Mybatis 分页,使用 pagehelper 实现分页功能。

注意:完成这个案例之前建议先去看看我上一篇博客,spring 整合数据源。

 

四、gitee 案例

完整代码地址:qiuqiu/conformity-study (gitee.com)

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

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

相关文章

JS类的继承和实现原理详解

一&#xff1a;前言 各位小伙伴在日常开发中&#xff0c;相信一定遇到过Class这种写法。这代表在JS中创建了一个类&#xff0c;并且可以通过这个类去 new 出一个新的对象。其实在JS中&#xff0c;这个类和java中的类是没有区别的&#xff0c;同样具有属性&#xff0c;方法&…

1209. 带分数

题目&#xff1a; 1209. 带分数 - AcWing题库 思路&#xff1a; 1.targetab/c&#xff0c;由题意a,b,c会包含1~9 且每个数出现且只能出现一次。我们可以抽象化为9个坑位分成3份分别给a,b,c。 2.先采用递归搜索树写出9个坑位的全排列&#xff0c;再分成3个区&#xff0c;分…

多分享,多输出,才有被看见的可能 (抽奖倒计时2天!文末有福利!)

* 戳上方蓝字“前端队长”关注我&#xff0c;每日更新 大家好啊&#xff0c;我是Daotin。 今天讨论一个话题&#xff0c;为什么要多分享&#xff0c;多输出&#xff1f; 因为&#xff0c;只有输出多了&#xff0c;被别人看到的机会才大。 不要相信什么&#xff0c;酒香不怕巷子…

Camtasia2023免费升级最新版本下载

在这个视频的大舞台上&#xff0c;每一帧都是你炫耀的机会&#xff0c;每一秒都是让观众瞪大眼睛的瞬间。现在&#xff0c;让我们一起飞跃时空&#xff0c;用更少的时间创作更多的惊喜吧&#xff01; 就算你是个小白&#xff0c;毫无经验&#xff0c;别担心&#xff0c;Camtas…

【树莓派触摸屏等学习笔记】

前言 树莓派触摸屏 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、触摸屏硬件驱动 出现黑屏的时候&#xff0c;恢复一下txt config.txt 全屏显示 showFull Exec &#xff1a;自启动 surf 算法 特征点识别 算法的复杂度挺高的 特性树莓派强大…

从Linux的tty_struct指针获取驱动上下文

背景 问题 前段时间开发一个tty驱动&#xff0c;用途是实现仪器对GPIB消息的接收、处理和上报。对于上报场景&#xff0c;下位机应用将上报内容写入一个驱动创建的tty设备&#xff0c;tty子系统将应用的输入转发给tty驱动&#xff0c;tty驱动将其转换成对SPI从设备&#xff0…

操作系统 - 《银行家算法》

&#xff08;一&#xff09;安全序列 你是一位成功的商人&#xff0c;手里掌握着 100 个w的资金 … 有三个企业想找你贷款&#xff0c;分别是 企业 B 、企业 A 、企业 T &#xff0c;为描述方便&#xff0c;简称 BAT 。 B 表示&#xff1a;“咱们的项目很有前景&#xff0c;…

中枢听觉处理障碍的行为干预方法

作者&#xff1a;听觉健康 在数十年前&#xff0c;中枢听觉处理障碍(CAPD)的研究已经引起了多学科的关注。1937年&#xff0c;Samuel Orton提出某些儿童的学习障碍与不能有效利用听觉有关。Myklebust是提出“中枢性听力障碍”引起儿童语言学习障碍的先驱者之一。二十世纪五十年…

【lesson13】进程控制初识

文章目录 进程创建 进程创建 请你描述一下&#xff0c;fork创建子进程操作系统都做了什么&#xff1f; fork创建子进程&#xff0c;系统里多了一个进程&#xff0c;进程 内核数据结构 进程代码数据&#xff0c;内核数据结构由OS维护&#xff0c;进程代码数据一般由磁盘维护。…

C++类和对象(1)

C类和对象&#xff08;1&#xff09; C新关键字及语法引用引用的底层原理引用使用的注意事项 auto范围for C结构体新特性C类的特性C类与结构体区别构造函数定义调用 析构函数调用 C新关键字及语法 引用 引用是C加入的新类型&#xff0c;引用是变量的别名&#xff0c;在整体上…

华为OD机试 - TLV格式 - 逻辑分析(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…

LeetCode:2316. 统计无向图中无法互相到达点对数(C++)

目录 2316. 统计无向图中无法互相到达点对数 题目描述&#xff1a; 实现代码与解析&#xff1a; 并查集 原理思路&#xff1a; 2316. 统计无向图中无法互相到达点对数 题目描述&#xff1a; 给你一个整数 n &#xff0c;表示一张 无向图 中有 n 个节点&#xff0c;编号为…

stable diffusion如何解决gradio外链无法开启的问题

问题确认 为了确认gradio开启不了是gradio库的问题还是stable diffusion的问题&#xff0c;可以先执行这样一段demo代码 import gradio as grdef greet(name):return "Hello " name "!"demo gr.Interface(fngreet, inputs"text", outputs&q…

Spring Cloud 之 Sentinel简介与GATEWAY整合实现

简介 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件&#xff0c;主要以流量为切入点&#xff0c;从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。 熔断 …

Damask使用指南-Hcp结构(镁(考虑孪晶))孪晶如何加入

1&#xff0c;首先利用geom布种子&#xff0c;种子数为40&#xff0c;模型空间尺寸为64*64*1&#xff08;表示二维平面问题&#xff09;代码&#xff1a; 2&#xff0c;根据布种区域生成voronoi镶嵌的晶体结构 代码&#xff1a; 3 检查结构是否正确生成 4&#xff0c;利用dama…

61 不同路径

不同路径 重点&#xff1a;从左上角移动到右下角&#xff0c;m-1次向右&#xff0c;n-1次向下题解1 DP降维——滚动数组 题解2 求解组合 C m n − 2 m − 1 C^{m-1}_{mn-2} Cmn−2m−1​的值 一个机器人位于一个 m x n 网格的 左上角 &#xff08;起始点在下图中标记为 “St…

自己动手写编译器:c 语言模板中的输入模块设计

使用过“框架”的同学都能感受到“框架”带来的方便。所谓”框架“本质上就是一系列代码安排帮助我们完成脏活累活&#xff0c;或者复杂的工作流程后&#xff0c;把处理结果交给我们提供的代码。本节我们要完成的 c 语言模板也是一个框架&#xff0c;它也需要做一系列脏活累活&…

鲲鹏+麒麟V10 mysql8.0适配

检查是否已安装数据库服务 for i in rpm -qa | grep mysql;do rpm -e --nodeps $i;done yum源地址&#xff1a; http://repo.mysql.com/yum/mysql-8.0-community/el/8/aarch64/ 配置yum源&#xff1a; 将mysql相关的rpm包都下载到指定文件里&#xff0c;留作以后考用 yum reins…

UE4 距离场

在项目设置的渲染模块可打开距离场 把该节点连上&#xff0c;该节点的意思是&#xff0c;距离表面越近&#xff0c;材质显示值为0 不接近表面时&#xff1a; 接近表面时 可勾选该值即可看到距离场具体效果&#xff1a; 未接触表面时&#xff1a; 接触表面时&#xff1a; 产生…

2024年仁爱学院专升本招生专业对应范围专业目录更新的通知

天津仁爱学院2024年高职升本科招生专业对应范围专业目录 为了更好的进行天津仁爱学院专升本工作&#xff0c;动画专业不分文理进行录取。为了进一步提升录取专业的培养需要&#xff0c;请同学们复习专业课时加强专业课学习&#xff0c;请同学们在报考时关注天津仁爱学院招生章…