SpringBoot2 学习系列(一):SpringBoot2 mybatis

编写一些关于Spring Boot 2相关技术的文档。并将相关源码发布在github中。希望用一丝善意拯救在痛苦之中的开发者们!本文主要介绍如何使用spring boot 2.0 + mybatis + log4j2构建项目。

一、环境准备

  • JDK1.8以上
  • ​​​​apache-maven-3.5.0以上
  • IntelliJ IDEA 2018.2.4 (Ultimate Edition)
  • mysql 5.6以上
  • Google Chrome 浏览器

二、创建项目

  1. 分别点击File —>New—>Project...

2.点击Maven,去掉Create from archetype 勾选。这里不选择模板构建,后面通过.pom文件可以引入相关依赖。

3.填入相关GroupId 和 ArtificitId

4.选择好路径后完成创建项目

三、配置pom.xml

1.编写pom.xml内容如下,这里要注意一定要写build标签中的内容,这里会在编译时将xml文件放在target文件夹下,否则mybatis读取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>test</groupId>
    <artifactId>test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--支持web方式启动-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.hibernate.validator</groupId>
                    <artifactId>hibernate-validator</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--支持log4j2方式记录日志-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

        <!-- 支持jdbc 方式连接数据库 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!-- 支持mysql 连接 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- 支持识别yml配置 -->
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-yaml</artifactId>
        </dependency>

        <!-- mybatis 支持-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>

        <!--支持动态编译-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- 引入thymeleaf模板引擎-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

    </dependencies>

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.1.7.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.yml</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <configuration>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

重新引入maven依赖:

四、目录结构

1.创建如下java包和文件夹。暂时不需要创建java类及xml文件,后面源码中已经存在位置。

五、编辑代码

1.编写配置文件application.yml,内容如下,这里的数据库配置要改成你的数据库密码:

server:
  #应用端口号
  port: 8000
spring:
  #数据库
  datasource:
    #地址
    url: jdbc:mysql://127.0.0.1:3306/csdnboot?serverTimezone=UTC
    #账号
    username: root
    #密码
    password: root
  jpa:
    #输出执行语句
    show-sql: true
  thymeleaf:
    #模板的模式,支持 HTML, XML TEXT JAVASCRIPT
    mode: HTML
    #编码 可不用配置
    encoding: UTF-8
    #开发配置为false,避免修改模板还要重启服务器
    cache: false
    #配置模板路径,默认是templates,可以不用配置
    prefix: classpath:/templates/
mybatis:
    #mybatis xml存放路径
    mapper-locations: classpath*:mapping/*.xml
    #mybatis 实体类包路径
    type-aliases-package: com.cc.ys.model

2.编写UserVO类,内容如下

package com.cc.ys.model;

/**
 * @tip 账户相关实体类
 * @author  ys
 */
public class UserVO {
    //用户id
    private  int userId;
    //用户名
    private String userName;
    //账号
    private String userNo;
    //密码
    private String password;

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserNo() {
        return userNo;
    }

    public void setUserNo(String userNo) {
        this.userNo = userNo;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

3.编写UserMapper.xml,需要放在src\main\resources\mapping下,注意这里的namespace值要指向UserMapper类,select 标签下的id 要和UserMapper类中的接口名一致, 内容如下:

<?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.cc.ys.mapper.UserMapper">

    <resultMap id="BaseResultMap" type="com.cc.ys.model.UserVO">
        <id column="user_id" property="userId" jdbcType="INTEGER"/>
        <result column="user_no" property="userNo" jdbcType="VARCHAR"/>
        <result column="user_name" property="userName" jdbcType="VARCHAR"/>
        <result column="user_passwd" property="password" jdbcType="VARCHAR"/>
    </resultMap>

    <sql id="Base_Column_List">
       user_id, user_no, user_name, user_passwd
    </sql>

    <select id="selectAll" resultMap="BaseResultMap" parameterType="map">
        select
        <include refid="Base_Column_List"/>
        from sys_user
        <where>
            <if test="userName != null and userName != ''">
                user_name=#{userName}
            </if>
            <if test="userNo != null and userNo != ''">
                and user_no=#{userNo}
            </if>
        </where>
    </select>

</mapper>

4.编写UserController类,内容如下

package com.cc.ys.controller;

import com.cc.ys.model.UserVO;
import com.cc.ys.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequestMapping("user")
public class UserController {

    private final UserService userService;

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

    @RequestMapping("queryAll")
    @ResponseBody
    public List<UserVO> queryList(String userName, String userNo){
        return userService.queryAll(userName, userNo);
    }
}

5.编写UserMapper类,内容如下:

package com.cc.ys.mapper;

import com.cc.ys.model.UserVO;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;
import java.util.Map;

@Mapper
public interface UserMapper{

    public List<UserVO> selectAll(Map<String,Object> map);

}

6.编写UserService接口,这里仅有一个查询全部用户的接口,内容如下:

package com.cc.ys.service;

import com.cc.ys.model.UserVO;

import java.util.List;

public interface UserService {

    public List<UserVO> queryAll(String userName, String userNo);
}

7.编写UserServiceImpl实现类,内容如下:

package com.cc.ys.serviceimpl;

import com.cc.ys.mapper.UserMapper;
import com.cc.ys.model.UserVO;
import com.cc.ys.service.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    public UserMapper userMapper;

    @Override
    public List<UserVO> queryAll(String userName, String userNo) {
        Map<String,Object> map = new HashMap<>();
        map.put("userName",userName);
        map.put("userNo",userNo);
        return userMapper.selectAll(map);
    }
}

8.编写Application, 运行这个类的main方法启动项目。

package com.cc.ys;

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

/**
 * @tip 项目启动类(一定要放在所有controllor service 最外层,否则无法自动扫描包)
 * @author ys
 * @version  2019年8月28日15:19:10
 */
@SpringBootApplication
@MapperScan("com.cc.ys.mapper")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

9.编写log4j2-spring.xml这里使用的是log4j2替换默认的logback记录日志

<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="WARN" monitorInterval="30">
    <!--先定义所有的appender-->
    <appenders>
        <!--这个输出控制台的配置-->
        <console name="Console" target="SYSTEM_OUT">
            <!--输出日志的格式-->
            <PatternLayout  charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
            <Filters>
                <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
                <!--
                <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
                 -->
                <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        </console>
        <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
        <!--
        <File name="log" fileName="logs/all.log" append="false">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
        </File>
         -->
        <RollingFile name="RollingFileDebug" fileName="logs/debug.log" filePattern="logs/$${date:yyyy-MM}/debug-%d{yyyy-MM-dd}-%i.log">
            <Filters>
                <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
                <!--
                <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
                 -->
                <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout  charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="30 MB"/>
            </Policies>
            <DefaultRolloverStrategy max="50"/>
        </RollingFile>
        <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileInfo" fileName="logs/info.log" filePattern="logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout  charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="30 MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
            <DefaultRolloverStrategy max="50"/>
        </RollingFile>
        <RollingFile name="RollingFileWarn" fileName="logs/warn.log" filePattern="logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
            <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout  charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="30 MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
            <DefaultRolloverStrategy max="50"/>
        </RollingFile>
        <RollingFile name="RollingFileError" fileName="logs/error.log" filePattern="logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout  charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <!-- <SizeBasedTriggeringPolicy size="20 MB"/> -->
                <SizeBasedTriggeringPolicy size="30 MB"/>
            </Policies>
            <DefaultRolloverStrategy max="50"/>
        </RollingFile>
    </appenders>
    <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>
        <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
        <logger name="org.springframework" level="INFO"></logger>
        <logger name="org.mybatis" level="INFO"></logger>
        <root level="all">
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFileDebug"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
        </root>
    </loggers>
</configuration>

10.数据库建表语句:

CREATE DATABASE /*!32312 IF NOT EXISTS*/`csdnboot` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `csdnboot`;

CREATE TABLE `sys_user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `user_no` varchar(64) DEFAULT NULL COMMENT '用户账号',
  `user_name` varchar(64) DEFAULT NULL COMMENT '用户名',
  `user_passwd` varchar(64) DEFAULT NULL COMMENT '密码',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

六.启动项目

运行Application.java,可以看到控制台的日志:

日志如下:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.7.RELEASE)

[2019-09-09 09:17:08:852] [INFO] - org.springframework.boot.StartupInfoLogger.logStarting(StartupInfoLogger.java:50) - Starting Application on USER-EV1CH82FDK with PID 44444 (D:\workdir-csdn\ccys\target\classes started by Administrator in D:\workdir-csdn\ccys)
[2019-09-09 09:17:08:856] [DEBUG] - org.springframework.boot.StartupInfoLogger.logStarting(StartupInfoLogger.java:53) - Running with Spring Boot v2.1.7.RELEASE, Spring v5.1.9.RELEASE
[2019-09-09 09:17:08:857] [INFO] - org.springframework.boot.SpringApplication.logStartupProfileInfo(SpringApplication.java:647) - No active profile set, falling back to default profiles: default
[2019-09-09 09:17:08:890] [INFO] - org.springframework.boot.logging.DeferredLog.logTo(DeferredLog.java:225) - Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
[2019-09-09 09:17:08:891] [INFO] - org.springframework.boot.logging.DeferredLog.logTo(DeferredLog.java:225) - For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
[2019-09-09 09:17:10:050] [INFO] - org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:90) - Tomcat initialized with port(s): 8000 (http)
[2019-09-09 09:17:10:064] [INFO] - org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:173) - Initializing ProtocolHandler ["http-nio-8000"]
[2019-09-09 09:17:10:072] [INFO] - org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:173) - Starting service [Tomcat]
[2019-09-09 09:17:10:072] [INFO] - org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:173) - Starting Servlet engine: [Apache Tomcat/9.0.22]
[2019-09-09 09:17:10:183] [INFO] - org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:173) - Initializing Spring embedded WebApplicationContext
[2019-09-09 09:17:10:183] [INFO] - org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.prepareWebApplicationContext(ServletWebServerApplicationContext.java:284) - Root WebApplicationContext: initialization completed in 1292 ms
[2019-09-09 09:17:10:277] [DEBUG] - com.zaxxer.hikari.HikariConfig.setDriverClassName(HikariConfig.java:480) - Driver class com.mysql.cj.jdbc.Driver found in Thread context class loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader@be8b62
[2019-09-09 09:17:10:291] [DEBUG] - org.apache.ibatis.logging.LogFactory.setImplementation(LogFactory.java:135) - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
[2019-09-09 09:17:10:371] [DEBUG] - org.apache.ibatis.io.VFS.getInstance(VFS.java:84) - Using VFS adapter org.mybatis.spring.boot.autoconfigure.SpringBootVFS
[2019-09-09 09:17:10:373] [DEBUG] - org.apache.ibatis.io.ResolverUtil.addIfMatching(ResolverUtil.java:256) - Checking to see if class com.cc.ys.model.UserVO matches criteria [is assignable to Object]
[2019-09-09 09:17:10:554] [INFO] - org.springframework.scheduling.concurrent.ExecutorConfigurationSupport.initialize(ExecutorConfigurationSupport.java:171) - Initializing ExecutorService 'applicationTaskExecutor'
[2019-09-09 09:17:12:322] [INFO] - org.springframework.boot.devtools.autoconfigure.OptionalLiveReloadServer.startServer(OptionalLiveReloadServer.java:57) - LiveReload server is running on port 35729
[2019-09-09 09:17:12:345] [INFO] - org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:173) - Starting ProtocolHandler ["http-nio-8000"]
[2019-09-09 09:17:12:389] [INFO] - org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start(TomcatWebServer.java:202) - Tomcat started on port(s): 8000 (http) with context path ''
[2019-09-09 09:17:12:408] [INFO] - org.springframework.boot.StartupInfoLogger.logStarted(StartupInfoLogger.java:59) - Started Application in 3.94 seconds (JVM running for 5.34)

在浏览器调用如下接口测试:

http://localhost:8000/user/queryAll

返回如下结果:

到此为止,spring boot 2.0 + mybatis + log4j2 就搭建完毕了。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Pro Spring Boot 2: An Authoritative Guide to Building Microservices, Web and Enterprise Applications, and Best Practices Quickly and productively develop complex Spring applications and microservices out of the box, with minimal concern over things like configurations. This revised book will show you how to fully leverage the Spring Boot 2 technology and how to apply it to create enterprise ready applications that just work. It will also cover what's been added to the new Spring Boot 2 release, including Spring Framework 5 features like WebFlux, Security, Actuator and the new way to expose Metrics through Micrometer framework, and more. This book is your authoritative hands-on practical guide for increasing your enterprise Java and cloud application productivity while decreasing development time. It's a no nonsense guide with case studies of increasing complexity throughout the book. The author, a senior solutions architect and Principal Technical instructor with Pivotal, the company behind the Spring Framework, shares his experience, insights and first-hand knowledge about how Spring Boot technology works and best practices. Pro Spring Boot 2 is an essential book for your Spring learning and reference library. What You Will Learn Configure and use Spring Boot Use non-functional requirements with Spring Boot Actuator Carry out web development with Spring Boot Persistence with JDBC, JPA and NoSQL Databases Messaging with JMS, RabbitMQ and WebSockets Test and deploy with Spring Boot A quick look at the Spring Cloud projects Microservices and deployment to the Cloud Extend Spring Boot by creating your own Spring Boot Starter and @Enable feature Who This Book Is For Experienced Spring and Java developers seeking increased productivity gains and decreased complexity and development time in their applications and software services.

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

y打伞的鱼y

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

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

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

打赏作者

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

抵扣说明:

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

余额充值