SpringBoot快速入门

2.1.1 创建Maven工程

使用idea工具创建一个maven工程,该工程为普通的java工程即可
 

2.1.2 添加SpringBoot的起步依赖

SpringBoot要求,项目要继承SpringBoot的起步依赖spring-boot-starter-parent
SpringBoot要集成SpringMVC进行Controller的开发,所以项目要导入web的启动依赖

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>


2.1.3 编写SpringBoot引导类

要通过SpringBoot提供的引导类起步SpringBoot才可以进行访问

package com.dharmayard;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class);
}
}


2.1.4 编写Controller

在引导类MySpringBootApplication同级包或者子级包中创建QuickStartController

package com.dharmayard.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class QuickStartController {
@RequestMapping("/quick")
@ResponseBody
public String quick(){
return "springboot 访问成功!";
}
}


2.1.5 测试

执行SpringBoot起步类的主方法,控制台打印日志:
通过日志发现,Tomcat started on port(s): 8080 (http) with context path ''
tomcat已经起步,端口监听8080web应用的虚拟工程名称为空
打开浏览器访问url地址为:http://localhost:8080/quick
 

2.2.3 SpringBoot工程热部署

我们在开发中反复修改类、页面等资源,每次修改后都是需要重新启动才生效,这样每次启动都很麻烦,浪费了大
量的时间,我们可以在修改代码后不重启就能生效,在 pom.xml 中添加如下配置就可以实现这样的功能,我们称
之为热部署。

<!--热部署配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>

因为Intellij IEDA默认情况下不会自动编译,需要对IDEA进行自动编译的设置,如下:

然后 Shift+Ctrl+Alt+/,选择Registry
 

 

四、SpringBoot的配置文件

4.1 SpringBoot配置文件类型

4.1.1 SpringBoot配置文件类型和作用

SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用
application.properties或者application.yml(application.yaml)进行配置。
SpringBoot默认会从Resources目录下加载application.properties或application.yml(application.yaml)文件
其中,application.properties文件是键值对类型的文件,之前一直在使用,所以此处不在对properties文件的格式
进行阐述。除了properties文件外,SpringBoot还可以使用yml文件进行配置,下面对yml文件进行讲解。
 

4.1.2 application.yml配置文件

4.1.2.1 yml配置文件简介
YML文件格式是YAML (YAML Aint Markup Language)编写的文件格式,YAML是一种直观的能够被电脑识别的的数
据数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导
入,比如: C/C++, Ruby, Python, Java, Perl, C#, PHP等。YML文件是以数据为核心的,比传统的xml方式更加简
洁。
YML文件的扩展名可以使用.yml或者.yaml。
4.1.2.2 yml配置文件的语法


4.1.2.2.1 配置普通数据
语法: key: value
示例代码:

name: haohao

注意:value之前有一个空格


4.1.2.2.2 配置对象数据
语法:
key:
key1: value1
key2: value2
或者:
key: {key1: value1,key2: value2}
示例代码:

person:
name: haohao
age: 31
addr: beijing
#或者
person: {name: haohao,age: 31,addr: beijing}

注意:key1前面的空格个数不限定,在yml语法中,相同缩进代表同一个级别


4.1.2.2.2 配置Map数据
同上面的对象写法


4.1.2.2.3 配置数组(List、Set)数据
语法:
key:
- value1
- value2
或者:
key: [value1,value2]
示例代码:

city:
- beijing
- tianjin
- shanghai
- chongqing
#或者
city: [beijing,tianjin,shanghai,chongqing]
#集合中的元素是对象形式
student:
- name: zhangsan
age: 18
score: 100
- name: lisi
age: 28
score: 88
- name: wangwu
age: 38
score: 90

注意:value1与之间的 - 之间存在一个空格
 

4.1.3 SpringBoot配置信息的查询

上面提及过,SpringBoot的配置文件,主要的目的就是对配置信息进行修改的,但在配置时的key从哪里去查询
呢?我们可以查阅SpringBoot的官方文档
文档URL:https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/reference/htmlsingle/#common-applicationproperties
常用的配置摘抄如下:

# QUARTZ SCHEDULER (QuartzProperties)
spring.quartz.jdbc.initialize-schema=embedded # Database schema initialization mode.
spring.quartz.jdbc.schema=classpath:org/quartz/impl/jdbcjobstore/tables_@@platform@@.
sql # Path to the SQL file to use to initialize the database schema.
spring.quartz.job-store-type=memory # Quartz job store type.
spring.quartz.properties.*= # Additional Quartz Scheduler properties.
# ----------------------------------------
# WEB PROPERTIES
# ----------------------------------------
# EMBEDDED SERVER CONFIGURATION (ServerProperties)
server.port=8080 # Server HTTP port.
server.servlet.context-path= # Context path of the application.
server.servlet.path=/ # Path of the main dispatcher servlet.
# HTTP encoding (HttpEncodingProperties)
spring.http.encoding.charset=UTF-8 # Charset of HTTP requests and responses. Added to
the "Content-Type" header if not set explicitly.
# JACKSON (JacksonProperties)
spring.jackson.date-format= # Date format string or a fully-qualified date format
class name. For instance, `yyyy-MM-dd HH:mm:ss`.
# SPRING MVC (WebMvcProperties)
spring.mvc.servlet.load-on-startup=-1 # Load on startup priority of the dispatcher
servlet.
spring.mvc.static-path-pattern=/** # Path pattern used for static resources.
spring.mvc.view.prefix= # Spring MVC view prefix.
spring.mvc.view.suffix= # Spring MVC view suffix.
# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.driver-class-name= # Fully qualified name of the JDBC driver. Autodetected based on the URL by default.
spring.datasource.password= # Login password of the database.
spring.datasource.url= # JDBC URL of the database.
spring.datasource.username= # Login username of the database.
# JEST (Elasticsearch HTTP client) (JestProperties)
spring.elasticsearch.jest.password= # Login password.
spring.elasticsearch.jest.proxy.host= # Proxy host the HTTP client should use.
spring.elasticsearch.jest.proxy.port= # Proxy port the HTTP client should use.
spring.elasticsearch.jest.read-timeout=3s # Read timeout.
spring.elasticsearch.jest.username= # Login username.

 

4.2 配置文件与配置类的属性映射方式


4.2.1 使用注解@Value映射


我们可以通过@Value注解将配置文件中的值映射到一个Spring管理的Bean的字段上
例如:
application.properties配置如下:

person:
name: zhangsan
age: 18

或者,application.yml配置如下:

person:
name: zhangsan
age: 18

实体Bean代码如下:

@Controller
public class QuickStartController {
@Value("${person.name}")
private String name;
@Value("${person.age}")
private Integer age;
@RequestMapping("/quick")
@ResponseBody
public String quick(){
return "springboot 访问成功! name="+name+",age="+age;
}
}

浏览器访问地址:http://localhost:8080/quick 结果。
 

4.2.2 使用注解@ConfigurationProperties映射

通过注解@ConfigurationProperties(prefix="配置文件中的key的前缀")可以将配置文件中的配置自动与实体进行映

实体Bean代码如下:

@Controller
@ConfigurationProperties(prefix = "person")
public class QuickStartController {
private String name;
private Integer age;
@RequestMapping("/quick")
@ResponseBody
public String quick(){
return "springboot 访问成功! name="+name+",age="+age;
} p
ublic void setName(String name) {
this.name = name;
} p
ublic void setAge(Integer age) {
this.age = age;
}
}

注意:使用@ConfigurationProperties方式可以进行配置文件与实体字段的自动映射,但需要字段必须提供set方
法才可以,而使用@Value注解修饰的字段不需要提供set方法
 

五、SpringBoot与整合其他技术

5.1 SpringBoot整合Mybatis

5.1.1 添加Mybatis的起步依赖
5.1.2 添加数据库驱动坐标

<!--mybatis起步依赖-->
<dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.0</version>
</dependency>

<!-- MySQL连接驱动 -->
<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
</dependency>


5.1.3 添加数据库连接信息

在application.properties中添加数据量的连接信息

#DB Configuration:
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?
useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root


5.1.4 创建user表

在test数据库中创建user表

-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`password` varchar(50) DEFAULT NULL,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'zhangsan', '123', '张三');
INSERT INTO `user` VALUES ('2', 'lisi', '123', '李四');


5.1.5 创建实体Bean

public class User {
// 主键
private Long id;
// 用户名
private String username;
// 密码
private String password;
// 姓名
private String name;
//此处省略getter和setter方法 .. ..
}

但是建议使用mybatis自动生成工具:自写插件。

package cn.dharmayard.mybatis.comment.generator;

import java.sql.Timestamp;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.internal.DefaultCommentGenerator;
import org.mybatis.generator.internal.util.StringUtility;

public class DharmayardCommentGenerator
  extends DefaultCommentGenerator
{
  public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn)
  {
    if ((introspectedColumn.getRemarks() != null) && (!introspectedColumn.getRemarks().equals("")))
    {
      StringBuffer sb = new StringBuffer();
      field.addJavaDocLine("/**");
      field.addJavaDocLine(" * <pre>");
      if (introspectedColumn.getRemarks() != null) {
        field.addJavaDocLine(" * 表字段注释 : " + introspectedColumn.getRemarks());
      }
      sb.append(" * 表字段 : ");
      sb.append(introspectedTable.getFullyQualifiedTable());
      sb.append('.');
      sb.append(introspectedColumn.getActualColumnName());
      field.addJavaDocLine(sb.toString());
      field.addJavaDocLine(" * </pre>");
      field.addJavaDocLine(" */");
    }
  }
  
  public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable)
  {
    StringBuilder sb = new StringBuilder();
    topLevelClass.addJavaDocLine("/**");
    String remarks = introspectedTable.getRemarks();
    if (StringUtility.stringHasValue(remarks))
    {
      topLevelClass.addJavaDocLine(" * Database Table Remarks:");
      String[] remarkLines = remarks.split(System.getProperty("line.separator"));
      String[] var6 = remarkLines;
      int var7 = remarkLines.length;
      for (int var8 = 0; var8 < var7; var8++)
      {
        String remarkLine = var6[var8];
        topLevelClass.addJavaDocLine(" *   " + remarkLine);
      }
    }
    topLevelClass.addJavaDocLine(" *");
    sb.append(" * the database table ");
    sb.append(introspectedTable.getFullyQualifiedTable());
    topLevelClass.addJavaDocLine(sb.toString());
    topLevelClass.addJavaDocLine(" * create by " + new Timestamp(System.currentTimeMillis()));
    topLevelClass.addJavaDocLine(" */");
  }
}

然后在pom中使用指定生成插件

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <!-- mybatis自动生成代码 -->
        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.2</version>
            <!-- 无法让插件编译本地代码,只能这样搞 -->
            <dependencies>
                <!--
                <dependency>
                    <groupId>com.xuwhyse</groupId>
                    <artifactId>mybatis-generate-self</artifactId>
                    <version>1.0.0</version>
                    <scope>system</scope>
                    <systemPath>${basedir}/src/main/webapp/WEB-INF/lib/mybatis-generate-self-1.0.0.jar</systemPath>
                </dependency>
                 -->
                <!--  -->
                <dependency>
                    <groupId>cn.dharmayard.mybatis</groupId>
                    <artifactId>mybatis-comment-plugin</artifactId>
                    <version>1.0.0</version>
                </dependency>
            </dependencies>
            <configuration>
                <verbose>true</verbose>
                <overwrite>true</overwrite>
            </configuration>
        </plugin>
    </plugins>
</build>

然后在项目resource目录下放入generatorConfig.xml文件。并修改其中的db连接,设置mysql的连接jar包路径,生成java model以及mapper.xml和mapper.java文件存放的路径位置,和要根据哪张表生成实体的表明和对应实体名。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>

    <!-- 自动生成代码,只加了mybatis2个包和plugin,再加上这个文件的配置就行,不依赖其他信息 mybatis-generator:generate -->
    <!-- !!!! Driver Class Path !!!! -->
    <classPathEntry
            location="D:\develop\apache-maven-3.5.3\repo\mysql\mysql-connector-java\5.1.41\mysql-connector-java-5.1.41.jar"/>

    <context id="context" defaultModelType="flat" targetRuntime="MyBatis3">

        <property name="javaFileEncoding" value="UTF-8"/>

        <plugin type="org.mybatis.generator.plugins.CaseInsensitiveLikePlugin"/>
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
        <!--支持分页-->
        <plugin type="org.mybatis.generator.plugins.RowBoundsPlugin"/>

        <commentGenerator
                type="cn.dharmayard.mybatis.comment.generator.DharmayardCommentGenerator">
            <property name="javaFileEncoding" value="UTF-8"/>
            <property name="suppressAllComments" value="true"/>
            <property name="suppressDate" value="true"/>
        </commentGenerator>

        <!-- !!!! Database Configurations !!!! -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"

                        connectionURL="jdbc:mysql://192.168.0.101:3306/lottery_builder" userId="root"
                        password="123456"/>
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <!-- !!!! Model Configurations !!!! -->
        <javaModelGenerator targetPackage="com.dharmayard.lottery.model"
                            targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <!-- !!!! Mapper XML Configurations !!!! -->
        <sqlMapGenerator targetPackage="mapper"
                         targetProject="src/main/resources">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <!-- !!!! Mapper Interface Configurations !!!! -->
        <javaClientGenerator targetPackage="com.dharmayard.lottery.mapper"
                             targetProject="src/main/java" type="XMLMAPPER">
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>


        <table tableName="lottery_dlt_reward" domainObjectName="DltReward" enableCountByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false" enableUpdateByExample="false">

        </table>



    </context>
</generatorConfiguration>

以上配置完成后可以点击maven插件生成了。

注意开发规范:如果生成的mapper接口名为DltBallOrderMapper里面是插件生成的原生方法,那我们新开发的接口一般是写在一个新建的名为DltBallOrderExtendsMapper的接口里面,如下

public interface DltBallOrderExtendsMapper extends DltBallOrderMapper {
    DltBallOrder selectByPeriodNo(String periodNo);

    DltBallOrder selectDltBallOrderByParams(Map<String, Object> params);
}


5.1.6 编写Mapper

@Mapper
public interface UserMapper {
public List<User> queryUserList();
}

注意:@Mapper标记该类是一个mybatis的mapper接口,可以被spring boot自动扫描到spring上下文中
 


5.1.7 配置Mapper映射文件

在src\main\resources\mapper路径下加入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.itheima.mapper.UserMapper">
<select id="queryUserList" resultType="user">
select * from user
</select>
</mapper>


5.1.8 在application.properties中添加mybatis的信息

#spring集成Mybatis环境
#pojo别名扫描包
mybatis.type-aliases-package=com.itheima.domain
#加载Mybatis映射文件
mybatis.mapper-locations=classpath:mapper/*Mapper.xml


5.1.9 编写测试Controller

@Controller
public class MapperController {
@Autowired
private UserMapper userMapper;
@RequestMapping("/queryUser")
@ResponseBody
public List<User> queryUser(){
List<User> users = userMapper.queryUserList();
return users;
}
}


5.1.10 测试

localhost:8080/queryUser

 

5.2 SpringBoot整合Junit
5.2.1 添加Junit的起步依赖

<!--测试的起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

5.2.2 编写测试类
 

package com.dharmayard.test;
import com.dharmayard.MySpringBootApplication;
import com.dharmayard.domain.User;
import com.dharmayard.mapper.UserMapper;
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 java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MySpringBootApplication.class)
public class MapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void test() {
List<User> users = userMapper.queryUserList();
System.out.println(users);
}
}

其中,
SpringRunner继承自SpringJUnit4ClassRunner,使用哪一个Spring提供的测试测试引擎都可以
 

public final class SpringRunner extends SpringJUnit4ClassRunner

@SpringBootTest的属性指定的是引导类的字节码对象
 

5.3 SpringBoot整合Spring Data JPA
 

5.3.1 添加Spring Data JPA的起步依赖

<!-- springBoot JPA的起步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>


5.3.2 添加数据库驱动依赖

<!-- MySQL连接驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>


5.3.3 application.properties中配置数据库和jpa的相关属性


#DB Configuration:
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?
useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
#JPA Configuration:
spring.jpa.database=MySQL
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy


5.3.4 创建实体配置实体

@Entity
public class User {
// 主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// 用户名
private String username;
// 密码
private String password;
// 姓名
private String name;
//此处省略setter和getter方法... ...
}


5.3.5 编写UserRepository


public interface UserRepository extends JpaRepository<User,Long>{
public List<User> findAll();
}


5.3.6 编写测试类


@RunWith(SpringRunner.class)
@SpringBootTest(classes=MySpringBootApplication.class)
public class JpaTest {
@Autowired
private UserRepository userRepository;
@Test
public void test(){
List<User> users = userRepository.findAll();
System.out.println(users);
}
}


5.3.7 控制台打印信息
注意:如果是jdk9,执行报错因为jdk缺少相应的jar
解决方案:手动导入对应的maven坐标,如下:

<!--jdk9需要导入如下坐标-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>

 

5.4 SpringBoot整合Redis

5.4.1 添加redis的起步依赖

<!-- 配置使用redis启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>


5.4.2 配置redis的连接信息

#Redis
spring.redis.host=127.0.0.1
spring.redis.port=6379


5.4.3 注入RedisTemplate测试redis操作
 


@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootJpaApplication.class)
public class RedisTest {
@Autowired
private UserRepository userRepository;
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Test
public void test() throws JsonProcessingException {
//从redis缓存中获得指定的数据

String userListData = redisTemplate.boundValueOps("user.findAll").get();
//如果redis中没有数据的话
if(null==userListData){
//查询数据库获得数据
List<User> all = userRepository.findAll();
//转换成json格式字符串
ObjectMapper om = new ObjectMapper();
userListData = om.writeValueAsString(all);
//将数据存储到redis中,下次在查询直接从redis中获得数据,不用在查询数据库
redisTemplate.boundValueOps("user.findAll").set(userListData);
System.out.println("===============从数据库获得数据===============");
}else{
System.out.println("===============从redis缓存中获得数据===============");
} S
ystem.out.println(userListData);
}
}


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值