springBoot学习2--整合篇--基于狂神说

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hdkt2cEr-1668096223478)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220916221010142.png)]

对于数据访问层,无论是 SQL(关系型数据库) 还是 NOSQL(非关系型数据库),Spring Boot 底层都是采用 Spring Data 的方式进行统一处理。

Spring Boot 底层都是采用 Spring Data 的方式进行统一处理各种数据库,Spring Data 也是 Spring 中与 Spring Boot、Spring Cloud 等齐名的知名项目。

Sping Data 官网:https://spring.io/projects/spring-data

数据库相关的启动器 :可以参考官方文档:

https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#using-boot-starter

1,整合JDBC

1,创建项目

​ 添加默认的环境,导入jdbc,和mysql驱动

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GZUUtvQD-1668096223481)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220917134422921.png)]

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

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

2,在springboot核心配置文件中添加数据源

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver #数据库驱动,8.0以上版本的
    username: root #数据库用户名
    password: 123456 #数据库密码
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC #链接路径
    #mybatis 数据库的名字    useUnicode=true&characterEncoding=utf-8  防止乱码   serverTimezone=UTC  时区设置为中国

3,使用springboot的内置类的方法操作数据库

​ 主要两个:

使用内置类都需要自动装配

//springboot内置的一个模板类,里面包含处理SQL操作的方法
@Autowired
JdbcTemplate jdbcTemplate;(具体方法)
//springboot内置的一个模板类,里面包含数据源的信息
// springBoot默认数据源:class com.zaxxer.hikari.HikariDataSource
@Autowired
DataSource dataSource;(有关数据源)

4,调方法操作数据库

JdbcTemplate常用方法:

execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
​ update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
​ query方法及queryForXXX方法:用于执行查询相关语句;
​ call方法:用于执行存储过程、函数相关语句。


        /**
         * 注意,jdbctemplate的方法是可以传递参数的,同时SQL可以动态传递数据,方式和原来一样
         */
        //查询信息
        String sql="select * from user";
        List<Map<String,Object>> list=jdbcTemplate.queryForList(sql);
        System.out.println(list.get(0).toString());
        //删除信息
        String sql2="delete from user where id='1'";
        int delete=jdbcTemplate.update(sql2);//删除,修改都是用的updata方法,SQL不一样
        System.out.println(delete);
        //修改信息
        String sql3="update user set name='王五' where id='2'";
        int update=jdbcTemplate.update(sql3);
        System.out.println(update);
        //增加信息
        String sql4="insert into user(id,name,pwd) value(4,'蔡闪','123456')";
        int add=jdbcTemplate.update(sql4);
        System.out.println(add);
    

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aMRwvP8p-1668096223482)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220917160525495.png)]

注意点:

1,springboot默认的数据库是8.0+(8+版本要添加时区)的所以如果直接在创建项目时导入mysql驱动那么会报错

​ nested exception is java.sql.SQLNonTransientConnectionException: CLIENT_PLUG

解决方法:

降低mysql驱动版本

 <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
             <version>5.1.43</version>
        </dependency>

img

变为:========5.1版本的

img

2,整合Druid数据源

Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控。

Druid 可以很好的监控 DB 池连接和 SQL 的执行情况,天生就是针对监控而生的 DB 连接池。

Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。

Spring Boot 2.0 以上默认使用 Hikari 数据源,可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源,我们来重点介绍 Spring Boot 如何集成 Druid 数据源,如何实现数据库监控。

Github地址:https://github.com/alibaba/druid/

2,1添加Druid数据源

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.21</version>
</dependency>

2,2切换数据源

通过spring.datasource.type 指定数据源。

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    #type后面接的是数据源的路径

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BKf6VDOU-1668096223482)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220917164608450.png)]

2,3druid数据源特殊功能

切换成功,就可以设置数据源连接初始化大小、最大连接数、等待时间、最小连接数 等设置项;可以查看源码

#Spring Boot 默认是不注入这些属性值的,需要自己绑定
#druid 数据源专有配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true

#****************************     核心     ****************************************
#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
#如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
#则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

.看到需要用到log4j,所以需要在pom中导入log4j的依赖

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

2,3,1 自己修改druid配置

现在需要程序员自己为 DruidDataSource 绑定全局配置文件中的参数,再添加到容器中,而不再使用 Spring Boot 的自动生成了;我们需要 自己添加 DruidDataSource 组件到容器中,并绑定属性;

@Configuration//表示这是一个自定义配置,类似前面的mvcconfig
public class DruidConfig {
    //作用是将springboot核心配置文件中前缀为spring.datasource的属性与自定义配置绑定
    @ConfigurationProperties(prefix = "spring.datasource")
	//这个方法(组件)是核心,@Bean是将这个组件注册到springboot容器中,然后这个组件是指将这个配置文件注册到spring中
    //这一套下来,类似于原来的创建application.xml这种文件
    @Bean
    public DataSource druidDataSource() {
        return new DruidDataSource();
    }
}
2,3,2打开druid的数据监控页面

在droid配置文件中

//前提:项目是一个web项目,要不然哪来的页面

//配置 Druid 监控管理后台的Servlet;
//内置 Servlet 容器时没有web.xml文件,所以使用 Spring Boot 的注册 Servlet 方式
//死代码
@Bean
public ServletRegistrationBean statViewServlet() {
    ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");//   "/druid/*"意思是访问druid路径下面的页面就是数据监控页面

    // 这些参数可以在 com.alibaba.druid.support.http.StatViewServlet 
    // 的父类 com.alibaba.druid.support.http.ResourceServlet 中找到
    Map<String, String> initParams = new HashMap<>();
    //map的key值不能变
    initParams.put("loginUsername", "admin"); //后台管理界面的登录账号,
    initParams.put("loginPassword", "123456"); //后台管理界面的登录密码

    //后台允许谁可以访问
    //initParams.put("allow", "localhost"):表示只有本机可以访问
    //initParams.put("allow", ""):为空或者为null时,表示允许所有访问
    initParams.put("allow", "");
    //deny:Druid 后台拒绝谁访问
    //initParams.put("kuangshen", "192.168.1.20");表示禁止此ip访问
    //设置初始化参数
    bean.setInitParameters(initParams);
    return bean;
}

配置完毕后,我们可以选择访问 :http://localhost:8080/druid/login.html

img

2,3,3设置过滤器
//配置 Druid 监控 之  web 监控的 filter
//WebStatFilter:用于配置Web和Druid数据源之间的管理关联监控统计
@Bean
public FilterRegistrationBean webStatFilter() {
    FilterRegistrationBean bean = new FilterRegistrationBean();
    bean.setFilter(new WebStatFilter());//添加过滤器,自带的过滤器

    //exclusions:设置哪些请求进行过滤排除掉,从而不进行统计
    Map<String, String> initParams = new HashMap<>();
    initParams.put("exclusions", "*.js,*.css,/druid/*,/jdbc/*");
    //设置初始化参数
    bean.setInitParameters(initParams);

    //"/*" 表示过滤所有请求
    bean.setUrlPatterns(Arrays.asList("/*"));
    return bean;
}

注意点:

DruidConfig文件一定要添加配置注解,在里面配置的一些servlet和filter都要添加@Bean注解

3,整合mybatis

​ 这一步就和普通的mybatis项目没什么大的差距了

​ 存放sql方法的接口(添加@mapper,@repository)

​ 对应的mapper.xml(和原来的写法一致)

​ 在yaml中配置mybatis: mapper-locations: classpath:mybatis/mapper/*.xml(类似原来在注册mapper)

3,1导入相关包

创建项目也需要导入这两个环境

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4JXNpfhP-1668096223483)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220917134422921.png)]

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.1</version>
</dependency>

3,2yaml中配置数据源

spring:
  datasource:
    username: root
    password: "000000"
    #?serverTimezone=UTC解决时区的报错
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&useSSL=false&useUnicode=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true #注意8.0和5.0的区别
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

3,3 创建实体类

3,4 创建接口

@Mapper//表示这是一个mapper接口
@Repository//在容器中注册   等价于  @Component
public interface UserMapper {

    public static final int age=18;

    List<User> queryUserList();

    User queryUserById(Integer id);

    int addUser(User user);

    int updateUser(User user);

    int deleteUserById(Integer id);

}

也可以在springboot的主体类中添加@MapperScan(“mapper包路径”)//可以代替@mapper注解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VIclQMVm-1668096223483)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220917175919982.png)]

3,5创建mapper.xml文件

接下来该去配置mapper.xml文件了,这里建议创建在resources的目录下:

img

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--configuration core file-->
<mapper namespace="com.guo.mapper.UserMapper">

    <select id="queryUserList" resultType="User">
        
    </select>
//如果返回结果没有起别名,那么就要写全路径
     <!-- <select id="queryUserList"  
				  resultType="com.example.springbootjdbc.pojo.User.User">
						select * from user
    </select>
	-->
</mapper>

img

3,6在springboot核心配置文件中配置mybatis

mybatis:
  type-aliases-package: com.example.springbootjdbc.pojo.User #对包下的类起别名(首字母大小)
  mapper-locations: classpath:mybatis/mapper/*.xml #注册mapper.xml   classpath:resources资源目录

4,整合Dubbo

1,安装zooKeeper

网址:https://zookeeper.apache.org/releases.html

运行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RQoMav3i-1668096223483)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220928192648691.png)]

初次运行会报错,没有zoo.cfg配置文件;

解决方案:编辑zkServer.cmd文件末尾添加pause 。这样运行出错就不会退出,会提示错误信息,方便找到原因。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SsKyqls7-1668096223484)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220928192842879.png)]

3、修改zoo.cfg配置文件

将conf文件夹下面的zoo_sample.cfg复制一份改名为zoo.cfg即可。

注意几个重要位置:

dataDir=./ 临时数据存储的目录(可写相对路径)

clientPort=2181 zookeeper的端口号

修改完成后再次启动zookeeper

2,安装Dubbo-admin

1,下载

地址 :https://github.com/apache/dubbo-admin/tree/master

2、解压进入目录

修改 dubbo-admin\src\main\resources \application.properties 指定zookeeper地址

server.port=7001
spring.velocity.cache=false
spring.velocity.charset=UTF-8
spring.velocity.layout-url=/templates/default.vm
spring.messages.fallback-to-system-locale=false
spring.messages.basename=i18n/message
spring.root.password=root
spring.guest.password=guest

dubbo.registry.address=zookeeper://127.0.0.1:2181
//默认情况下是没有改的

开启方式一:

这种方式目前还有问题

3、在项目目录下打包dubbo-admin
mvn clean package -Dmaven.test.skip=true
4、执行 dubbo-admin\target 下的dubbo-admin-0.0.1-SNAPSHOT.jar

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dVZuH0Oh-1668096223484)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220928212813041.png)]

java -jar dubbo-admin-0.0.1-SNAPSHOT.jar

【注意:zookeeper的服务一定要打开!】

执行完毕,我们去访问一下 http://localhost:7001/ , 这时候我们需要输入登录账户和密码,我们都是默认的root-root;

登录成功后,查看界面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8X6Twbyo-1668096223485)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220928232724616.png)]

5,报错:

mvn打包报错

解决方法:

首先是ui模块构建失败,所以找到ui模块的pom.xml

在这里插入图片描述

找到导入失败的插件com.github.eirslett:frontend-maven-plugin

在这里插入图片描述

手动去远程仓库查找对应的插件

链接:https://repo.maven.apache.org/maven2/com/github/eirslett/frontend-maven-plugin/

在这里插入图片描述

在这里插入图片描述

更名为刚刚pom.xml所对应的名字 frontend-maven-plugin-1.9.0.jar (对应版本号

在这里插入图片描述

再前往pom.xml修改对应配置,与刚刚在本地仓库创建的文件夹、文件名一致

在这里插入图片描述

然后把

<goals>
	<goal>npm</goal>
</goals>

都删除掉

防止构建时用npm的方式下载插件

完整代码:

<plugin>
                <groupId>com.github.eirslett</groupId>
                <artifactId>frontend-maven-plugin</artifactId>
                <version>1.9.0</version>
                <executions>
                    <execution>
                        <id>install node and npm</id>
                        <configuration>
                            <nodeVersion>v9.11.1</nodeVersion>
                        </configuration>
                    </execution>
                    <!-- Install all project dependencies -->
                    <execution>
                        <id>npm install</id>
                        <!-- optional: default phase is "generate-resources" -->
                        <phase>generate-resources</phase>
                        <!-- Optional configuration which provides for running any npm command -->
                        <configuration>
                            <arguments>install</arguments>
                        </configuration>
                    </execution>
                    <!-- Build and minify static files -->
                    <execution>
                        <id>npm run build</id>
                        <configuration>
                            <arguments>run build</arguments>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

再用maven打包就ok啦

mvn clean package -Dmaven.test.skip=true

大概原理是,maven在远程仓库找不到该依赖,我们用我们找到的依赖放到本地仓库,构建时会先检查本地仓库是否有所需依赖。

开启方式二

第一步,启动zookeeper

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KSNzzF9n-1668096223485)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220928233605597.png)]

第二步: 启动 dubbo-admin-ui:

cd找到 dubbo-admin-ui 执行:npm run dev

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AgO9xyUi-1668096223485)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220928233740103.png)]

如果报错vue-cli不是内部命令,就重新npm install一下

第三步:idea启动dubbo-admin-server

找到 dubbo-admin-server 下的 application,并 配置端口号 :

server.port = 7001

在这里插入图片描述

之后启动 项目:

值得注意的是:
此时 dubbo-admin-ui 下的vue.config.js:

在这里插入图片描述

需要将 target 的端口号与后端的一致:

在这里插入图片描述

最后,点击如下任意一个 即可启动前端页面

在这里插入图片描述

在这里插入图片描述

Dubbo(注册中心)分布式开发

1,创建一个**provider(服务者)**项目

​ 这个项目相当于是一个服务的提供者

2,创建一个**Consumer(消费者)**项目

​ 这个项目相当于一个服务的消费者

3,在两个项目中导入需要的包

<!--dubbo-->
<!--将服务提供者注册到注册中心,我们需要整合Dubbo和zookeeper,所以需要导包-->
<!-- Dubbo Spring Boot Starter -->
<dependency>
   <groupId>org.apache.dubbo</groupId>
   <artifactId>dubbo-spring-boot-starter</artifactId>
   <version>2.7.3</version>
</dependency>
<!--zookeeper-->
<!--zookeeper的包我们去maven仓库下载,zkclient;-->
<!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
<dependency>
   <groupId>com.github.sgroschupf</groupId>
   <artifactId>zkclient</artifactId>
   <version>0.1</version>
</dependency>
<dependency>
   <groupId>org.apache.curator</groupId>
   <artifactId>curator-framework</artifactId>
   <version>2.12.0</version>
</dependency>
<dependency>
   <groupId>org.apache.curator</groupId>
   <artifactId>curator-recipes</artifactId>
   <version>2.12.0</version>
</dependency>
<dependency>
   <groupId>org.apache.zookeeper</groupId>
   <artifactId>zookeeper</artifactId>
   <version>3.4.14</version>
   <!--排除这个slf4j-log4j12
【新版的坑】zookeeper及其依赖包,解决日志冲突,还需要剔除日志依赖;-->
   <exclusions>
       <exclusion>
           <groupId>org.slf4j</groupId>
           <artifactId>slf4j-log4j12</artifactId>
       </exclusion>
   </exclusions>
</dependency>

4,修改消费者,服务者的配置文件

《服务者配置文件》
#当前应用名字(项目名)
dubbo.application.name=provider-server
#注册中心地址(这个地址和你的zookeeper相关)
dubbo.registry.address=zookeeper://127.0.0.1:2181
#扫描指定包下服务(需要注册在注册中心上给消费者使用的服务【自己写的方法和类】)
dubbo.scan.base-packages=com.example.providerserver.service
#服务者端口
server.port=8081
#因为之前的20880端口被占,所以修改端口
dubbo.protocol.port=20881


《消费者配置文件》
#当前应用名字(项目名)
dubbo.application.name=consumer-server
#注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181

#服务者是将自己的信息,和自己要发送的服务传递给注册中心
#消费者是将自己的信息发送给注册中心去取服务

5,将服务放在容器和注册中心中

@Component //放在容器中,这里不用service注解的原因是为了区分
@Service//项目一启动发布到注册中心
//service关联的类import org.apache.dubbo.config.annotation.Service;
public class TicketServiceImpl implements TicketService{
    @Override
    public String getTicket() {
        return "《狂神说Java》";
    }
}

6,开启zookeeper,然后启动服务者项目就可以看到服务被注册

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dMdo9pFQ-1668096223486)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220929221716552.png)]

也可以通过dubbo-admin看

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Iax9fvlt-1668096223486)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220929224440444.png)]

消费者取服务的流程

1,导入相关包

2,编写配置类

3,编写一个获取服务的类

@Component //注入到容器中
public class UserService {
    /**
     *  我们需要去拿去注册中心的服务
     *  @Reference  远程应用自动装配
     *  等价于 @Autowired的自动装配,只是Autowired是装配本地项目的类
     *   @Reference  是装配其他项目中的类(在注册中心注册的接口)
     *   此时可以发现会爆红这是因为本项目没有这个类
     *   解决方法:
     *   1,引用pom坐标(不会)
     *   2,创建一个被引用类相同的路径类,内容可以不一样
     */
    @Reference//远程注册这个类
    TicketService ticketService;
    
    public void buyTicket(){
        String ticket = ticketService.getTicket();
        System.out.println("在注册中心买到"+ticket);
    }
}

4,还原远程注册接口的路径

首先服务者向注册中心注册的服务类路径:

image-20220929231344372

在消费者项目中还原这个路径(可以不用遵循所有资源要在springboot主类的同一路径上)

里面的方法可以不同,但是服务者有的消费者尽量有(因为一会要调这个方法)

image-20220929231322835

5,编写测试类

@SpringBootTest
class ConsumerServerApplicationTests {
    //这里自动装配的是那个调服务的类
   @Autowired
   UserService userService;

   @Test
   public void contextLoads() {
      userService.buyTicket();
   }
}

6,运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a3T6qYIu-1668096223487)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220929231930809.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Q7MkWNA-1668096223487)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220929233255504.png)]

可能报错

Fail to start server(url: dubbo://192.168.0.9:20880/service

原因:

20880端口被占

只需要修改项目的dubbo端口即可

//在服务者核心配置文件中写
dubbo.protocol.port=20881
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值