SpringBoot配置多数据源

最详细的SpringBoot配置多数据源讲解 关于springboot配置多数据源整理了笔记,分享给有需要的小伙伴,视频是看的动力节点王鹤老师讲的springboot, 动力节点王鹤老师讲解的springboot教程,由浅入深,带你体验Spring Boot的极速开发过程,内容丰富,涵盖了SpringBoot开发的方方面面,并且同步更新到Spring Boot 2.x系列的最新版本。 视频链接:动力节点springboot视频教程-初学springboot必备教程-springboot最新完整版_哔哩哔哩_bilibili你的三连就是录制视频的动力 阅读详情

有时候我们需要一个项目中连接多个数据源,这里我们将展示spring boot以及xml方式配置多数据源的方式。

一、Springboot配置多数据源

spring boot配置多数据源,只需要先将数据库连接信息写入配置文件,然后编写相应的数据源配置类,最后在spring boot启动中排除默认配置的数据源即可。

1.添加数据源连接信息

在application.properties中加入如下配置:(示例中其实是同一个数据源不同的库)

### 主数据源
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.primary.url=jdbc:mysql:///zzs?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&useSSL=false&verifyServerCertificate=false&serverTimezone=GMT
spring.datasource.primary.username=root
spring.datasource.primary.password=root

### 第二数据源
spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.secondary.url=jdbc:mysql:///weblog?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&useSSL=false&verifyServerCertificate=false&serverTimezone=GMT
spring.datasource.secondary.username=root
spring.datasource.secondary.password=root

2.编写每一个数据源对应的配置类

主数据源对应的配置类:

以下加入了JdbcTemplate以及Mybatis以及事务等的支持,如果不需要,去掉相应的方法即可

package com.example.demo.config.ds;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * @author zzs
 * @date 2019/9/10 20:39
 */
@Configuration
//@MapperScan指定mybatis的扫描路径
@MapperScan(basePackages = "com.example.demo.db.primary.dao", sqlSessionTemplateRef  = "primarySqlSessionTemplate")
public class PrimaryDataSourceConfig {

    /**
     * 这里的@Primary注解是指存在多个相同类型的bean时,首选哪个进行注入
     *
     * 因为配置了多个相同的bean,因此@Bean注解要指定bean名称,后面注入时也需要@Qualifier指定哪个bean
     */
    @Primary
    @Bean(name = "primaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    public DataSource primaryDataSource() {
        //这里根据配置中的spring.datasource.primary前缀实例化数据源
        return DruidDataSourceBuilder.create().build();
    }

    /** JdbcTemplate支持 **/
    @Primary
    @Bean(name = "primaryJdbcTemplate")
    public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    /** Mybatis支持 **/
    @Primary
    @Bean(name = "primarySqlSessionFactory")
    public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //Mybatis配置文件
        //bean.setConfigLocation(new PathMatchingResourcePatternResolver().getResource("classpath:mybatis-config.xml"));
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:com/example/demo/db/primary/**/*.xml"));
        return bean.getObject();
    }

    /** 事务 **/
    @Primary
    @Bean(name = "primaryTransactionManager")
    public DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Primary
    @Bean(name = "primarySqlSessionTemplate")
    public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("primarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

第二个数据源的配置类,也是一样的:

package com.example.demo.config.ds;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * @author zzs
 * @date 2019/9/10 21:13
 */
@Configuration
@MapperScan(basePackages = "com.example.demo.db.secondary.dao", sqlSessionTemplateRef  = "secondarySqlSessionTemplate")
public class SecondaryDataSourceConfig {

    @Bean(name = "secondaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "secondaryJdbcTemplate")
    public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    @Bean(name = "secondarySqlSessionFactory")
    public SqlSessionFactory primarySqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //bean.setConfigLocation(new PathMatchingResourcePatternResolver().getResource("classpath:mybatis-config.xml"));
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:com/example/demo/db/secondary/**/*.xml"));
        return bean.getObject();
    }

    @Bean(name = "secondaryTransactionManager")
    public DataSourceTransactionManager primaryTransactionManager(@Qualifier("secondaryDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "secondarySqlSessionTemplate")
    public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("secondarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

3.排除Springboot默认的数据源

在启动类上添加如下:

@SpringBootApplication(exclude = {
        DataSourceAutoConfiguration.class
})
public class SingleDemoApplication {

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

4.测试

这里就不展示了。

以上就是Springboot配置多数据源的方式,下面我们继续探索传统的xml配置方式

二、xml方式配置多数据源

xml比较简单,直接加入另一个数据源连接信息,然后指定其中一个为默认的即可:

这里有两个xml文件,spring-dao.xml和spring-beanContext.xml,第一个spring-dao.xml是数据源的配置,包括数据库连接信息、事务等,第二个spring-beanContext.xml是mybatis的相关配置。

spring-dao.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:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="parentDataSource" class="com.alibaba.druid.pool.DruidDataSource" abstract="true">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="maxActive" value="10"/>
        <property name="minIdle" value="1"/>
        <property name="initialSize" value="3"/>
        <property name="maxWait" value="3000"/>
        <property name="testWhileIdle" value="true" />
        <property name="timeBetweenEvictionRunsMillis" value="180000" />
        <property name="validationQuery" value="SELECT 1"/>
        <property name="validationQueryTimeout" value="3"/>
        <property name="filters" value="config"/>
    </bean>
    
    <!-- 其中primary="true"即表示该数据源为默认数据源 -->
    <!-- primary -->
    <bean id="primaryDataSource" parent="parentDataSource" init-method="init" destroy-method="close" primary="true">
        <property name="url" value=""/>
        <property name="username" value=""/>
        <property name="password" value=""/>

    </bean>

    <!-- secondary -->
    <bean id="secondaryDataSource" parent="parentDataSource" init-method="init" destroy-method="close">
        <property name="url" value=""/>
        <property name="username" value=""/>
        <property name="password" value=""/>
    </bean>


    <!-- 配置jdbcTemplate -->
    <bean name="primaryJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="primaryDataSource"/>
    </bean>

    <bean name="secondaryJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="secondaryDataSource"/>
    </bean>


    <!-- 库事务管理配置  开始 -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="primaryDataSource"/>
    </bean>

    <!-- ①使用注解 -->
    <!--<tx:annotation-driven  transaction-manager="txManager" />-->

    <!-- ②使用AOP切面的方式 -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="create*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
            <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
            <tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception" isolation="READ_COMMITTED"/>
            <tx:method name="insert*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
            <tx:method name="del*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
            <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
            
            <!--<tx:method name="*" read-only="true"/>-->
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="allManagerMethod1"
                      expression="execution(* com.example..*.service..*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod1"/>
    </aop:config>

    <!-- 主库事务管理配置  结束  -->
</beans>

spring-beanContext.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">

    <!-- mybatis start -->

    <!-- primary -->
    <bean id="primarySqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="primaryDataSource"/>
        <property name="mapperLocations"
                  value="classpath:com/example/demo/db/primary/**/*.xml"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>
    <bean id="primarySqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="primarySqlSessionFactory" />
    </bean>
    <bean id="primaryDb" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.example.demo.db.primary.dao"/>
        <property name="sqlSessionTemplateBeanName" value="primarySqlSessionTemplate"/>
    </bean>

    <!-- secondary -->
    <bean id="secondarySqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="secondaryDataSource"/>
        <property name="mapperLocations"
                  value="classpath:com/example/demo/db/secondary/**/*.xml"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>
    <bean id="secondarySqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="secondarySqlSessionFactory" />
    </bean>
    <bean id="secondaryDb" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.example.demo.db.secondary.dao"/>
        <property name="sqlSessionTemplateBeanName" value="secondarySqlSessionTemplate"/>
    </bean>

    <!-- mybatis end -->

</beans>

最后,在applicationContext.xml中引入这两个文件即可。

springboot之多数据源配置 应用直接操作的是abstractRoutingDataSource的实现类,告诉AbstractRoutingDataSource访问哪个数据库,然后由AbstractRoutingDataSource从事先配置好的数据源 (ds1,ds2)选择哪一个 ,来访问对应的数据库。 阅读详情

相关推荐

Springboot多数据源配置

分库分表在大项目中非常的常见,此时就可能会遇到,一个项目需要连接多个数据源的情况,下面就以springboot框架来实现连接多个mysql数据源

yghandsome的博客 1122

SpringBoot多数据源配置

文章目录1 SpringBoot分库配置1.1 准备数据1.2 springboot+mybatis使用分包方式整合1.2.1 pom.xml1.2.2 application.yml 配置文件1.2.3 连接数据源配置文件1.2.3.1 连接源配置一1.2.3.2 连接源配置二1.2.4 项目结构1.3 springboot+druid+mybatisplus使用注解整合1.3.1 pom.xml1.3.2 application.yml 配置文件1.3.3 使用@DS区分数据源1.4 读写分离库1.4.

上善若泪 3万+

深入探讨Spring Boot中的DataSourceAutoConfiguration:何时去掉自动数据源配置

Spring Boot自动配置简化了开发,其中DataSourceAutoConfiguration自动配置数据库连接。但有时需要更多控制权,或者遇到问题,需要禁用它。本文深入探讨DataSourceAutoConfiguration,讨论去掉它的原因、潜在问题和如何正确使用。帮助您理解exclude = DataSourceAutoConfiguration.class的含义,以满足应用需求。

专注于深入研究多种编程语言,以实战为导向,逐步拓展开发技能,提升工程化编码和思维能力,展现无敌技术实力。 1479

SpringBoot多数据源配置详解

动态数据源上下文// 使用ThreadLocal保证线程安全// 数据源列表动态数据源配置/*** 创建动态数据源 Bean,并将其设置为主要的数据源 Bean// 用于存储目标数据源的映射,键为数据源标识,值为数据源实例 Map < Object , Object > targetDataSources = new HashMap < >();

墨鸦的博客 1万+

大模型-高通qnn基础

提供较低级别、高度可定制的统一API,通过单独的库加速所有AI加速器核心上的AI模型, 可以直接用于针对特定的加速器核心或从流行的运行时(包括Qualcomm Neural Processing SDK、TensorFlow Lite和ONNX运行时)委派工作负载。一个支持异构计算、系统级配置的一体化SDK,旨在将AI工作负载引导到我们平台上的所有加速器核心。为开发人员提供灵活性,包括核心间协作支持和其他高级功能。是一个为训练好的神经网络模型提供高级量化和压缩技术的库。

点滴的岁月 4097

论文阅读—Square Attack: a query-efficient black-box adversarial attack via random search

论文阅读—Square Attack: a query-efficient black-box adversarial attack via random search 发表位置 ECCV 2020 摘要 作者提出了一种基于得分的黑盒Square attack,该模型不依赖于模型的局部梯度信息,因此可以绕过梯度隐藏防御攻击。Square Attack是一种随机搜索方法,它在随机位置选择局部的方形更新,使得每次迭代时扰动近似位于可行集的边界。 背景 当涉及到对安全至关重要的机器学习应用时,对抗性的例子尤其值得

yayayamaomaoya的博客 2495

springboot+dynamic多数据源配置

springboot+dynamic多数据源配置配置使用 springboot+dynamic多数据源配置 来源:https://mp.baomidou.com/guide/dynamic-datasource.html dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器。 配置...

weixin_30387663的博客 1916

ubuntu为Docker配置代理

我们平常在ubuntu终端中使用curl或git命令时,往往会很慢。所以,首先需要给ubuntu终端环境添加代理。查看自身那个软件的端口号,我这里是7890。

不想随波逐流的大学生一枚,我们每个人都在努力奔跑 1643

springboot配置多数据源

之前的文章我们已经实现了springboot的连接池,springboot添加数据库连接池druid-优快云博客。现在我们来实现一下多数据源的配置。

bailegebai的博客 3831

IAR调试CC1310的错误:Fatal error:Failed to connect to the XDS emlulator (Error -241 @ 0x0:)

从simplelink_cc13x0_sdk_2_10_00_36导入collector工程后,rebuild后进行debug,出现了如图错误:Fatal error:Failed to connect to the XDS emlulator (connect ICEPick)...(Error -241 @ 0x0)A router subpath could not be accessed....

qq_40417648的博客 6228

IPD实战指南:如何运用SPAN模型精准定位高潜力市场并优化资源配置

本文是IPD实战指南,详细解析了如何运用SPAN模型进行市场分析与战略决策。文章通过四步实战法,指导企业科学定义细分市场、量化评估吸引力与竞争力,并绘制矩阵以制定精准的资源配置策略,从而跳出红海竞争,将资源聚焦于高潜力市场。

weixin_29306317的博客 75

springboot使用dynamic做多数据源配置

本文介绍一下springboot使用dynamic做动态数据源配置。

qq_50867577的博客 3758

spring boot 集成cas(一) 服务端搭建

简单点就是统一服务认证,多个系统一次登录。俗称单点登录。

慕孑晨的博客 1957

【springboot专题】二十 springboot中如何配置多数据源

使用springboot+mybatis-plus+多数据源+swagger实现多数据源,以及如何解决多数据源事务一致性。

程序猿学社的博客 1万+

YOLOv11改进-卷积-引入小波卷积WTConv 解决多尺度小目标问题

1.首先,WTConv利用二维Haar小波变换对输入图像进行多级分解。低频分量 (LL):捕捉图像的低频信息,如整体形状或轮廓。水平高频分量 (LH):捕捉图像中的水平边缘信息。垂直高频分量 (HL):捕捉图像中的垂直边缘信息。对角线高频分量 (HH):捕捉图像的对角线细节。在每一级的小波变换中,图像被下采样(空间分辨率减半),但频率信息得到了更细的分解。递归地执行小波变换(称为多级分解)可以得到不同尺度下的频率分量。

qq_64693987的博客 1万+

【Bug已解决】Request timed out / API Timeout — Claude Code 请求超时解决方案

方案适用场景推荐指数难度方案一:增加超时大任务处理⭐⭐⭐⭐⭐低方案二:切换 SonnetOpus 太慢⭐⭐⭐⭐⭐低方案三:缩小范围大代码库⭐⭐⭐⭐⭐低方案四:优化网络网络延迟高⭐⭐⭐⭐中方案五:减少 MCPMCP 超时⭐⭐⭐中方案六:流式响应长生成任务⭐⭐⭐低根本原因:请求超时最常见原因是请求体过大(35%)和 Opus 模型推理慢(25%),默认 60 秒超时阈值对大型任务不够最佳实践。

一键难忘的博客 5164

SpringBoot配置JPA多数据源

SpringBoot版本 不同的版本其配置方式可能有所区别,我采用的是SpringBoot2.0.4.RELEASE。 多数据源配置 application.yml配置如下: spring: application: name: test jpa: hibernate: ddl-auto: update show-sql: true datasour...

在下的博客 8251

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

SpringBoot下配置Mybatis多数据源

spring boot 整合mybatis 多数据源。对于现在的web项目来说,很多大一点的项目都是微服务框架,这就导致web项目需要访问多个数据源,每一个小的模块是一个自己独立的数据源。这时候就需要配置多数据源了,对于多数据源,spring boot支持就是需要配置一个主数据源,若干个非主数据源,可以实现自由切换。只是实现数据源bean注入的时候需要注意一下,主数据源需要加上@Primary注解,其他非主数据源一定不能加@Primary注解,否者启动报错。

tianhouquan的专栏 1879

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SpringBoot实现多数据源配置

SpringBoot实现多数据源配置

一恍过去 3万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Spring Boot多数据源配置之JdbcTemplate

多数据源配置也算是一个常见的开发需求,Spring和SpringBoot中,对此都有相应的解决方案,不过一般来说,如果有多数据源的需求,我还是建议首选分布式数据库中间件MyCat去解决相关问题,之前有小伙伴在我的知识星球上提问,他的数据根据条件的不同,可能保存在四十多个不同的数据库中,怎么办?这种场景下使用多数据源其实就有些费事了,我给的建议是使用MyCat,然后分表策略使用sharding-by...

江南一点雨的专栏 1万+

Spring Boot 实现多数据源配置

在application.properties或application.yml中配置多个数据源的连接信息。在 Spring Boot 中实现多数据源配置通常用于需要连接多个数据库的场景。首先,在pom.xml中添加MyBatis、数据库驱动和Spring Boot的JDBC依赖。在Spring Boot中,通过@Configuration类来配置多个数据源的Bean。将Mapper接口和XML文件分别放在不同的包中,以区分不同的数据源。主数据源Mapper XML文件。次数据源Mapper XML文件。

qq_33807380的博客 5831
上一篇: axios+springboot实现图片预览(POST方式)
下一篇: Mybatis批量提交
淋雨一直走啊
博客等级 码龄11年 39粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值