springboot+mybatis(从零开始搭建maven转springboot+mybatis项目)

后端开发 专栏收录该内容
15 篇文章 0 订阅

目录结构

0.环境
1.创建maven项目
2.maven项目转springboot项目
3.springboot整合mybatis实现简单数据库访问

0.环境

windows+eclipse+jdk8+mysql/oracle/…+tomcat8.5(也可以使用eclipse内嵌,不过我后面会排除内嵌tomcat,所以最好自己弄一个)

1.创建maven项目

打开eclispe,创建一个项目,选择创建类型为maven.如图:

在这里插入图片描述
其他步骤直接默认选项,到选择Group ID页面时输入Group id和Artifact id,可以按照自己习惯选择。两个坐标唯一确定项目,如下图:
在这里插入图片描述
点击finish,完成创建。
这是会在项目中src/main/java下的cn.zoulang.frame包下回生成一个app.java,可以运行该文件测试是否成功创建。

2.maven项目转springboot项目

maven项目转springboot项目基本只要修改下pom.xml文件,即可。然后修改App.java测试。
修改pom.xml
打开pom.xml,添加parent标签,继承springboot.

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.2.RELEASE</version>
 </parent>

在标签内添加web起步依赖:

<dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
</dependency>

稍后会贴出完整的pom.xml文件,但是完整的pom.xml文件中由于添加其他内容(如排除内嵌tomcat等,导致会和讲解过程中的配置有些不一样,读者可以直接使用我配置好的完整的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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

修改App.java名称为Application.java,然后修改其中的代码为如下(修改名称只是为了表达已经转为springboot项目,因为直接通过插件创建的springboot项目默认启动类就叫Application.java):
Application.java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class Application extends SpringBootServletInitializer{

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

运行Application.java类,查看控制台,启动成功后服务器一直运行着。到此,已经将maven项目转为springboot项目。

3.springboot项目整合mybatis

添加springboot测试起步依赖、jdbc驱动(oracle&mysql,可以只添加其中一个)、mybatis依赖,druid连接池依赖,log4j日志管理依赖等。然后在标签中配置资源文件编译路径为src/main/resources(配置完成后需要右键工程项目,选择maven->update project是配置资源路径生效,刷新项目后就可以看到项目中已经添加了改路径)。添加插件maven-compiler-plugin,这个为必须,java1.3版本以上都必须配置这一步。(其他插件、依赖都有注释,可以参考注释查看)完整的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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

	<groupId>cn.zoulang</groupId>
	<artifactId>frame</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	
	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.2.RELEASE</version>
    </parent>
	
	<properties>
	  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	
	<!-- 依赖包 -->
	<dependencies>
		
		<!-- ########################### web base ########################### -->
		
		<!-- 支持web的起步依赖。起步依赖:类似spring-boot-starter-xx的依赖为起步依赖 -->
		<!-- spring web application -->
	    <dependency>
	    	<groupId>org.springframework.boot</groupId>
	    	<artifactId>spring-boot-starter-web</artifactId>
	    	<exclusions>
	    		<!-- 排除内嵌logging,避免与log4j冲突(如果没有引入log4j则不需要排除) -->
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
                <!-- 排除内嵌tomcat -->
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
	    </dependency>
	    
	    <!-- Srping Boot 测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
	    
	    <!-- tomcat -->
	    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
	    
	    <!-- servlet api(主要提供声明周期接口)-->

        <!-- ########################### drivers ########################### -->

        <!-- oracle jdbc -->
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc8</artifactId>
            <version>12.2.0.1.0</version>
            <!-- 依赖的范围
            	compile:默认值,表示被依赖的maven项目会参与项目编译、运行、测试、打包。是一个强依赖。
            	test:仅参与测试代码的编译和运行,如junit
            	runtime:被依赖项目在运行期间动态参与
            	provided:由服务器/servelet容器提供,非传递性,不会打包
            	system:需要显示提供一个本地jar包路径
             -->
            <scope>system</scope>
            <systemPath>${basedir}/lib/ojdbc8.jar</systemPath>
        </dependency>

        <!-- mysql connector -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        
        <!-- ########################### database and cache things ########################### -->
        
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
        
        <!-- druid 连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.12</version>
        </dependency>
        
        <!-- ########################### auth ########################### -->
        
        <!-- spring security 权限控制 -->

        <!-- ########################### tools ########################### -->
        
        <!-- commons lang 3 -->
        
	    <!-- ########################### others ########################### -->

        <!-- log4j2 日志管理 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

        <!-- log4j1 切换到 log4j2 的桥接包 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-1.2-api</artifactId>
            <version>2.6.2</version>
        </dependency>

	</dependencies>
	
	<build>
		<!-- 资源文件配置 -->
		<resources>
			<resource>
				<directory>${project.basedir}/src/main/resources</directory>
			</resource>
		</resources>
		
		<plugins>
            <plugin>
            	<!-- maven的核心插件compile插件默认只支持java1.3,需要使用java高版本,必须指定该插件 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                    <compilerArguments>
                        <bootclasspath>${env.JAVA_HOME}/jre/lib/rt.jar;${env.JAVA_HOME}/jre/lib/jce.jar</bootclasspath>
                        <extdirs>${project.basedir}/src/main/webapp/WEB-INF/lib</extdirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            
            <!-- 支持springboot插件,打包成jar/war -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            
        </plugins>
	</build>

	
</project>

在src/main/resources下面新建一个文件,命名为application.properties,如图:
在这里插入图片描述
双击打开文件,添加数据源和durid连接池及mybatis配置信息,如下:
application.properties

# datasource 数据源驱动配置信息
# mysql
server.port=8899
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Drive

# oracle
#spring.datasource.url=jdbc:oracle:thin:@localhost:1521:ORCL
#spring.datasource.username=ggjt
#spring.datasource.password=123456
#spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
#spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

# durid 连接池配置信息
# 连接池初始化大小
spring.datasource.initialSize=5   
# 连接池最小连接数量	
spring.datasource.minIdle=5     
# 连接池中最大的连接数量  	
spring.datasource.maxActive=20	
# 连接池最大空闲连接数量(已抛弃使用),无效配置	
#spring.datasource.maxIdle=8    
# 获取连接最大等待时间,超时抛出异常。设置为-1表示无限等待		
spring.datasource.maxWait=60000		
# 1.检测连接有效时间间隔,删除无效连接  2.设置testWhilIdle属性为true时需要依赖该配置
spring.datasource.timeBetweenEvictionRunsMillis=60000
# 配置最小生存时间,最后活跃时间和当前时间差值大于该值,则关闭连接	
spring.datasource.minEvictableIdleTimeMillis=300000	
# 查询语句,如检测连接有效性等会用到	
spring.datasource.validationQuery=SELECT 1 FROM DUAL	
# 申请连接时检测连接可用性 
spring.datasource.testWhileIdle=true		
# 申请连接时执行validationQuery判断连接的有效性
spring.datasource.testOnBorrow=false	
# 归还连接时执行validationQuery判断连接的有效性,如果这个链接失效则删除	
spring.datasource.testOnReturn=false		
# 打开PSCache,并且指定每个连接上PSCache的大小?
spring.datasource.poolPreparedStatements=true 	
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.filters=stat,wall		
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 	

# mybatis
# 配置mybatis的SQLxml扫描路径(全注解方式则不用配置)
mybatis.mapper-locations=classpath*:mappings/**/*.xml 

# 打印SQL
#mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl


上面使用的是mysql数据库驱动,注释掉了oracle的,如果使用oracle数据库,需要打开oracle代码部分,并注释掉mysql部分。

创建类DruidDataSourceConfiguration配置数据源配置信息,如图。
在这里插入图片描述
DruidDataSourceConfiguration.java

import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.alibaba.druid.pool.DruidDataSource;

@Configuration
@Primary //在同样的DataSource中,首先使用被标注的DataSource
public class DruidDataSourceConfiguration extends DataSourceProperties{

	@Value("${spring.datasource.url}")  
    private String dbUrl;  

    @Value("${spring.datasource.username}")  
    private String username;  

    @Value("${spring.datasource.password}")  
    private String password;  

    @Value("${spring.datasource.driver-class-name}")  
    private String driverClassName;  

    @Value("${spring.datasource.initialSize}")  
    private int initialSize;  

    @Value("${spring.datasource.minIdle}")  
    private int minIdle;  

    @Value("${spring.datasource.maxActive}")  
    private int maxActive;  

    @Value("${spring.datasource.maxWait}")  
    private int maxWait;  

    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")  
    private int timeBetweenEvictionRunsMillis;  

    @Value("${spring.datasource.minEvictableIdleTimeMillis}")  
    private int minEvictableIdleTimeMillis;  

    @Value("${spring.datasource.validationQuery}")  
    private String validationQuery;  

    @Value("${spring.datasource.testWhileIdle}")  
    private boolean testWhileIdle;  

    @Value("${spring.datasource.testOnBorrow}")  
    private boolean testOnBorrow;  

    @Value("${spring.datasource.testOnReturn}")  
    private boolean testOnReturn;  

    @Value("${spring.datasource.poolPreparedStatements}")  
    private boolean poolPreparedStatements;  

    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")  
    private int maxPoolPreparedStatementPerConnectionSize;  

    @Value("${spring.datasource.filters}")  
    private String filters;  

    @Value("{spring.datasource.connectionProperties}")  
    private String connectionProperties;
    
    @Bean     //声明其为Bean实例  
    public DataSource dataSource(){  
        DruidDataSource datasource = new DruidDataSource();  

        datasource.setUrl(this.dbUrl);  
        datasource.setUsername(username);  
        datasource.setPassword(password);  
        datasource.setDriverClassName(driverClassName);  

        //configuration  
        datasource.setInitialSize(initialSize);  
        datasource.setMinIdle(minIdle);  
        datasource.setMaxActive(maxActive);  
        datasource.setMaxWait(maxWait);  
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);  
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);  
        datasource.setValidationQuery(validationQuery);  
        datasource.setTestWhileIdle(testWhileIdle);  
        datasource.setTestOnBorrow(testOnBorrow);  
        datasource.setTestOnReturn(testOnReturn);  
        datasource.setPoolPreparedStatements(poolPreparedStatements);  
        datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);  
        try {  
            datasource.setFilters(filters);  
        } catch (SQLException e) {  
            System.out.println("druid configuration initialization filter");  
        }  
        datasource.setConnectionProperties(connectionProperties);  

        return datasource;  
    }
    
}

各个配置信息的作用在application.properties中已经有注释,这里不再赘述。

创建mysql连接,连接信息需要和application.properties里面的连接信息一致,然后创建测试表:

CREATE TABLE `user` (
  `id` int(13) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(33) DEFAULT NULL COMMENT '姓名',
  `age` int(3) DEFAULT NULL COMMENT '年龄',
  `money` double DEFAULT NULL COMMENT '账户余额',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

创建测试类如图:
在这里插入图片描述
SysUser.java

import java.io.Serializable;

public class SysUser implements Serializable{

	private static final long serialVersionUID = 1L;
	
	private int id;
    private String name;
    private int age;
    private double money;
    
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public double getMoney() {
		return money;
	}
	public void setMoney(double money) {
		this.money = money;
	}
    
    
}

SysUserMapper.java
import java.util.List;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import cn.zoulang.frame.modules.test.model.SysUser;

@Mapper
public interface SysUserMapper {

// @Select(“SELECT * FROM user WHERE name = #{name}”)
// SysUser findUserByName(@Param(“name”) String name);
//
// @Select(“SELECT * FROM user”)
// List findAllUser();
//
// @Insert(“INSERT INTO user(name, age,money) VALUES(#{name}, #{age}, #{money})”)
// void insertUser(@Param(“name”) String name, @Param(“age”) Integer age, @Param(“money”) Double money);
//
// @Update(“UPDATE user SET name = #{name},age = #{age},money= #{money} WHERE id = #{id}”)
// void updateUser(@Param(“name”) String name, @Param(“age”) Integer age, @Param(“money”) Double money,
// @Param(“id”) int id);
//
// @Delete(“DELETE from user WHERE id = #{id}”)
// void deleteUser(@Param(“id”) int id);

SysUser findUserByName(@Param("name") String name);

List<SysUser> findAllUser();

void insertUser(@Param("name") String name, @Param("age") Integer age, @Param("money") Double money);

void updateUser(@Param("name") String name, @Param("age") Integer age, @Param("money") Double money,
                @Param("id") int id);

void deleteUser(@Param("id") int id);

}
注意,注释掉的部分是使用纯注解方式访问数据库,改部分代码直接从网上资源获取,没有做修改,这里忘记是哪位大佬的了,无法贴出源出处。
SysUserService.java

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.zoulang.frame.modules.test.mapper.SysUserMapper;
import cn.zoulang.frame.modules.test.model.SysUser;

@Service
public class SysUserService {

	@Autowired
	private SysUserMapper sysUserMapper;
	
	public SysUser selectUserByName(String name) {
        return sysUserMapper.findUserByName(name);
    }
	
	public List<SysUser> selectAllUser() {
        return sysUserMapper.findAllUser();
    }
	
	public void insertService() {
		sysUserMapper.insertUser("SnailClimb", 22, 3000.0);
		sysUserMapper.insertUser("Daisy", 19, 3000.0);
    }
	
	public void deleteService(int id) {
		sysUserMapper.deleteUser(id);
    }

	/**
     * 模拟事务。由于加上了 @Transactional注解,如果转账中途出了意外 SnailClimb 和 Daisy 的钱都不会改变。
     */
	@Transactional
    public void changemoney() {
		sysUserMapper.updateUser("SnailClimb", 22, 2000.0, 3);
        // 模拟转账过程中可能遇到的意外状况
        int temp = 1 / 0;
        System.out.println(temp);
        sysUserMapper.updateUser("Daisy", 19, 4000.0, 4);
    }
	
}

SysUserController.java(该部分在apringboot整合mybatis过程中没有起到左右,不过建议先写好)

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import cn.zoulang.frame.modules.test.model.SysUser;
import cn.zoulang.frame.modules.test.service.SysUserService;

@Controller
@RequestMapping("/user")
public class SysUserController {

	@Autowired
    private SysUserService SysUserService;

    @RequestMapping("/query")
    public SysUser testQuery() {
        return SysUserService.selectUserByName("Daisy");
    }

    @RequestMapping("/insert")
    public List<SysUser> testInsert() {
    	SysUserService.insertService();
        return SysUserService.selectAllUser();
    }

    @RequestMapping("/changemoney")
    public List<SysUser> testchangemoney() {
    	SysUserService.changemoney();
        return SysUserService.selectAllUser();
    }

    @RequestMapping("/delete")
    public String testDelete() {
    	SysUserService.deleteService(3);
        return "OK";
    }
	
}

创建springboot测试类:
在这里插入图片描述
Main.java

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import cn.zoulang.frame.modules.test.model.SysUser;
import cn.zoulang.frame.modules.test.service.SysUserService;

@RunWith(SpringRunner.class)
@SpringBootTest
public class Main {

	@Autowired
	SysUserService sysUserService;
	
	@Test
	public void test(){
//		sysUserService.insertService();
		List<SysUser> list = sysUserService.selectAllUser();
		
		System.out.println("id \t name \t\t age \t money");
		for( SysUser entity : list ){
			System.out.println(entity.getId() + " \t" + entity.getName()
					+ " \t\t" + entity.getAge() + " \t" + entity.getMoney());
		}
		
		try{
			sysUserService.changemoney();
		}catch(Exception e){
			System.out.println("发生了事务回滚1111111111111111111111111111");
		}
		
		List<SysUser> list2 = sysUserService.selectAllUser();
		for( SysUser entity : list2 ){
			System.out.println(entity.getId() + " \t" + entity.getName()
					+ " \t\t" + entity.getAge() + " \t" + entity.getMoney());
		}
		
	}
}

到这里,可以将上面的SysUserMapper.java里面的全注解注释打开,并注释掉下面部分代码,测试使用权注解方式访问数据库。即完成上面全注解代码打开并注释掉下面部分代码后,使用单元测试运行Main.java类的test方法,可以看到输出结果(需要先运行sysuserService.insertService()添加数据,或者手动在数据库添加测试数据)。

如果不适用全注解方式,需要配置xml文件。资源文件夹下新建文件夹及文件SysUserMapper.xml,如图:
在这里插入图片描述
SysUserMapper.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="cn.zoulang.frame.modules.test.mapper.SysUserMapper">

	<resultMap id="SysUser" type="cn.zoulang.frame.modules.test.model.SysUser">
        <result column="ID" property="id"/>
        <result column="NAME" property="name"/>
        <result column="AGE" property="age"/>
        <result column="MONEY" property="money"/>
    </resultMap>
    
    <select id="findUserByName" parameterType="String" resultMap="SysUser">
        SELECT * FROM user WHERE name = #{name}
    </select>
    
    <select id="findAllUser" parameterType="String" resultMap="SysUser">
    	SELECT * FROM user
    </select>
    
    <insert id="insertUser">
    	INSERT INTO user (
    		ID,
    		NAME,
    		AGE,
    		MONEY
    	)
    	VALUES (
    		#{id},
    		#{name},
    		#{age},
    		#{money}
    	)
    </insert>
    
    <update id="updateUser">
    	UPDATE user
    	SET
    		NAME = #{name},
    		AGE = #{age},
    		MONEY = #{money}
    	WHERE ID = #{id}
    </update>
    
    <delete id="deleteUser">
    	DELETE
    	FROM user
    	WHERE ID = #{id}
    </delete>
    
</mapper>     
        
 

此时可以注释掉SysUserMapper.java中的全注解部分代码,放开剩下部分代码测试使用xml配置方式。运行Main.java里面的代码查看数据。

  • 0
    点赞
  • 0
    评论
  • 5
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

寒语-四月魂

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值