spring4.0.2+mybatis3.2.4+sharding-jdbc1.4.2实现分库分表、读写分离及事物支持

Sharding-JDBC实战   1、快速入门 1.1、分库分表数据库架构 以订单中心为例,无论库还是表,都是以卖家ID或者买家ID去分片。假设有两个数据库 order_center_0和order_center_1,每个库有两张表t_order_0,t_order_1以及t_order_item_0和t_order_item_1,于是我们得到下面的数据库架构: 1.2、Sharding-JDBC的配置 1.... 阅读详情

当当sharding-jdbc的使用公司挺多的,今天就整理下sharding-jdbc最新的配置及使用,包含实现分库分表、主从及事物支持范围。

1、pom文件引用

<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	    <spring.version>4.0.2.RELEASE</spring.version>
		<mybatis.version>3.2.4</mybatis.version>
	    <sharding-jdbc.version>1.4.2</sharding-jdbc.version>
	</properties>

<dependency>
			<groupId>com.dangdang</groupId>
			<artifactId>sharding-jdbc-core</artifactId>
			<version>${sharding-jdbc.version}</version>
		</dependency>
		<dependency>
			<groupId>com.dangdang</groupId>
			<artifactId>sharding-jdbc-config-spring</artifactId>
			<version>${sharding-jdbc.version}</version>
		</dependency>
2、spring配置
       spring-database.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:context="http://www.springframework.org/schema/context"
	xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
		http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

	<context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="true"/>
		
	<bean name="sharding_0" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
		<property name="url" value="${jdbc_url0}" />
		<property name="username" value="${jdbc_username0}" />
		<property name="password" value="${jdbc_password0}" />
<!-- 		<property name="driverClass" value="${jdbc_driver0}" /> -->
		<!-- 初始化连接大小 -->
		<property name="initialSize" value="0" />
		<!-- 连接池最大使用连接数量 -->
		<property name="maxActive" value="20" />
		<!-- 连接池最小空闲 -->
		<property name="minIdle" value="0" />
		<!-- 获取连接最大等待时间 -->
		<property name="maxWait" value="60000" />
		<property name="validationQuery" value="${validationQuery}" />
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />
		<property name="testWhileIdle" value="true" />
		<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
		<property name="timeBetweenEvictionRunsMillis" value="60000" />
		<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
		<property name="minEvictableIdleTimeMillis" value="25200000" />
		<!-- 打开removeAbandoned功能 -->
		<property name="removeAbandoned" value="true" />
		<!-- 1800秒,也就是30分钟 -->
		<property name="removeAbandonedTimeout" value="1800" />
		<!-- 关闭abanded连接时输出错误日志 -->
		<property name="logAbandoned" value="true" />
		<property name="filters" value="stat" />
	</bean>
	
	<bean name="sharding_1" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
		<property name="url" value="${jdbc_url1}" />
		<property name="username" value="${jdbc_username1}" />
		<property name="password" value="${jdbc_password1}" />
<!-- 		<property name="driverClass" value="${jdbc_driver1}" /> -->
		<!-- 初始化连接大小 -->
		<property name="initialSize" value="0" />
		<!-- 连接池最大使用连接数量 -->
		<property name="maxActive" value="20" />
		<!-- 连接池最小空闲 -->
		<property name="minIdle" value="0" />
		<!-- 获取连接最大等待时间 -->
		<property name="maxWait" value="60000" />
		<property name="validationQuery" value="${validationQuery}" />
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />
		<property name="testWhileIdle" value="true" />
		<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
		<property name="timeBetweenEvictionRunsMillis" value="60000" />
		<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
		<property name="minEvictableIdleTimeMillis" value="25200000" />
		<!-- 打开removeAbandoned功能 -->
		<property name="removeAbandoned" value="true" />
		<!-- 1800秒,也就是30分钟 -->
		<property name="removeAbandonedTimeout" value="1800" />
		<!-- 关闭abanded连接时输出错误日志 -->
		<property name="logAbandoned" value="true" />
		<property name="filters" value="stat" />
	</bean>


	<bean name="sharding_0_slave" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
		<property name="url" value="${jdbc_slave_url0}" />
		<property name="username" value="${jdbc_slave_username0}" />
		<property name="password" value="${jdbc_slave_password0}" />
		<!-- 		<property name="driverClass" value="${jdbc_driver0}" /> -->
		<!-- 初始化连接大小 -->
		<property name="initialSize" value="0" />
		<!-- 连接池最大使用连接数量 -->
		<property name="maxActive" value="20" />
		<!-- 连接池最小空闲 -->
		<property name="minIdle" value="0" />
		<!-- 获取连接最大等待时间 -->
		<property name="maxWait" value="60000" />
		<property name="validationQuery" value="${validationQuery}" />
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />
		<property name="testWhileIdle" value="true" />
		<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
		<property name="timeBetweenEvictionRunsMillis" value="60000" />
		<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
		<property name="minEvictableIdleTimeMillis" value="25200000" />
		<!-- 打开removeAbandoned功能 -->
		<property name="removeAbandoned" value="true" />
		<!-- 1800秒,也就是30分钟 -->
		<property name="removeAbandonedTimeout" value="1800" />
		<!-- 关闭abanded连接时输出错误日志 -->
		<property name="logAbandoned" value="true" />
		<property name="filters" value="stat" />
	</bean>

	<bean name="sharding_1_slave" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
		<property name="url" value="${jdbc_slave_url1}" />
		<property name="username" value="${jdbc_slave_username1}" />
		<property name="password" value="${jdbc_slave_password1}" />
		<!-- 		<property name="driverClass" value="${jdbc_driver1}" /> -->
		<!-- 初始化连接大小 -->
		<property name="initialSize" value="0" />
		<!-- 连接池最大使用连接数量 -->
		<property name="maxActive" value="20" />
		<!-- 连接池最小空闲 -->
		<property name="minIdle" value="0" />
		<!-- 获取连接最大等待时间 -->
		<property name="maxWait" value="60000" />
		<property name="validationQuery" value="${validationQuery}" />
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />
		<property name="testWhileIdle" value="true" />
		<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
		<property name="timeBetweenEvictionRunsMillis" value="60000" />
		<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
		<property name="minEvictableIdleTimeMillis" value="25200000" />
		<!-- 打开removeAbandoned功能 -->
		<property name="removeAbandoned" value="true" />
		<!-- 1800秒,也就是30分钟 -->
		<property name="removeAbandonedTimeout" value="1800" />
		<!-- 关闭abanded连接时输出错误日志 -->
		<property name="logAbandoned" value="true" />
		<property name="filters" value="stat" />
	</bean>
	

</beans>
     spring-sharding.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:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:rdb="http://www.dangdang.com/schema/ddframe/rdb"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
       http://www.dangdang.com/schema/ddframe/rdb  http://www.dangdang.com/schema/ddframe/rdb/rdb.xsd">
    <import resource="spring-database.xml"/>
	<context:component-scan base-package="com.yufei.sharding_jdbc" />

    
    
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.yufei.sharding_jdbc.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>
    
    <!-- 配置sqlSessionFactory -->
     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="shardingDataSource"/>
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>

    <rdb:master-slave-data-source id="rbb_0" master-data-source-ref="sharding_0" slave-data-sources-ref="sharding_0_slave"/>
    <rdb:master-slave-data-source id="rbb_1" master-data-source-ref="sharding_1" slave-data-sources-ref="sharding_1_slave"/>

    <rdb:strategy id="userTableStrategy"  sharding-columns="user_id" algorithm-class="com.yufei.sharding_jdbc.algorithm.UserTableShardingAlgorithm"/>

    <rdb:strategy id="userDataBaseStrategy"  sharding-columns="user_id" algorithm-class="com.yufei.sharding_jdbc.algorithm.UserDataBaseShardingAlgorithm"/>

    <rdb:data-source id="shardingDataSource">
        <rdb:sharding-rule data-sources="rbb_0,rbb_1" default-data-source="rbb_0">
            <rdb:table-rules>
                <rdb:table-rule logic-table="t_user" actual-tables="t_user_${0..2}" database-strategy="userDataBaseStrategy" table-strategy="userTableStrategy"/>
            </rdb:table-rules>
        </rdb:sharding-rule>
    </rdb:data-source>

    <!-- 事务 -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="shardingDataSource" />
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager" />
		

</beans>

    3、分库规则实现
        
 /**
     * sql 中关键字 匹配符为 =的时候,表的路由函数
     * @param availableTargetNames
     * @param shardingValue
     * @return
     */
    public String doEqualSharding(Collection<String> availableTargetNames, ShardingValue<Integer> shardingValue) {
        for (String each : availableTargetNames) {
            if (each.endsWith(shardingValue.getValue() % 2 + "")) {
                return each;
            }
        }
        throw new IllegalArgumentException();
    }

    /**
     * sql 中关键字 匹配符为 in 的时候,表的路由函数
     * @param availableTargetNames
     * @param shardingValue
     * @return
     */
    public Collection<String> doInSharding(Collection<String> availableTargetNames, ShardingValue<Integer> shardingValue) {
        Collection<String> result = new LinkedHashSet<String>(availableTargetNames.size());
        for (Integer value : shardingValue.getValues()) {
            for (String tableName : availableTargetNames) {
                if (tableName.endsWith(value % 2 + "")) {
                    result.add(tableName);
                }
            }
        }
        return result;
    }

      分表规则实现:
       
 /**
     * sql 中 = 操作时,table的映射
     * @param tableNames
     * @param shardingValue
     * @return
     */
    public String doEqualSharding(Collection<String> tableNames, ShardingValue<Integer> shardingValue) {
        for (String each : tableNames) {
            if (each.endsWith(shardingValue.getValue() % 3 + "")) {
                return each;
            }
        }
        throw new IllegalArgumentException();
    }

    /**
     * sql 中 in 操作时,table的映射
     * @param tableNames
     * @param shardingValue
     * @return
     */
    public Collection<String> doInSharding(Collection<String> tableNames, ShardingValue<Integer> shardingValue) {
        Collection<String> result = new LinkedHashSet<String>(tableNames.size());
        for (Integer value : shardingValue.getValues()) {
            for (String tableName : tableNames) {
                if (tableName.endsWith(value % 3 + "")) {
                    result.add(tableName);
                }
            }
        }
        return result;
    }

    本来想详细描述下的, 但是时间有限,这里我就把demo分享给大家,大家有疑问的地方,我们一起探讨沟通。如不正确的地方,也希望能留言指正,谢谢  demo下载地址:http://download.youkuaiyun.com/download/yufei_java/10140530   

SpringBoot第31讲:SpringBoot集成ShardingJDBC - Sharding-JDBC简介和基于MyBatis的单库分表 本文是SpringBoot第31讲,主要介绍分表分库,以及SpringBoot集成基于ShardingJDBC+MyBatis的单库分表实践。 阅读详情

相关推荐

spring4.0.2+mybatis3.2.4+sharding-jdbc1.4.2实现分库分表、主从及事物支持

spring4.0.2+mybatis3.2.4+sharding-jdbc1.4.2实现分库分表、主从及事物支持

理解Sharding jdbc原理,看这一篇就够了

相比于Spring基于AbstractRoutingDataSource实现的分库分表功能,Sharding jdbc在单库单表扩展到多库多表时,兼容性方面表现的更好一点。例如,spring实现的分库分表sql写法如下: select id, name, price, publish, intro from book${tableIndex} where id = #{id,jdbcType...

wenyuan65的博客 2万+

Springboot2+JPA|MyBatis+Sharding-JDBC示例

Springboot2+JPA|MyBatis+Sharding-JDBC示例源码,可直接运行。

SpringBoot整合Sharding-JDBC分库分表+读写分离

使用sharding-jdbc进行分库分表和读写分离

weixin_46012179的博客 1091

Sharding-JDBC教程:Spring Boot整合Sharding-JDBC实现分库分表+读写分离.docx

Sharding-JDBC教程:Spring Boot整合Sharding-JDBC实现分库分表+读写分离

springBoot和sharding-jdbc、mybatis整合demo

这是sharding-jdbc spring boot的一个demo程序。分别使用了controller的单元测试及服务的单元测试resources / sql下的sql语句在两个不同的数据库下执行。

SpringBoot + Sharding JDBC,一文搞定分库分表、读写分离

mysqld]## 设置server_id,注意要唯一## 开启binlog## binlog缓存## binlog格式(mixed、statement、row,默认格式是statement)

LU58542226的博客 5557

从零构建:基于Docker与FRR的OSPF虚拟网络实验室

本文详细介绍了如何利用Docker与FRR构建OSPF虚拟网络实验室,从环境设计到高级网络拓扑配置,再到实验验证与排错。通过容器化技术实现高效资源利用和快速部署,特别适合网络协议教学、企业网络架构验证等场景。

plum99的博客 222

SpringBoot 2.x ShardingSphere分库分表实战

一. 项目需求 在之前我做项目的时候,数据量比较大,单表千万级别的,需要分库分表,于是在网上搜索这方面的开源框架,最常见的就是mycat,sharding-sphere,最终我选择后者,用它来做分库分表比较容易上手。 二. 简介sharding-sphere 官网地址: https://shardingsphere.apache.org/ ShardingSph...

李浩东的博客 1万+

UE游戏引擎材质简单入门

什么是物体的材质,材质属性定义了物体的某些特性,从而决定了物体表面是如何与光线相作用的。UE中物理基础渲染(Physically Based Rendering OR PBR)几乎可以让我们模拟显示世界中的任何材质。那么如何在UE中制作出真实的PBR材质,基于我们提供的游戏引擎插件,如何将这些材质资源导出,并应用到 SuperMap iClient3D for Cesium/WebGL 平台上,提升模型的显示效果呢,下面小编将详细讲解一下。

m0_71055362的博客 2511

四足机器人关节电机FOC控制实战:从磁编码器校准到SVPWM调试避坑指南

本文详细解析了四足机器人关节电机FOC控制实战,涵盖磁编码器校准、电流环调试和SVPWM波形优化等关键环节。通过MIT Cheetah案例展示如何解决21倍电气误差问题,并提供相序自动校正、PI参数整定等实用代码片段,帮助工程师避开永磁同步电机(PMSM)控制中的常见陷阱。

weixin_29281915的博客 490

论多数据源(读写分离)的实现方案

好的,作为一个合格的bug生产者,我们直接进入主题,多数据源和读写分离实现方案。 首先多数据源和读写分离什么时候我们才需要呢? 多数据源:一个单体项目过于复杂,需要操作多个业务库的时候,就需要多数据源操作不同的数据 读写分离:数据库压力较大时,我们考虑读写分离,主库写,从库读,减少数据库的压力。多个库数据是一样的。 理解完使用场景后,再入主题,怎么实现呢?这里说三种实现方式 ...

weixin_40663800的博客 1075

DELL Precision T7920加装显卡遇到的坑

文章目录DELL Precision T7920加装显卡服务器原有配置介绍选购过程确认型号确认PCIE x16插槽确认电源功率和电源线安装过程电源模组线不够多单装一个3090显卡尺寸问题加装上1080Ti非常重要!官方文档 DELL Precision T7920加装显卡 实验室由于显卡计算能力不够,以及显卡显存不够,请老师花了大价钱购入了两张GeForce 3090显卡。老师赛高!记录一下这次加装显卡过程中学到的一些知识。 服务器原有配置介绍 服务器原有一张1080Ti显卡,一个16核Xeon CPU。

weixin_45520982的博客 1万+

Sharding-jdbc+spring boot 2.X+mybatis项目实战 (Sharding-jdbc分表利器 轻松搞定)

Apache ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈,它由 JDBC、Proxy 和 Sidecar(规划中)这 3 款相互独立,却又能够混合部署配合使用的产品组成。 它们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如 Java 同构、异构语言、云原生等各种多样化的应用场景。 Apache ShardingSphere 定位为关系型数据库中间件,旨在充分合理地在分布式的场景下利用关系型数据库的计算和存储能力,而并非实现一个全新的关系型数据库。 它通

wo1901446409的博客 926

一生一芯 预学习阶段 NEMU代码学习(2)

如果 nemu_state.state == NEMU_ABORT:说明程序处于 "中止" 状态,输出 "ABORT",并且使用 ANSI_FG_RED 红色格式化显示。如果 halt_ret == 0,表示程序正常终止(触发了 "GOOD TRAP"),输出 "HIT GOOD TRAP",并使用 ANSI_FG_GREEN 绿色显示。如果要执行的指令数量 n 小于预定义的常量 MAX_INST_TO_PRINT,则将 g_print_step 置为 true,表示会逐步打印指令执行的过程。

weixin_45041054的博客 828

VMware Workstation Pro必备技巧:5分钟搞定Ubuntu虚拟机磁盘瘦身(附常见错误解决)

本文详细介绍了如何为VMware Workstation Pro中的Ubuntu虚拟机进行磁盘瘦身,解决.vmdk文件只增不减的问题。通过清理系统垃圾、使用零填充空闲空间,并利用vmware-toolbox-cmd或vmware-vdiskmanager工具进行压缩,可有效回收被无效占用的磁盘空间。文章还提供了常见错误解决方案和预防性维护建议,帮助用户高效管理虚拟机存储。

sea99的博客 299

2 数据源配置_论多数据源(读写分离)的实现方案

好的,作为一个合格的bug生产者,我们直接进入主题,多数据源和读写分离实现方案。首先多数据源和读写分离什么时候我们才需要呢?多数据源:一个单体项目过于复杂,需要操作多个业务库的时候,就需要多数据源操作不同的数据读写分离:数据库压力较大时,我们考虑读写分离,主库写,从库读,减少数据库的压力。多个库数据是一样的。理解完使用场景后,再入主题,怎么实现呢?这里说三种实现方式1、扩展Spring的Abstr...

weixin_39611413的博客 204

浪潮服务器ESXI6.7部署实战:手动集成RAID驱动避坑指南

本文详细介绍了在浪潮服务器上部署ESXI6.7时手动集成RAID驱动的完整流程和避坑指南。从驱动获取、解压技巧到封装实战,逐步解决国产服务器常见的驱动缺失问题,特别针对PM8060 RAID卡提供具体解决方案,帮助IT运维人员顺利完成ESXI部署。

weixin_33725722的博客 462

Spring/SpringBoot系列之SpringBoot集成ShardingSphere实现分库分表实战【二十四】

1. 前言 去年开发一个项目的时候,因为系统的核心数据是定时从外界发送过来的,数据量比较大,后来很快单表就达到了千万级别,这就需要分库分表,最后选择了ShardingSphere,原因就是比较容易上手。 2. Sharding JDBC简介 官网地址:https://shardingsphere.apache.org/ 如上图所示,当前版本是4.x,并且官网支持中文阅读。点击文档下拉4.x版本: 简介如下: ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sha

fei1234456的博客 3540

【毕设实战】基于YOLOv8的HRSC2016船舶智能检测系统开发全指南(含可视化UI界面,打造海事领域高分毕设)

亲爱的同学,通过这篇教程,你已经掌握了“基于YOLOv8的HRSC2016微小船只检测系统”从数据集处理、模型训练到Tkinter界面开发的全流程。这个课题既贴合“海事智能化”的产业战略,又涵盖了“目标检测、深度学习、界面开发”等多个毕设评分点,非常适合作为计算机或海事工程专业的毕业设计。在实践中,你可能会遇到“海面背景复杂导致船只漏检”“微小船只识别精度不足”“UI与模型推理同步卡顿”等挑战——别担心,这些都是技术成长的必经之路。

know_F0727的博客 130

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

oracle单表支持多大数据量_「Spring Boot 实战」数据库单表千万级别怎么办?

作 者:小东啊来 源:李浩东的博客>>免费送书活动进行中<<一. 项目需求在之前我做项目的时候,数据量比较大,单表千万级别的,需要分库分表,于是在网上搜索这方面的开源框架,最常见的就是mycat,sharding-sphere,最终我选择后者,用它来做分库分表比较容易上手。二. 简介sharding-sphere官网地址: https://shardingsphere.apache.org/Sha...

weixin_39759060的博客 2525

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

上一篇: linux常用命令command not found的解决方案(自己整理)
下一篇: docker的常用命令汇总
yufei_java
博客等级 码龄10年 18粉丝 60原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值