MyBatis与Spring和Spring Boot的整合

大家好,我是王有志,一个分享硬核 Java 技术的金融摸鱼侠,欢迎大家加入 Java 人自己的交流群“共同富裕的 Java 人”。

前面,我们都是基于 MyBatis 的原生应用程序来学习 MyBatis 相关知识点的,除了引入了必要的 MyBaits 依赖和数据库的驱动外,我们没有使用任何其它的框架和组件。
但是在 Spring 已经成为 Java Web 应用事实标准的今天,我们不会只以 MyBatis 为基础构建应用程序,通常的做法是以 Spring 或 Spring Boot 为核心构建应用程序,并将 MyBatis 整合到以 Spring 或 Spring Boot 为核心构建的应用程序中使用。
那么今天,我们就一起来学习如何在以 Spring 和 Spring Boot 为基础构建的应用程序中整合 MyBatis。

Spring 项目中整合 MyBatis

当下的应用程序中,大都使用了 Spring Boot 去简化 Spring 的配置信息,因此很多小伙伴可能不会直接使用 Spring 构建应用程序并整合 MyBatis。不过 还是有一部分老旧的应用程序直是接跑在 Spring 项目上的,所以我们还是先来看一下以 Spring 为基础的项目中是如何整合 MyBatis 的。
首先我们来创建一个 Maven 项目,我这里使用的是 IDEA 创建的 Maven 项目名字为 MyBatis-Spring,如图所示:

构建完成的 Maven 项目结构以及 POM 文件如下:

下面我们对这个项目稍微做一些修改:

  • 新增 resources 路径
  • 新增 mapper 包,entity 包和 service 包
  • 修改 pom.xml 文件

修改后的项目结构如下:

Tips:后面我会提供 pom.xml 的完整代码。

Spring 项目中引入依赖

这个案例中,我们只引入最基础的依赖即可,需要引入的依赖如下:

  • MyBatis 相关依赖:mybatis-spring:3.0.3,mybatis:3.5.15;
  • Spring 相关依赖:spring-core:6.1.0,spring-context:6.1.0,spring-jdbc:6.1.0;
  • 数据库相关依赖:mysql-connector-j:8.3.0;
  • 其它依赖:HikariCP:5.1.0,lombok:1.18.30,fastjson2:2.0.45。

首先是 MyBatis 的相关的依赖,MyBatis 官方提供的 mybatis-spring 最新版本是 3.0.3,依赖的 MyBatis 版本是 3.5.14,依赖的 Spring 版本是 6.1.0,因为我一直使用的 MyBatis 版本是 3.5.15,所以这里我单独引入了 3.5.15 版本的 MyBatis(同时需要再 pom.xml 中移除 mybatis-spring 依赖的 MyBatis 版本);Spring 这里我只引入了几个核心依赖,也是我们在 Spring 项目整合 MyBatis 过程中对 Sping 的最小依赖;mysql-connector-j,lombok 和 fastJson2 就不必多说了;最后我引入了 HikariCP,这是数据库连接池,也是 Spring Boot 中默认的数据库连接池,性能非常优秀,如果有时间的话推荐大家去阅读 HikariCP 的源码,相信你一定会有收获的。
MyBatis-Spring 项目中完整的 pom.xml 文件如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.wyz</groupId>
  <artifactId>MyBatis-Spring</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>MyBatis-Spring</name>

  <properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    <mybatis.version>3.5.15</mybatis.version>
    <mybatis-spring.version>3.0.3</mybatis-spring.version>
    <spring.version>6.1.0</spring.version>
    <mysql.version>8.3.0</mysql.version>
    <hikari.version>5.1.0</hikari.version>
    <lombok.version>1.18.30</lombok.version>
    <fastjson2.version>2.0.45</fastjson2.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>${mybatis-spring.version}</version>
      <exclusions>
        <exclusion>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.15</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>com.mysql</groupId>
      <artifactId>mysql-connector-j</artifactId>
      <version>${mysql.version}</version>
    </dependency>

    <dependency>
      <groupId>com.zaxxer</groupId>
      <artifactId>HikariCP</artifactId>
      <version>${hikari.version}</version>
    </dependency>

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>${lombok.version}</version>
      <optional>true</optional>
    </dependency>

    <dependency>
      <groupId>com.alibaba.fastjson2</groupId>
      <artifactId>fastjson2</artifactId>
      <version>${fastjson2.version}</version>
    </dependency>
  </dependencies>
</project>

Spring 项目中配置数据库

我们在 resources 路径下创建 spring-datasource.xml 文件,用来配置 Spring 项目中的数据源,在数据源的选择上,我们使用 HikariCP 提供的 HikariDataSource 作为数据源,spring-datasource.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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybatis"/>
    <property name="username" value="root"/>
    <property name="password" value="123456"/>
  </bean>
</beans>

Spring 项目中配置 MyBatis

下面我们在 Spring 项目中配置 MyBatis,同样的我们在 resources 路径下创建配置文件 spring-mybatis.xml,用来配置 Spring 项目中 MyBatis 的核心–SqlSessionFactory 实例,spring-mybatis.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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans.xsd">

  <!-- 引入数据源的配置 -->
  <import resource="classpath:spring-datasource.xml"/>

  <!-- 配置 MyBatis 的 SqlSessionFactory -->
  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mapperLocations" value="classpath:mapper/*.xml"/>
  </bean>

  <!-- 配置 MyBatis 的 Mapper 接口扫描 -->
  <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.wyz.mapper"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
  </bean>
</beans>

第 8 行中,我们引入了之前配置的 spring-datasource.xml 文件,我个人是习惯在 spring-mybatis.xml 文件中引入 spring-datasource.xml 文件的,因为它们都是与数据库相关的配置,所以我习惯将它们放在一起。
第 11 行中是创建 MyBatis 的 SqlSessionFactory,这与我们使用原生 MyBatis 应用不同,这里我们使用的是 MyBatis-Spring 项目下的 SqlSessionFactoryBean。在 SqlSessionFactory 的配置中,我们还配置了两项内容:

  • dataSource,这是数据源的配置,使用的是 spring-datasource.xml 中配置的 dataSource;
  • mapperLocations,这是 MyBatis 映射器文件的配置,可以自动扫描到 resources/mapper 包下的 XML 文件。

当然,这里也可以通过加载 MyBatis 的配置实现,如:

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

  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="configLocation" value="mybatis-config.xml"/>
  </bean>
</beans>

回到 spring-mybatis.xml 第 17 行中,配置了 MapperScannerConfigurer,是 MyBatis-Spring 项目中提供的用于扫描 Mapper 接口,为 Mapper 接口生成代理并注册为 Spring 中的 Bean,配置 basePackage 用于声明 Mapper 接口的位置,配置 sqlSessionFactoryBeanName 用于声明 SqlSessionFactory 实例。
Tips:你也可以使用 MapperFactoryBean 将 MyBatis 的 Mapper 接口注册为 Spring 中的 Bean,就是麻烦点。

Spring 项目的核心配置

最后我们来配置 Spring 项目的核心配置,我这里创建了两个配置文件:spring-beans.xml 和 spring-applicantion.xml。
spring-beans.xml 用于配置需要注册为 Spring 的 Bean 的 Java 类,这里我只是将com.wyz.service包下的 Java 类通过自动扫描的方式注册为 Spring 的 Bean,spring-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: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 https://www.springframework.org/schema/context/spring-context.xsd">

  <!-- 由 Spring 自动扫描 -->
  <context:component-scan base-package="com.wyz.service"/>
</beans>

然后是 spring-applicantion.xml,由于我们只是在 Spring 项目中整合 MyBatis,因此我们不需要太多的配置,所以这里只是开启了 Spring 的注解配置,并引入了 spring-mybatis.xml 和 spring-beans.xml 文件,spring-applicantion.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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/context
  https://www.springframework.org/schema/context/spring-context.xsd">

  <context:annotation-config/>

  <import resource="classpath:spring-beans.xml"/>
  <import resource="classpath:spring-mybatis.xml"/>
</beans>

测试 Spring 整合 MyBatis

最后我们来做一个测试,这里我使用的是《MyBatis映射器:实现简单的SQL语句》中的 User 相关的 Java 对象 UserDO,接口 UserMapper 和映射器 UserMapper.xml。
UserDO 的代码如下:

public class UserDO {

  private Integer userId;

  private String name;

  private Integer age;

  private String gender;

  private Integer idType;

  private String idNumber;

  private List<UserOrderDO> userOrders;
}

UserMapper 接口的代码如下:

public interface UserMapper {
  List<UserDO> selectAll();
}

UserMapper.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="com.wyz.mapper.UserMapper">

  <select id="selectAll" resultType="com.wyz.entity.UserDO">
    select user_id, name, age, gender, id_type, id_number from user
  </select>
</mapper>

接下来我们补充一个 UserService 及其实现类(实际上不补充也没什么问题,只是前面我都建了 service 包了)。
UserService 的代码如下;

public interface UserService {
  List<UserDO> queryAllUsers();
}

UserServiceImpl 的代码如下:

@Service
public class UserServiceImpl implements UserService {

  private UserMapper userMapper;

  @Override
  public List<UserDO> queryAllUsers() {
    return userMapper.selectAll();
  }

  @Autowired
  public void setUserMapper(UserMapper userMapper) {
    this.userMapper = userMapper;
  }
}

此时,完整的 MyBatis-Spring 项目结构如下:

最后我们来测试一下我们的程序,我们来创建一个启动类 MyBatisSpringApp,测试代码如下:

public class MyBatisSpringApp {
  public static void main(String[] args) {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-application.xml");
    UserService userService = applicationContext.getBean(UserService.class);
    System.out.println(JSON.toJSONString(userService.queryAllUsers()));
  }
}

你可以执行下测试代码,看一下控制台输出的结果,这里我就偷个懒不执行了。
至此,我们已经完成了在 Spring 项目中整合 MyBatis,可以看到整个过程还是比较繁琐的,而且还需要大量使用“讨厌”的 XML 配置(至少我是非常讨厌 XML 配置的),但好在是我们有了 Spring Boot,可以大大简化 Spring 的配置工作。
接下来,我们就在 Sring Boot 项目中整合 MyBatis。

Spring Boot 项目中整合 MyBatis

我们再来创建一个 Spring Boot 项目,可以直接使用 IDEA 创建 Spring Boot 项目,如果你使用的 Eclipse 的话,也可以通过 Spring Initializr 来创建 Spring Boot 项目。
在 IDEA 中创建 Spring Boot 项目如下:

我们可以选择一些依赖,也可以在创建完成后手动添加这些依赖:

创建完成的 Spring Boot 项目,完整的结构如下:

Spring Boot 项目中引入依赖

这里我们需要修改下 pom.xml 文件,这个案例中我们也只需要引入最基础对的依赖即可。
通常我们的应用程序中不会将 Spring Boot 项目作为父项目,因此我们需要移除 pom 文件中 parent 的配置,然后单独引入 Spring Boot 的相关依赖,需要引入的依赖如下:

  • MyBatis 相关依赖:mybatis-spring-boot-starter:3.0.3,mybatis-spring-boot-autoconfigure:3.0.3;
  • Spring Boot 相关依赖:spring-boot-starter:3.2.6,spring-boot-starter-jdbc:3.2.6;
  • 日志相关:slf4j-api:2.0.13;
  • 数据库相关依赖:mysql-connector-j:8.3.0;
  • 其它依赖:lombok:1.18.30,fastjson2:2.0.45。

首先是 MyBatis 相关的依赖,与之前不同的是,这次我们使用的是 mybatis-spring-boot-starter 项目和 mybatis-spring-boot-autoconfigure 项目,这两个项目也是由 MyBatis 官方维护的,用于实现 MyBatis 与 Spring Boot 项目的整合
接着是 Spring Boot 项目的相关依赖 spring-boot-starter 和 spring-boot-starter-jdbc,一个是 Spring Boot 的核心依赖,一个是用于与数据库交互的依赖。
在 Spring Boot 项目中,我们还需要引入日志相关的依赖 slf4j-api,这是因为 Spring Boot 使用 slf4j 日志组件输出启动信息,如果不引入 slf4j 的依赖,就无法启动 Spring Boot 项目。
最后就是我们的 3 个“老朋友了”:mysql-connector-j,lombok 和 fastjson2,我们就略过不谈了。
注意,与之前 Spring 项目中整合 MyBatis 不同的是,我们这里没有引入 HikariCP,这是因为 HikariCP 已经是 Spring Boot 项目中默认使用的数据源了,因此无需额外配置。另外,由于我们移除了 parent 的配置,这里我们还需要单独的指定 mysql-connector-j 和 lombok 的版本信息。
MyBatis-SpringBoot 项目完整的 pom.xml 文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.wyz</groupId>
  <artifactId>MyBatis-SpringBoot</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>MyBatis-SpringBoot</name>
  <description>MyBatis-SpringBoot</description>

  <properties>
    <java.version>17</java.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    <spring-boot.version>3.2.6</spring-boot.version>
    <mybatis-spring-boot.version>3.0.3</mybatis-spring-boot.version>
    <mysql.version>8.3.0</mysql.version>
    <sl4j.version>2.0.13</sl4j.version>
    <lombok.version>1.18.30</lombok.version>
    <fastjson2.version>2.0.45</fastjson2.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>${mybatis-spring-boot.version}</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-autoconfigure</artifactId>
      <version>${mybatis-spring-boot.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>${spring-boot.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jdbc</artifactId>
      <version>${spring-boot.version}</version>
    </dependency>
    <dependency>
      <groupId>com.mysql</groupId>
      <artifactId>mysql-connector-j</artifactId>
      <version>${mysql.version}</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${sl4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>${lombok.version}</version>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>com.alibaba.fastjson2</groupId>
      <artifactId>fastjson2</artifactId>
      <version>${fastjson2.version}</version>
    </dependency>
  </dependencies>
</project>

Spring Boot 项目中配置数据源

我们直接在 application.properties 文件中配置要使用的数据源,配置如下:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
spring.datasource.username=root
spring.datasource.password=123456

与我们在 Spring 整合 MyBatis 的项目中使用的配置一样,这里我们就不多说了。
Tips:部分小伙伴可能喜欢使用 yaml 文件进行配置,这也是没有问题的。

Spring Boot 项目中配置 MyBatis

接下来我们来配置 MyBatis,依旧是在 application.properties 文件中配置,配置如下:

mybatis.mapper-locations=classpath:mapper/*.xml

相比之前我们在 Spring 项目中配置 MyBatis,在 Spring Boot 项目中配置 MyBatis 就简单很多了,我们只需要配置映射器 Mapper.xml 文件的位置即可,这样就可以保证在 Spring Boot 项目当中的 MyBatis 是可用的了。
Tips:MyBatis 提供的其它配置项也是可以用过这种方式进行配置的,我这里就不再展示了,留给大家自行探索了。
当然了,在 Spring Boot 项目中,你依旧可以通过引入 mybatis-config.xml 配置的方式实现在 Spring Boot 项目中配置 MyBatis,配置如下:

mybatis.config-location=classpath:mybatis-config.xml

至此,我们在 Spring Boot 项目中整合 MyBatis 的最小配置就已经完成了,完整的 application.properties 配置文件如下:

spring.application.name=MyBatis-SpringBoot

spring.datasource.hikari.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.hikari.jdbc-url=jdbc:mysql://localhost:3306/mybatis
spring.datasource.hikari.username=root
spring.datasource.hikari.password=123456

mybatis.mapper-locations=classpath:mapper/*.xml

可以看到,相比与之前在 Spring 项目中整合 MyBatis,Spring Boot 项目中整合 MyBatis 所需要的配置简洁了很多,更重要的是它会比 XML 配置清晰明了,如果你使用的是 yaml 文件,在配置层测上也会变得很清晰。

Spring Boot 项目中扫描 Mapper 接口

我们还需要通过配置将 MyBatis 的接口注册为 Spring 的 Bean。
在 Spring Boot 项目中,我们可以直接通过为 Spring Boot 启动类添加@MapperSacn注解的方式实现,代码如下:

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@MapperScan("com.wyz.mapper")
@SpringBootApplication
public class MyBatisSpringBootApplication {
  public static void main(String[] args) {
    SpringApplication.run(MyBatisSpringBootApplication.class, args);
  }
}

如果需要扫描多个包可以使用@MapperScans注解,使用方式如下:

@MapperScans(value = {@MapperScan("com.wyz.mapper")})

测试 Spring Boot 项目整合 MyBatis

我们把上面 MyBatis-Spring 项目中的 Java 对象 UserDO,接口 UserMapper ,映射器 UserMapper.xml,UserService 和它的实现类复制到我们的 MyBatis-SpringBoot 项目中。
到这里,我们再来看下 MyBatis-SpringBoot 项目的完整结构,如下图所示:

最后我们做一个简单的测试,我们来为启动类实现 CommandLineRunner 接口,注入 UserService,并在启动时调用UserService#queryAllUsers方法,执行查询全部用户的 SQL 语句。
修改后的启动类 MyBatisSpringBootApplication 完整代码如下:

@MapperScan("com.wyz.mapper")
@SpringBootApplication
public class MyBatisSpringBootApplication implements CommandLineRunner {

  private UserService userService;

  public static void main(String[] args) {
    SpringApplication.run(MyBatisSpringBootApplication.class, args);
  }

  @Override
  public void run(String... args) {
    List<UserDO> users = userService.queryAllUsers();
    System.out.println(JSON.toJSON(users));
  }

  @Autowired
  public void setUserService(UserService userService) {
    this.userService = userService;
  }
}

我们启动 Spring Boot 项目,可以看到控制台输出的结果,如下图所示:

可以看到,我们控制台中成功的输出了我们查询的全部用户信息,至此我们已经完成了在 Spring Boot 项目中整合 MyBatis。另外,我们还可以看到,在控制台输出的日志中,Spring Boot 使用的数据源是 HikariCP。
当然,由于我们的目的只是为了在 Spring 项目和 Spring Boot 项目中整合 MyBatis,因此所有的配置都是以最小依赖为原则引入和配置的,是无法直接在生产环境中应用的。


尾图(无二维码).png

  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术范王有志

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值