spring+jpa+hibernate实现多数据源

12 篇文章 0 订阅
2 篇文章 0 订阅

关键配置:AbstractRoutingDataSource

使用这个动态管理DataSource的数据源就可以实现动态切换数据源了,亲测可用。

给出部分配置代码:

spring-datasource.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">
	<description>数据源配置</description>

	<!-- 数据源模板 -->
	<bean id="dataSourceTemplate"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName"
			value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>
	<!-- 数据源,Tomcat-jdbc实现 -->
	<bean id="dataSource"
		class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
		<!-- 通过引用加载数据库信息,否则会报找不到数据库驱动的错误 -->
		<property name="dataSource" ref="dataSourceTemplate" />
		<!-- (int) 初始化连接: 连接池启动时创建的初始化连接数量 -->
		<property name="initialSize" value="${jdbc.initialPoolSize}" />
		<property name="minIdle" value="${jdbc.minPoolSize}" />
		<property name="maxIdle" value="${jdbc.maxPoolSize}" />
		<property name="maxActive" value="${jdbc.maxPoolSize}" />
		<property name="maxWait" value="600" />
		<property name="removeAbandoned" value="true" />
		<!-- (int) 泄露的连接可以被删除的超时值, 单位秒应设置为应用中查询执行最长的时间 -->
		<property name="removeAbandonedTimeout" value="600" />
		<property name="validationQuery" value="select 1" />
		<property name="validationInterval" value="30000" />
		<!-- (boolean) 连接池创建的连接的默认的auto-commit 状态,driver default -->
		<property name="defaultAutoCommit" value="true" />
		<!-- 验证失败时,是否将连接从池中丢弃 -->
		<property name="testWhileIdle" value="true" />
		<property name="timeBetweenEvictionRunsMillis"
			value="1200000" />
		<!-- 连接池中连接可空闲的时间(毫秒,5分钟) -->
		<property name="minEvictableIdleTimeMillis" value="1800000" />
		<!-- 在每次空闲连接回收器线程(如果有)运行时检查的连接数量 -->
		<property name="numTestsPerEvictionRun" value="5" />
	</bean>

	<!-- 数据源模板2 -->
	<bean id="dataSourceTemplate2"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName"
			value="${jdbc2.driverClassName}" />
		<property name="url" value="${jdbc2.url}" />
		<property name="username" value="${jdbc2.username}" />
		<property name="password" value="${jdbc2.password}" />
	</bean>
	<!-- 数据源2,Tomcat-jdbc实现 -->
	<bean id="dataSource2"
		class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
		<!-- 通过引用加载数据库信息,否则会报找不到数据库驱动的错误 -->
		<property name="dataSource" ref="dataSourceTemplate2" />
		<!-- (int) 初始化连接: 连接池启动时创建的初始化连接数量 -->
		<property name="initialSize" value="${jdbc2.initialPoolSize}" />
		<property name="minIdle" value="${jdbc2.minPoolSize}" />
		<property name="maxIdle" value="${jdbc2.maxPoolSize}" />
		<property name="maxActive" value="${jdbc2.maxPoolSize}" />
		<property name="maxWait" value="600" />
		<property name="removeAbandoned" value="true" />
		<!-- (int) 泄露的连接可以被删除的超时值, 单位秒应设置为应用中查询执行最长的时间 -->
		<property name="removeAbandonedTimeout" value="600" />
		<property name="validationQuery" value="select 1" />
		<property name="validationInterval" value="30000" />
		<!-- (boolean) 连接池创建的连接的默认的auto-commit 状态,driver default -->
		<property name="defaultAutoCommit" value="true" />
		<!-- 验证失败时,是否将连接从池中丢弃 -->
		<property name="testWhileIdle" value="true" />
		<property name="timeBetweenEvictionRunsMillis"
			value="1200000" />
		<!-- 连接池中连接可空闲的时间(毫秒,5分钟) -->
		<property name="minEvictableIdleTimeMillis" value="1800000" />
		<!-- 在每次空闲连接回收器线程(如果有)运行时检查的连接数量 -->
		<property name="numTestsPerEvictionRun" value="5" />
	</bean>

	<!-- 路由数据源配置 -->
	<bean id="dynamicDataSource"
		class="com.szhis.frsoft.common.datasource.DynamicDataSource">
		<!-- 默认数据源 -->
		<property name="defaultTargetDataSource" ref="dataSource"></property>
		<!-- 数据源集合 -->
		<property name="targetDataSources">
			<map key-type="java.lang.String">
				<entry key="first" value-ref="dataSource" />
				<entry key="second" value-ref="dataSource2" />
			</map>
		</property>
	</bean>

</beans>

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:jpa="http://www.springframework.org/schema/data/jpa"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">
	<description>持久层配置</description>

	<!-- jpa 实体工厂 -->
	<bean id="entityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<!-- 指定路由数据源,这个很关键 -->
		<property name="dataSource" ref="dynamicDataSource" />
		<property name="packagesToScan"
			value="com.szhis.frsoft.entity" />
		<property name="persistenceProvider">
			<bean class="org.hibernate.jpa.HibernatePersistenceProvider"></bean>
		</property>
		<property name="jpaDialect">
			<bean
				class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"></bean>
		</property>
		<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
		<property name="jpaProperties" ref="entityProps" />
	</bean>
	<bean id="jpaVendorAdapter"
		class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
		<property name="generateDdl" value="false" />
		<property name="database"
			value="${jpaVendorAdapter.database}" />
		<property name="databasePlatform"
			value="${jpaVendorAdapter.databasePlatform}" />
	</bean>
	<util:properties id="entityProps">
		<prop key="hibernate.show_sql">true</prop>
		<prop key="hibernate.format_sql">false</prop>
		<prop key="hibernate.jdbc.fetch_size">30</prop>
		<prop key="hibernate.jdbc.batch_size">15</prop>
		<prop key="hibernate.order_inserts">true</prop>
		<prop key="hibernate.order_updates">true</prop>
		<prop key="hibernate.check_nullability">false</prop>
		<prop key="javax.persistence.sharedCache.mode">ENABLE_SELECTIVE</prop>
		<prop key="hibernate.generate_statistics">false</prop>
		<prop key="hibernate.id.new_generator_mappings">true</prop>
		<prop key="hibernate.id.optimizer.pooled.prefer_lo">true</prop>
		<prop key="hibernate.archive.autodetection">class</prop>
		<!-- 开启一级缓存 -->
		<prop key="hibernate.cache.use_query_cache">true</prop>
		<!-- 开启二级缓存 -->
		<prop key="hibernate.cache.use_second_level_cache">true</prop>
		<!-- 缓存,ehcache实现 -->
		<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
		</prop>
		<prop key="net.sf.ehcache.configurationResourceName">cache/ehcache.xml</prop>
	</util:properties>

	<!-- Spring Data Jpa配置 jpa Dao必须定义该标签 -->
	<jpa:repositories
		base-package="com.szhis.frsoft.repository"
		factory-class="com.szhis.frsoft.common.persistence.FRJpaRepositoryFactoryBean"
		transaction-manager-ref="transactionManager"
		entity-manager-factory-ref="entityManagerFactory"
		repository-impl-postfix="Impl" />

</beans>

config.properties

#jpa配置
jpaVendorAdapter.database = MYSQL
jpaVendorAdapter.databasePlatform = org.hibernate.dialect.MySQL5Dialect


#jdbc配置
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://127.0.1:3306/fr-db01?useSSL=false
jdbc.username = root
jdbc.password = 1234
#数据库连接池-c3p0
jdbc.checkoutTimeout = 2000
#初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间
jdbc.initialPoolSize = 5
jdbc.minPoolSize = 5
jdbc.maxPoolSize = 15


#数据源2
jdbc2.driverClassName = com.mysql.jdbc.Driver
jdbc2.url = jdbc:mysql://127.0.1:3306/fr-db02?useSSL=false
jdbc2.username = root
jdbc2.password = 1234
#数据库连接池-c3p0
jdbc2.checkoutTimeout = 2000
#初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间
jdbc2.initialPoolSize = 5
jdbc2.minPoolSize = 5
jdbc2.maxPoolSize = 15





pom.xml

<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>com.szhis.frsoft</groupId>
	<artifactId>multiple-dataSource-ex1</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<properties>
		<!-- Generic properties -->
		<java.version>1.7</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

		<!-- common -->
		<commons-lang3.version>3.2.1</commons-lang3.version>
		<commons-dbutils.version>1.6</commons-dbutils.version>
		<guava.version>16.0.1</guava.version>
		<commons-codec.version>1.9</commons-codec.version>

		<!-- 数据连接 -->
		<mysql.version>5.1.40</mysql.version>
		<!-- sql server driver 注意jdk7必须使用1.3.0版本1.3.0以下不支持jdk7 -->
		<jtds.version>1.3.0</jtds.version>

		<!-- Web -->
		<jsp.version>2.2</jsp.version>
		<jstl.version>1.2</jstl.version>
		<servlet.version>2.5</servlet.version>

		<!-- Spring -->
		<spring-framework.version>4.1.9.RELEASE</spring-framework.version>
		<spring-data-jpa.version>1.7.4.RELEASE</spring-data-jpa.version>

		<!-- hibernate -->
		<hibernate.version>4.3.11.Final</hibernate.version>
		<hibernate-validator.version>5.0.3.Final</hibernate-validator.version>
		<jackson-datatype-hibernate4.version>2.9.5</jackson-datatype-hibernate4.version>

		<!-- json -->
		<jackson.version>2.6.7</jackson.version>
		<aspectj.version>1.7.4</aspectj.version>
		<shiro.version>1.2.3</shiro.version>

		<!-- 缓存 -->
		<ehcache-core.version>2.6.8</ehcache-core.version>

		<!-- 日志 -->
		<logback.version>1.0.13</logback.version>
		<slf4j.version>1.7.5</slf4j.version>

		<!-- 测试 -->
		<junit.version>4.12</junit.version>
		<groboutils.version>5</groboutils.version>
		<assertj.version>1.5.0</assertj.version>
		<mockito.version>1.9.5</mockito.version>
		<selenium.version>2.40.0</selenium.version>
	</properties>

	<dependencies>
		<!-- java公共组件 -->
		<dependency>
			<groupId>javax.mail</groupId>
			<artifactId>mail</artifactId>
			<version>1.4.7</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>${commons-lang3.version}</version>
		</dependency>
		<!-- shiro依赖commons-beanutils包 -->
		<dependency>
			<groupId>commons-beanutils</groupId>
			<artifactId>commons-beanutils</artifactId>
			<version>1.8.3</version>
		</dependency>
		<!-- 编码解码工具md5,sha1,base64 -->
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
			<version>${commons-codec.version}</version>
		</dependency>
		<!-- 文件上传 -->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.1</version>
		</dependency>
		<!-- 数据库驱动器,mysql driver -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.version}</version>
		</dependency>
		<!-- 数据库连接池,tomcat-jdbc -->
		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-jdbc</artifactId>
			<version>7.0.54</version>
			<scope>provided</scope>
		</dependency>
		<!-- spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<!-- Spring MVC -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<!-- spring aop -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${aspectj.version}</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>${aspectj.version}</version>
		</dependency>
		<!-- Other Web dependencies -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>${jstl.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>${servlet.version}</version>
			<scope>provided</scope>
		</dependency>
		<!-- websocket -->
		<dependency>
			<groupId>javax</groupId>
			<artifactId>javaee-api</artifactId>
			<version>7.0</version>
			<scope>provided</scope>
		</dependency>
		<!-- Spring and Transactions -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<!-- Logging with SLF4J & LogBack -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>${logback.version}</version>
			<scope>runtime</scope>
		</dependency>
		<!-- 代码直接调用log4j会被桥接到slf4j -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>log4j-over-slf4j</artifactId>
			<version>${slf4j.version}</version>
			<scope>runtime</scope>
		</dependency>
		<!-- 代码直接调用common-logging会被桥接到slf4j -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${slf4j.version}</version>
			<scope>runtime</scope>
		</dependency>
		<!-- 代码直接调用java.util.logging会被桥接到slf4j -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jul-to-slf4j</artifactId>
			<version>${slf4j.version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>com.googlecode.log4jdbc</groupId>
			<artifactId>log4jdbc</artifactId>
			<version>1.2</version>
			<scope>runtime</scope>
		</dependency>
		<!-- LOGGING end -->
		<!-- JSON begin -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>${jackson.version}</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.module</groupId>
			<artifactId>jackson-module-jaxb-annotations</artifactId>
			<version>${jackson.version}</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.datatype</groupId>
			<artifactId>jackson-datatype-hibernate4</artifactId>
			<version>${jackson-datatype-hibernate4.version}</version>
			<!-- <version>2.4.0</version> -->
		</dependency>
		<!-- JSON end -->
		<!-- Hibernate -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-ehcache</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<!-- spring data access -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-jpa</artifactId>
			<version>${spring-data-jpa.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-core</artifactId>
			<version>${shiro.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-web</artifactId>
			<version>${shiro.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>${shiro.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-ehcache</artifactId>
			<version>${shiro.version}</version>
		</dependency>
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz</artifactId>
			<version>2.2.3</version>
			<exclusions>
				<exclusion>
					<groupId>c3p0</groupId>
					<artifactId>c3p0</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<!-- 使用apache httpclient做代理服务DebugProxyController -->
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5.2</version>
		</dependency>
		<!-- 测试组件 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring-framework.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- 緩存cache -->
		<dependency>
			<groupId>net.sf.ehcache</groupId>
			<artifactId>ehcache-core</artifactId>
			<version>2.6.8</version>
		</dependency>
	</dependencies>

</project>

java代码

使用aop注解需要注意:在spring中药支持注解开发,<aop:aspectj-autoproxy proxy-target-class="true" />

package com.szhis.frsoft.common.datasource;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @desc 多数据源,切面处理类
 * @author jaden.liu
 * @createTime 2018年10月1日 下午7:51:06
 * @version v1.0
 */
@Aspect
@Component
@Order(1)
public class DataSourceAspect {
	protected Logger logger = LoggerFactory.getLogger(getClass());

	@Pointcut("@annotation(com.szhis.frsoft.common.datasource.FRDataSource)")
	public void dataSourcePointCut() {
	}

	@Around("dataSourcePointCut()")
	public Object around(ProceedingJoinPoint point) throws Throwable {
		MethodSignature signature = (MethodSignature) point.getSignature();
		Method method = signature.getMethod();

		FRDataSource ds = method.getAnnotation(FRDataSource.class);
		if (ds == null) {
			DynamicDataSource.setDataSource(DataSourceNames.FIRST);
			logger.info("set datasource is " + DataSourceNames.FIRST);
		} else {
			DynamicDataSource.setDataSource(ds.name());
			logger.info("set datasource is " + ds.name());
		}

		try {
			return point.proceed();
		} finally {
			DynamicDataSource.clearDataSource();
			logger.info("clean datasource");
		}
	}

}
package com.szhis.frsoft.common.datasource;

/**
 * @desc 增加多数据源,在此配置
 * @author jaden.liu
 * @createTime 2018年10月1日 下午7:47:49
 * @version v1.0
 */
public interface DataSourceNames {

	String FIRST = "first";

	String SECOND = "second";

}
package com.szhis.frsoft.common.datasource;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource {

	@Override
	protected Object determineCurrentLookupKey() {
		return getDataSource();
	}

	/*
	 *ThreadLocal 用于提供线程局部变量,在多线程环境可以保证各个线程里的变量独立于其它线程里的变量。
	 * 也就是说 ThreadLocal 可以为每个线程创建一个【单独的变量副本】
	 * 相当于线程的 private static 类型变量。
	 */
	private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

	public static void setDataSource(String dataSource) {
		contextHolder.set(dataSource);
	}

	public static String getDataSource() {
		return contextHolder.get();
	}

	public static void clearDataSource() {
		contextHolder.remove();
	}

}
package com.szhis.frsoft.common.datasource;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @desc 多数据源注解
 * @author jaden.liu
 * @createTime 2018年10月1日 下午6:25:09
 * @version v1.0
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FRDataSource {

	/**
	 * @desc 设置数据源
	 * @author jaden.liu
	 * @createTime 2018年10月1日 下午6:25:42
	 * @return String
	 */
	String name() default "";

}

在后台就可以使用EntityManager.createQuery()方法了

测试用例就不传了,想要的了解更多可以私聊

就这些东西了,相信剩下的东西可以百度,能看我这个博客的maven要回玩才行啊!

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值