jdk8的时间表示, 你真的在乎吗?

47 篇文章 0 订阅
23 篇文章 0 订阅
文章讨论了Java8中新的时间API相对于旧API的优势,如线程安全、可读性和灵活性,并解释了如何在MySQL中与timestamp和datetime字段对应。同时,提到了在SpringBoot中配置时区的一致性,以及MyBatis中使用TypeHandler处理日期时间类型的问题。
摘要由CSDN通过智能技术生成

一旦圆满了,马上就要亏厌,树上的果子,一旦熟透了,马上就要坠落

java8中, 时间使用上可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar,
DateTimeFormatter 代替 SimpleDateFormat, 为什么要这么替代呢, 原来的时间api有什么问题呢?

jdk8前的时间api有什么问题

在Java 8之前,Java中的时间API存在一些问题,主要有以下几点:

  1. 线程不安全:Date和Calendar都是可变对象,并且不是线程安全的。如果多个线程同时使用同一个Date或Calendar实例进行操作,可能会导致数据出错。

  2. 可读性差:在Date和Calendar中,大量的方法名都不够清晰,使用起来不够直观,容易出现误操作。

  3. 不够灵活:Date和Calendar中的很多操作都比较麻烦,比如要获取某一天的前一天,需要进行多次操作才能实现。

为了解决这些问题,Java 8引入了新的时间API,即java.time包,其中包含了一系列新的日期和时间类。这些类的主要优点包括:

  1. 线程安全:新的日期和时间类都是不可变对象,并且线程安全,可以在多线程环境下安全使用。

  2. 可读性高:新的日期和时间类使用了更清晰的方法名,并且提供了更直观的操作方式,易于理解和使用。

  3. 更灵活:新的日期和时间类提供了更多的操作方法,比如获取某一天的前一天只需要一步操作即可。

在Java 8中,Instant类用于表示时间戳,相当于旧的Date类;LocalDateTime类用于表示日期和时间,相当于旧的Calendar类;DateTimeFormatter类用于格式化日期和时间,相当于旧的SimpleDateFormat类。

综上所述,Java 8中的新日期和时间API更加方便、灵活和易于使用,是对旧的日期和时间API的一次重要升级和改进。

mysql的时间相关字段对应

java8中的时间类如何跟mysql的时间相关字段对应起来呢?

Java 8中的时间类与MySQL的时间相关字段可以使用以下方式进行对应:

  1. Instant类对应MySQL的TIMESTAMP字段。在Java中,可以使用Instant.ofEpochSecond()方法将秒数转换为Instant对象,然后将其转换为Timestamp对象,再将Timestamp对象插入到MySQL的TIMESTAMP字段中。

  2. LocalDateTime类对应MySQL的DATETIME字段。在Java中,可以使用LocalDateTime.parse()方法将字符串解析为LocalDateTime对象,然后将其转换为Timestamp对象,再将Timestamp对象插入到MySQL的DATETIME字段中。

  3. LocalDate类对应MySQL的DATE字段。在Java中,可以使用LocalDate.parse()方法将字符串解析为LocalDate对象,然后将其转换为java.sql.Date对象,再将java.sql.Date对象插入到MySQL的DATE字段中。

需要注意的是,Java 8中的日期和时间类与MySQL的时间相关字段之间的转换需要考虑时区问题,确保时区的一致性。另外,在将Java 8中的日期和时间对象转换为MySQL的时间相关字段时,也需要进行格式化和解析等操作,确保数据的正确性和完整性。

mysql中timestamp和datetime, timestamp是带时区, 而datetime是不带时区,除了这点区别, 还有其他区别吗?

除了时区的差异,MySQL中的timestamp和datetime类型还有以下几个区别:

  1. 存储范围:MySQL中的timestamp类型可以存储的范围比datetime类型小。timestamp类型可以存储的时间范围为1970-01-01 00:00:01到2038-01-19 03:14:07,而datetime类型可以存储的时间范围为1000-01-01 00:00:00到9999-12-31 23:59:59。

  2. 存储空间:MySQL中的timestamp类型占用4个字节的存储空间,而datetime类型占用8个字节的存储空间。

  3. 存储精度:MySQL中的timestamp类型存储精度为秒级,而datetime类型存储精度为微秒级。

  4. 默认值:MySQL中的timestamp类型默认值为CURRENT_TIMESTAMP,表示当前时间戳,而datetime类型默认值为NULL。

需要注意的是,由于timestamp类型存储的是UTC时间戳,因此在将timestamp类型转换为本地时间时,需要考虑时区的差异。如果在Java中使用Instant类型表示MySQL中的timestamp类型,可以使用JDBC驱动提供的方法直接将timestamp类型转换为Instant类型,从而避免时区转换的问题。而对于datetime类型,由于不包含时区信息,需要在程序中手动进行时区转换。

springboot中, 我要如何考虑时区问题

Java 8中的日期和时间类与MySQL的时间相关字段之间的转换需要考虑时区问题,确保时区的一致性, 如果是在springboot中, 我要如何考虑时区问题?

在Spring Boot中,可以通过配置文件中的属性来设置时区,从而确保Java 8中的日期和时间类与MySQL的时间相关字段之间的转换时区一致。

具体来说,可以在application.properties或application.yml中添加以下属性:

  • 对于Spring Boot 2.x及以上版本:
spring:
  jackson:
    time-zone: Asia/Shanghai

这里以设置时区为"Asia/Shanghai"为例。通过设置这个属性,可以确保Spring Boot应用程序的默认时区为"Asia/Shanghai",从而在处理Java 8中的日期和时间类时,能够正确地进行时区转换,与MySQL的时间相关字段之间保持一致。

需要注意的是,如果在Spring Boot中使用了JPA等ORM框架来操作数据库,还需要确保ORM框架的配置中也设置了正确的时区。一般来说,ORM框架会自动采用Spring Boot的默认时区,因此不需要额外配置。但是,如果ORM框架的默认时区与Spring Boot的默认时区不一致,需要手动进行配置,以确保时区的一致性。

mybatis和hibernate这两个orm框架来说吧, 默认时区跟springboot中一致吗

MyBatis和Hibernate这两个ORM框架默认时区与Spring Boot中的默认时区是一致的,都是使用JVM的默认时区。

具体来说,MyBatis使用JDBC连接数据库,而JDBC的默认时区就是JVM的默认时区,因此在使用MyBatis操作数据库时,其默认时区就是JVM的默认时区。Hibernate也类似,它会自动根据JVM的默认时区来进行时区转换。

需要注意的是,如果需要在MyBatis或Hibernate中手动设置时区,可以通过设置JDBC连接的时区来实现。对于MyBatis来说,可以在mybatis-config.xml In spring中添加如下配置:

<configuration>
  <settings>
    <setting name="jdbcTypeForNull" value="NULL" />
    <setting name="defaultTimeZone" value="Asia/Shanghai" />
  </settings>
</configuration>

对于Hibernate来说,可以在application.properties或application.yml中添加如下配置:

spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai

这里以设置时区为"Asia/Shanghai"为例。通过这些配置,可以确保在使用MyBatis和Hibernate操作数据库时,其默认时区与Spring Boot中的默认时区一致,避免时区转换带来的问题。

现在我使用的是mybatis框架, 有一个类A, 有四个字段String id, Instant birthday, LocalDateTime createTime, LocalDate updateTime, 我要如何配置我的SQL呢?

如何配置我的SQL | 梦回 spring 配置时代

如果需要对birthday、createTime和updateTime进行范围查询,可以使用如下的SQL语句:

SELECT id, birthday, create_time, update_time FROM table_a WHERE birthday >= #{startDate} AND birthday <= #{endDate} AND create_time >= #{startTime} AND create_time <= #{endTime} AND update_time >= #{updateDate} AND update_time <= #{updateDateEnd} ORDER BY id

这里的"startDate"、“endDate”、“startTime”、“endTime”、"updateDate"和"updateDateEnd"是查询条件,需要在Java代码中动态设置它们的值。

如果需要插入A类的一条数据,可以使用如下的SQL语句:

INSERT INTO table_a (id, birthday, create_time, update_time) VALUES (#{id}, #{birthday}, #{createTime}, #{updateTime})

这里的"#{id}“、”#{birthday}“、”#{createTime}“和”#{updateTime}"是A类的四个字段,需要在Java代码中设置它们的值。

需要注意的是,在处理Instant、LocalDateTime和LocalDate等Java 8中的日期和时间类型时,需要配置对应的TypeHandler来实现与数据库的转换。可以在mybatis-config.xml中添加如下的TypeHandler配置:

<typeHandlers>
  <typeHandler handler="org.apache.ibatis.type.InstantTypeHandler" javaType="java.time.Instant"/>
  <typeHandler handler="org.apache.ibatis.type.LocalDateTimeTypeHandler" javaType="java.time.LocalDateTime"/>
  <typeHandler handler="org.apache.ibatis.type.LocalDateTypeHandler" javaType="java.time.LocalDate"/>
</typeHandlers>

这里的"org.apache.ibatis.type.InstantTypeHandler"、"org.apache.ibatis.type.LocalDateTimeTypeHandler"和"org.apache.ibatis.type.LocalDateTypeHandler"是MyBatis提供的处理Instant、LocalDateTime和LocalDate等Java 8中的日期和时间类型的TypeHandler,可以直接使用。

如果有些Mapper使用的TypeHandler不同,可以分别为它们设置不同的TypeHandler

如果有些Mapper使用的TypeHandler不同,可以分别为它们设置不同的TypeHandler。具体来说,有两种方式可以实现:

在Mapper接口中使用@TypeHandler注解
  1. 在Mapper接口中使用@TypeHandler注解

可以在Mapper接口的方法上使用@TypeHandler注解来指定要使用的TypeHandler。例如:

@Select("SELECT * FROM table_a WHERE birthday = #{birthday, typeHandler=org.apache.ibatis.type.InstantTypeHandler}")
A findByBirthday(@Param("birthday") Instant birthday);

这里的"org.apache.ibatis.type.InstantTypeHandler"是要使用的TypeHandler类的全限定名。在执行查询时,MyBatis会自动将Instant类型的birthday参数转换为对应的数据库类型,并使用指定的TypeHandler来完成转换。

在Mapper XML文件中为每个参数和结果集设置对应的TypeHandler
  1. 在Mapper XML文件中为每个参数和结果集设置对应的TypeHandler

可以在Mapper XML文件中为每个参数和结果集设置对应的TypeHandler。例如:

<select id="findByBirthday" resultType="A">
    <parameterMap type="java.util.Map" id="param">
        <parameter property="birthday" javaType="java.time.Instant" typeHandler="org.apache.ibatis.type.InstantTypeHandler"/>
    </parameterMap>
    SELECT * FROM table_a WHERE birthday = #{birthday, typeHandler=org.apache.ibatis.type.InstantTypeHandler}
</select>

这里的"“标签用于指定参数类型和TypeHandler,”"标签用于指定参数名、Java类型和TypeHandler。在执行查询时,MyBatis会自动将Instant类型的birthday参数转换为对应的数据库类型,并使用指定的TypeHandler来完成转换。

类似地,如果需要设置结果集的TypeHandler,可以在标签上使用resultMap属性,指定结果集的TypeHandler。例如:

<select id="findAll" resultMap="result" >
    SELECT * FROM table_a
</select>

<resultMap id="result" type="A">
    <result property="birthday" column="birthday" javaType="java.time.Instant" typeHandler="org.apache.ibatis.type.InstantTypeHandler" />
    <result property="createTime" column="create_time" javaType="java.time.LocalDateTime" typeHandler="org.apache.ibatis.type.LocalDateTimeTypeHandler" />
    <result property="updateTime" column="update_time" javaType="java.time.LocalDate" typeHandler="org.apache.ibatis.type.LocalDateTypeHandler" />
</resultMap>

这里的"“标签用于指定结果集的TypeHandler和映射关系,”"标签用于指定每个属性对应的列名、Java类型和TypeHandler。在查询结果转换时,MyBatis会自动将数据库类型转换为Java类型,并使用指定的TypeHandler来完成转换。

示例

mysql中timestamp和datetime, timestamp是带时区, 而datetime是不带时区, 如果使用的是datetime, java中接受的instant类型, 这样会有什么问题

在MySQL中,datetime类型表示一个不带时区的日期和时间值,而timestamp类型则包含时区信息。如果在MySQL中使用datetime类型,而在Java中使用Instant类型,可能会遇到时区转换问题,因为Instant是基于UTC时间的,表示一个时间戳。

使用Java中的Instant类型来表示MySQL中的datetime类型可能会导致以下问题:

  1. 数据转换问题:由于datetime类型不包含时区信息,所以在将MySQL中的datetime值转换为Java的Instant类型时,可能会导致错误的时区转换,从而产生不准确的时间值。

假设你有一个MySQL数据库,其中有一个包含datetime类型的列,记录了用户的注册时间。你的应用程序在美国东部时区运行,而数据库服务器在UTC时区。

+----+---------------------+
| id | registration_time   |
+----+---------------------+
|  1 | 2023-04-06 10:00:00 |
+----+---------------------+

在这种情况下,如果你直接将MySQL中的datetime值转换为Java的Instant类型,可能会导致错误的时区转换。例如:

import java.sql.*;
import java.time.Instant;

public class Main {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC";
        String user = "username";
        String password = "password";

        try (Connection conn = DriverManager.getConnection(url, user, password)) {
            String query = "SELECT id, registration_time FROM users WHERE id = 1";
            PreparedStatement stmt = conn.prepareStatement(query);
            ResultSet rs = stmt.executeQuery();

            if (rs.next()) {
                Instant registrationTime = rs.getTimestamp("registration_time").toInstant();
                System.out.println("Registration time (Instant): " + registrationTime);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

在这个示例中,我们将MySQL中的datetime值转换为了Java的Instant类型。但由于datetime类型不包含时区信息,所以这将导致错误的时区转换。实际上,返回的时间值将被错误地解释为UTC时间,即2023-04-06T10:00:00Z,而不是正确的美国东部时区时间2023-04-06T06:00:00-04:00

  1. 时区不一致问题:在不同地区运行程序时,由于时区的差异,可能会导致程序处理MySQL中的datetime类型时出现问题。

假设你的应用程序需要支持多个时区的用户,并且你的数据库服务器仍然在UTC时区。在这种情况下,由于MySQL中的datetime类型不包含时区信息,所以在不同地区运行程序时,可能会导致程序处理MySQL中的datetime类型时出现问题。

例如,一个用户在美国东部时区创建了一个事件,另一个用户在欧洲柏林时区查看该事件。由于数据库中存储的时间值不包含时区信息,所以在将MySQL中的datetime值转换为Java的Instant类型时,你需要首先将其转换为正确的时区,然后再进行进一步的处理。

在这种情况下,你需要确保在处理MySQL中的datetime类型时,能够根据每个用户所在的时区进行正确的时区转换。这将使应用程序的逻辑更加复杂,因为你需要在应用程序中手动处理时区转换。

为了避免这些问题,建议将MySQL中的datetime类型转换为Java中的LocalDateTime类型,而不是Instant类型。LocalDateTime是不带时区的日期和时间,类似于MySQL中的datetime。

示例代码:

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.Instant;
import java.sql.Timestamp;

public class Main {
    public static void main(String[] args) {
        // 假设从MySQL数据库中获取的datetime值为2023-04-06 12:00:00
        Timestamp mysqlDatetime = Timestamp.valueOf("2023-04-06 12:00:00");

        // 将Timestamp转换为LocalDateTime
        LocalDateTime localDateTime = mysqlDatetime.toLocalDateTime();

        // 如果需要将LocalDateTime转换为Instant,需要指定时区,例如系统默认时区
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
        Instant instant = zonedDateTime.toInstant();
    }
}

在此示例中,我们首先将MySQL中的datetime(Timestamp)转换为Java中的LocalDateTime。如果确实需要将其转换为Instant类型,我们可以通过指定时区(如系统默认时区)将LocalDateTime转换为ZonedDateTime,然后将ZonedDateTime转换为Instant。这样,我们可以确保在转换过程中正确处理时区问题。

这里当然是使用我们的 typehandler 进行转换啦

public class InstantTypeHandler extends BaseTypeHandler<Instant> {

    private final DateTimeTypeHandler dateTimeTypeHandler = new DateTimeTypeHandler();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Instant parameter, JdbcType jdbcType) throws SQLException {
        ps.setObject(i, Timestamp.from(parameter));
    }

    @Override
    public Instant getNullableResult(ResultSet rs, String columnName) throws SQLException {
        LocalDateTime localDateTime = dateTimeTypeHandler.getNullableResult(rs, columnName);
        return localDateTime != null ? localDateTime.toInstant(ZoneOffset.UTC) : null;
    }

    @Override
    public Instant getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        LocalDateTime localDateTime = dateTimeTypeHandler.getNullableResult(rs, columnIndex);
        return localDateTime != null ? localDateTime.toInstant(ZoneOffset.UTC) : null;
    }

    @Override
    public Instant getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        LocalDateTime localDateTime = dateTimeTypeHandler.getNullableResult(cs, columnIndex);
        return localDateTime != null ? localDateTime.toInstant(ZoneOffset.UTC) : null;
    }
}
这里其实还有一个神奇的时区问题

如果没有设置serverTimezone参数,MySQL服务器会使用系统时区来解析datetime类型的值。因此,如果在MySQL中使用NOW()函数获取当前时间,返回的就是系统时区的当地时间。例如,在中国使用的MySQL服务器上执行NOW()函数,返回的就是中国时区的当地时间。

需要注意的是,如果MySQL服务器和应用程序运行在不同的时区,那么从MySQL中查询到的datetime类型的值可能与应用程序期望的本地时间不一致。在这种情况下,需要手动进行时区转换,以保证查询结果的正确性。

如果在连接MySQL数据库时没有指定serverTimezone参数,就会使用MySQL服务器的系统时区来解析datetime类型的值。在这种情况下,如果MySQL服务器和应用程序运行在不同的时区,就会导致datetime类型的值被错误地转换为本地时间

建议在链接数据库URL中配置

spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC

即使在连接MySQL数据库时指定了serverTimezone参数,也不会对MySQL服务器上存储的datetime类型的值产生影响。因此,在查询MySQL数据库时,仍然需要手动进行时区转换,以保证查询结果的正确性。

假设应用程序在运行UTC+8,而数据库服务器在UTC-5时区, 如果我使用 now()插入datetime类型的字段, 这个时候存储的是UTC-5时区时区的datetime, 这个时候读到应用程序中的LocalDateTime, 这个时候LocalDateTime比我要的时候是少了13个小时的是吗? 如果不使用now(), 我在程序中创建LocalDateTime,然后插入到数据库就不会有这个问题?

就是这样的。如果应用程序运行在UTC+8时区,而数据库服务器在UTC-5时区,当你在MySQL中使用now()函数插入datetime类型的字段时,存储的是UTC-5时区的时间。当你从数据库中读取这个datetime类型字段到应用程序中的LocalDateTime时,它会比你期望的时间少了13个小时。

为了避免这个问题,你可以在应用程序中创建一个LocalDateTime对象,将其转换为UTC-5时区的时间,然后插入到数据库。这样,在插入和读取时,都会使用相同的时区,从而避免时区转换的问题。以下是一个简单的示例:

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        // 在应用程序中创建一个LocalDateTime对象
        LocalDateTime localDateTime = LocalDateTime.now();

        // 获取数据库服务器所在的时区(以UTC-5为例)
        ZoneId databaseTimeZone = ZoneId.of("UTC-5");

        // 将应用程序中的LocalDateTime转换为数据库服务器所在时区的时间
        ZonedDateTime databaseTime = localDateTime.atZone(ZoneId.systemDefault()).withZoneSameInstant(databaseTimeZone);

        // 现在,你可以将databaseTime插入到数据库的datetime类型字段中
        // ...
    }
}

通过这种方式,你可以确保插入和读取datetime类型字段时使用相同的时区,从而避免时区转换的问题。当然,这仅适用于单一时区的情况。如果你需要支持多个时区的用户,你可能需要在应用程序中进行更复杂的时区处理。

springboot中,当然starter已经帮我们做好了这些类型转换的注册

当然这里权当看下, 你可以怎么配置类型转换器

你可以在@Configuration类中配置MyBatis的TypeHandler。具体来说,可以在@Configuration类中创建一个SqlSessionFactoryBean,并设置其typeHandlers属性为要使用的TypeHandler列表。示例如下:

@Configuration
public class MyBatisConfig {

    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        TypeHandler<?>[] typeHandlers = new TypeHandler<?>[] {
            new InstantTypeHandler(),
            new LocalDateTimeTypeHandler(),
            new LocalDateTypeHandler()
        };
        sqlSessionFactoryBean.setTypeHandlers(typeHandlers);
        return sqlSessionFactoryBean;
    }
}

这里的InstantTypeHandler、LocalDateTimeTypeHandler和LocalDateTypeHandler都是MyBatis提供的处理Java 8中的日期和时间类型的TypeHandler。如果你有自定义的TypeHandler,也可以添加到typeHandlers列表中。

需要注意的是,如果你在@Configuration类中配置了SqlSessionFactoryBean的typeHandlers属性,那么所有使用该SqlSessionFactoryBean的Mapper都会共享这些TypeHandler,因此应该确保这些TypeHandler适用于所有Mapper。如果有些Mapper使用的TypeHandler不同,可以在Mapper接口中使用@TypeHandler注解来指定要使用的TypeHandler,或者在Mapper XML文件中为每个参数和结果集设置对应的TypeHandler。

如果在Spring Boot项目中使用了mybatis-spring-boot-starter依赖,那么MyBatis的TypeHandler会自动注册。具体来说,MyBatis会扫描项目中所有的TypeHandler实现类,并自动注册到MyBatis的TypeHandlerRegistry中。因此,你不需要手动在mybatis-config.xml中配置TypeHandler,也不需要在@Configuration类中配置SqlSessionFactoryBean的typeHandlers属性。

如果需要自定义TypeHandler,只需要实现TypeHandler接口,并在实现类上添加@MappedTypes和@MappedJdbcTypes注解,MyBatis就会自动将其注册为TypeHandler。例如:

@MappedTypes({Instant.class})
@MappedJdbcTypes({JdbcType.TIMESTAMP, JdbcType.DATE})
public class InstantTypeHandler implements TypeHandler<Instant> {
    @Override
    public void setParameter(PreparedStatement ps, int i, Instant parameter, JdbcType jdbcType) throws SQLException {
        if (parameter != null) {
            ps.setTimestamp(i, Timestamp.from(parameter));
        } else {
            ps.setTimestamp(i, null);
        }
    }

    @Override
    public Instant getResult(ResultSet rs, String columnName) throws SQLException {
        return rs.getTimestamp(columnName).toInstant();
    }

    @Override
    public Instant getResult(ResultSet rs, int columnIndex) throws SQLException {
        return rs.getTimestamp(columnIndex).toInstant();
    }

    @Override
    public Instant getResult(CallableStatement cs, int columnIndex) throws SQLException {
        return cs.getTimestamp(columnIndex).toInstant();
    }
}

这里的@MappedTypes和@MappedJdbcTypes注解分别用于指定Java类型和数据库类型。在使用Instant类型时,MyBatis会自动使用InstantTypeHandler进行转换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值