MyBatis初识

Mybatis

简介

Mybatis是一个Apache下的开源项目
后来转到了谷歌旗下
2013年迁移到github上
它是一个超轻量级的半自动ORM框架

在它框架架构中
    核心的就是输入映射 将参数映射到sql语句中(JDBC中的参数替换)
    map list Integer POJO(普通的java对象)
    和输出映射(JDBC ResultSet到对象的映射)

    并且能帮我们管理事务

    开发人员只需要关注具体的sql语句即可(sql语句需要自己写 半自动)

MyBatis与Hibernate

1.Mybatis需要手写sql 适用于需求变化频繁的场景
2.切换数据库成本较高 通常要重写一边sql语句
3.不是一个完全的ORM映射 无法实现面向对象操作数据库
4.体积更小 学习难度低
5.不能自动生成表结构

1.Hibernate与数据库的关联性几乎没有 随时可以切换方言
2.可以自动生成表结构 从实体类 映射 关联关系
3.更加完整的ORM映射 可以不编写sql语句
4.体积大 学习过程更长

MyBatis环境搭建

1.下载jar包
2.添加jar包到工程中
    Mybatis核心包 依赖lib中的依赖包
3.编写核心配置文件
    名字没有要求
    配置数据源的db.properties
    <!-- 加载properties配置文件 必须放在src下 不需指定classpath -->
    <properties resource="db.properties"></properties>
4.编写Mapper文件
    创建对应的数据库和表
    创建与表对应的实体类(bean)
    创建与实体类关联的mapper文件
    添加到主配置文件mappers中
5.获取session进行操作
6.关闭资源

测试增删该查方法

需求:
    1.通过id获取User对象
    2.通过姓名搜索User数据
        确定需求 到mapper中添加对应的sql
    3.添加新数据
    4.更新user数据
    5.删除数据
通过id获取User对象
User.java
package com.lanou.bean;

public class User {
    private int id;
    private String name;
    private String password;
    private String sex;
    public User() {
        super();
        // TODO Auto-generated constructor stub
    }


    public String getSex() {
        return sex;
    }


    public void setSex(String sex) {
        this.sex = sex;
    }


    public User(int id, String name, String password, String sex) {
        super();
        this.id = id;
        this.name = name;
        this.password = password;
        this.sex = sex;
    }


    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }


    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", password=" + password + ", sex=" + sex + "]";
    }

}
SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 加载properties配置文件 必须放在src下 不需指定classpath -->
  <properties resource="db.properties"></properties>
  <!-- 当前开发环境 -->
  <environments default="development">
    <environment id="development">
    <!-- 事务管理 -->
      <transactionManager type="JDBC"/>
      <!-- 数据源 -->
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <!-- 映射文件 -->
    <mappers>
    <!-- resource指定相对路径 -->
        <mapper resource="com/lanou/bean/User.xml"/>
    </mappers>
</configuration>
User.xml
与sql进行映射 这里写的都是实现业务的sql语句
有可能多个mapper中有相同id 所有namespace用来区分哪个mapper 必填参数
根据id获取User id用来标示这个sql语句
parameterType 指定输入参数类型
resultType 指定输出结果类型
原生sql语句 #{}代表占位符 等同于?
括号中的内容可以随便写 但是不能不写

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="test">
  <select id="findUserById" parameterType="Integer" resultType="com.lanou.bean.User">
     select * from User where id = #{**}
  </select>
</mapper>
MyTest.java
import com.lanou.bean.User;

public class MyTest {
    @Test
    public void fun1() throws IOException {
        // 构建器
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 读取配置文件
        InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
        1.获取会话工厂
        SqlSessionFactory factory = builder.build(input);
        2.获取会话
        SqlSession session = factory.openSession();
        3.crud 
        selectOne 查询单个
        指定sql的id和需要的参数
        User user = session.selectOne("test.findUserById", 3);
        System.out.println(user);
    }
}
通过姓名搜索User数据
User.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="test">
  <select id="findUserById" parameterType="Integer" resultType="com.lanou.bean.User">
     select * from User where id = #{**}
  </select>
  <select id="findUserByName" parameterType="String" resultType="com.lanou.bean.User">
    select * from User where name like "%${value}%"
  </select>
</mapper>
MyTest.java
如果当前参数需要拼接到字符串中就使用${value}
如果只有一个参数 value是固定的
因为#{xx}会在字符串的左右加上引号}
select * from User where name like "%${value}%"
select * from User where name like "%"#{value}"%"
resultTRype是结果的泛型 如果有多个结果 就自动封装为list

public void fun2() throws IOException {
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactory factory = builder.build(input);
    SqlSession session = factory.openSession(); 
    // 模糊查找
    List<User> list = session.selectList("test.findUserByName", "曹");
    System.out.println(list);
}
添加新数据
添加新的User
isert中不需要声明返回类型 因为固定的integer
仅支持一个参数 参数比较复杂 就直接传对象 或者map
获取属性 或者 map 通过#{属性名} 或 #{key名}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="test">
  <select id="findUserById" parameterType="Integer" resultType="com.lanou.bean.User">
     select * from User where id = #{**}
  </select>
  <select id="findUserByName" parameterType="String" resultType="com.lanou.bean.User">
    select * from User where name like "%${value}%"
  </select>
  <insert id="insertUser" parameterType="com.lanou.bean.User">
    insert into User values (null,#{name},#{password},#{sex})
  </insert>
</mapper>


public void fun3() throws IOException {
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactory factory = builder.build(inputStream);
    SqlSession session = factory.openSession();
    User user = new User();
    user.setName("曹丕");
    user.setPassword("12345");
    user.setSex("男");
    int i = session.insert("test.insertUser", user);
    System.out.println(i);
}
更新user数据
除了查询操作 都需要提交事务 因为默认不会提交

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <properties resource="db.properties"></properties>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
    <mappers>
        <mapper resource="com/lanou/bean/User.xml"/>
    </mappers>
</configuration>

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="test">
  <select id="findUserById" parameterType="Integer" resultType="com.lanou.bean.User">
     select * from User where id = #{**}
  </select>
  <select id="findUserByName" parameterType="String" resultType="com.lanou.bean.User">
    select * from User where name like "%${value}%"
  </select>
  <insert id="insertUser" parameterType="com.lanou.bean.User">
    insert into User values (null,#{name},#{password},#{sex})
  </insert>
  <update id="updateUser" parameterType="com.lanou.bean.User">
    update User set name=#{name},password=#{password},sex=#{sex} where id=#{id}
  </update>
</mapper>

public void testFun4() throws IOException{
    // 构建器
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    // 读取配置文件
    InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
    // 1.获取会话工厂
    SqlSessionFactory factory = builder.build(input);
    // 2.获取会话
    SqlSession session = factory.openSession();
    // 3.crud
    // 添加新用户
    User user = new User();
    user.setName("曹植");
    user.setPassword("123");
    user.setSex("男");
    user.setId(3);
    // 调用sql 插入的返回值为影响的行数
    int insert = session.insert("test.updateUser", user);
    // 除了查询操作 都需要提交事务 因为默认不会自动提交
    session.commit();
    System.out.println(insert);
}
删除数据
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="test">
  <select id="findUserById" parameterType="Integer" resultType="com.lanou.bean.User">
     select * from User where id = #{**}
  </select>
  <select id="findUserByName" parameterType="String" resultType="com.lanou.bean.User">
    select * from User where name like "%${value}%"
  </select>
  <insert id="insertUser" parameterType="com.lanou.bean.User">
    insert into User values (null,#{name},#{password},#{sex})
  </insert>
  <update id="updateUser" parameterType="com.lanou.bean.User">
    update User set name=#{name},password=#{password},sex=#{sex} where id=#{id}
  </update>
  <delete id="deleteUserById" parameterType="Integer">
    delete from user where id = #{param}
  </delete>
</mapper>

public void fun5() throws IOException {
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactory factory = builder.build(inputStream);
    SqlSession session = factory.openSession();
    int i = session.delete("test.deleteUserById", 3);
    System.out.println(i);
    session.commit();
}
插入数据 然后获取id
useGeneratedKeys="true" keyProperty="id"
最后通过输入的参数对象 来获取id
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="test">
  <select id="findUserById" parameterType="Integer" resultType="com.lanou.bean.User">
     select * from User where id = #{**}
  </select>
  <select id="findUserByName" parameterType="String" resultType="com.lanou.bean.User">
    select * from User where name like "%${value}%"
  </select>
  <insert id="insertUser" parameterType="com.lanou.bean.User">
    insert into User values (null,#{name},#{password},#{sex})
  </insert>
  <update id="updateUser" parameterType="com.lanou.bean.User">
    update User set name=#{name},password=#{password},sex=#{sex} where id=#{id}
  </update>
  <delete id="deleteUserById" parameterType="Integer">
    delete from user where id = #{param}
  </delete>
  <insert id="insertNewUser" parameterType="com.lanou.bean.User"
     useGeneratedKeys="true" keyProperty="id" >
    insert into User values (null,#{name},#{password},#{sex})
  </insert>
</mapper>

public void fun6() throws IOException {
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactory factory = builder.build(inputStream);
    SqlSession session = factory.openSession();
    User user = new User();
    user.setName("孙尚香");
    user.setSex("女");
    user.setPassword("1235");
    session.insert("test.insertNewUser", user);
    int id = user.getId();
    System.out.println(id);
    session.commit();
}
总结
Mybatis核心功能就是封装了输入参数映射 和 结果映射
我们主要编写mapper文件

在mapper文件中 根据业务需求  添加对应的 select
update insert delete 标签
select 标签常用属性
id 标示sql
parameterType 参数类型 可以说是基础数据类型(list map)或者POJO
resultType 查询结果目标类型 可以是基础数据类型(list map)或者POJO
标签内部就是sql语句
如果有参数需要替换
    #{}直接获取对应的参数或是参数中的属性
    ${}获取参数并且进行字符串拼接

update insert delete
    parameter 参数类型 可以是基础数据类型(list map)或者pojO
    resultType不可用 因为只能是integer
insert 获取添加成功的数据的自增主键

无动态代理测试

SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <properties resource="db.properties"></properties>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
    <mappers>
        <mapper resource="com/lanou/bean/User.xml"/>
    </mappers>
</configuration>
User.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="test">
  <select id="findUserById" parameterType="Integer" resultType="com.lanou.bean.User">
     select * from User where id = #{**}
  </select>
</mapper>
UserDao.java
package com.lanou.dao;

import com.lanou.bean.User;

public interface UserDao {
    public User findUserById(int id);
}
UserDaoImpl.java
package com.lanou.daoImpl;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Before;

import com.lanou.bean.User;
import com.lanou.dao.UserDao;

public class UserDaoImpl implements UserDao{
    private SqlSessionFactory factory;
    public UserDaoImpl() {
        super();
        // TODO Auto-generated constructor stub
    }
    public UserDaoImpl(SqlSessionFactory factory) {
        super();
        this.factory = factory;
    }
    @Override
    public User findUserById(int id) {
        SqlSession session = factory.openSession();
        User user = session.selectOne("test.findUserById", id);
        return user;
    }
}
MybatisTest.java
public class MybatisTest {
    private SqlSessionFactory  factory;
    @Before
    public void before() throws IOException {
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        factory = builder.build(inputStream);
    }
    @Test
    public void test() {
        UserDaoImpl daoImpl = new UserDaoImpl(factory);
        User user = daoImpl.findUserById(10);
        System.out.println(user);
    }

}

动态代理测试一

SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <properties resource="db.properties"></properties>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
    <mappers>
        <mapper resource="com/lanou/bean/User.xml"/>
        <mapper resource="com/lanou/dao/UserDao.xml"/> 
    </mappers>
</configuration>
UserDao.java
package com.lanou.dao;

import com.lanou.bean.User;

public interface UserDao {
    public User findUserById(int id);
}
UserDao.xml
1.动态代理开发时 命名空间必须制定对应的接口
2.要求 id必须要和方法名保持一致 大小写铭感 必须一模一样
3.返回值类也必须一样
4.参数和接口方法中一致
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lanou.dao.UserDao">
    <select id="findUserById" parameterType="Integer" resultType="com.lanou.bean.User">
        select * from User where id = #{param}
    </select>
</mapper>
MybatisProxyTest.java
public class MybatisProxyTest {
    @Test
    public void test1() throws IOException {
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        InputStream stream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory factory = builder.build(stream);
        SqlSession session = factory.openSession();
        // 获取代理对象
        UserDao dao = session.getMapper(UserDao.class);
        User user = dao.findUserById(10);
        System.out.println(user);
    }
}

动态代理测试二

使用动态代理 完成接口开发
1.dog实体类
2.dogDao接口
3.dogDao映射文件
4.根据接口中定义的方法 完成映射文件的sql编写
5.自建数据库
获取所有dog数据
SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <properties resource="db.properties"></properties>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
    <mappers>
        <mapper resource="com/lanou/bean/User.xml"/>
        <mapper resource="com/lanou/dao/UserDao.xml"/> 
        <mapper resource="com/lanou/dao/DogDao.xml"/> 
    </mappers>
</configuration>
DogDao.java
package com.lanou.dao;

import java.util.List;

import com.lanou.bean.Dog;

public interface DogDao {
    public List<Dog> getAllDog();
}
DogDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.lanou.dao.DogDao">
    <select id="getAllDog" resultType="com.lanou.bean.Dog">
        select * from Dog
    </select>
 </mapper>
MybatisProxyTest.java
public void test2() throws IOException {
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactory factory = builder.build(inputStream);
    SqlSession session = factory.openSession();
    DogDao dao = session.getMapper(DogDao.class);
    List<Dog> list = dao.getAllDog();
    System.out.println(list);
}

理解纯接口开发原理

SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <properties resource="db.properties"></properties>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
    <mappers>
        <mapper resource="com/lanou/dao/UserDao.xml"/> 
    </mappers>
</configuration>
UserDao.java
package com.lanou.dao;

import com.lanou.bean.User;

public interface UserDao {
    public User findUserById(int id);
}
UserDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lanou.dao.UserDao">
    <select id="findUserById" parameterType="Integer" resultType="com.lanou.bean.User">
        select * from User where id = #{param}
    </select>
</mapper>
UserDaoTest.java

public class UserDaoTest {
    @Test
    public void testName() throws Exception {
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory factory = builder.build(inputStream);
        SqlSession session = factory.openSession();

        UserDao dao = new UserDao() {

            @Override
            public User findUserById(int id) {
                // TODO Auto-generated method stub
                return session.selectOne("com.lanou.dao.UserDao.findUserById", id);
            }
        };

        User user = dao.findUserById(10);
        System.out.println(user);
    }
}

小结

在传统的分层结构中 有大量的dao层实现类 随着项目的扩展 这些类文件会越来越多 不方便维护
MyBatis 提供了一种dao层解决方案
纯接口开发
    只有接口 没有实现类 Mybatis自动为接口生成代理对象 完成实现类的封装
    实现原理 生成代理对象 实现目标接口 并在代理对象中 通过mapper读取配置信息 生成实现代码

    之前手动创建实现类 手动调用mapper中定义好的sql语句
    之后Mybatis根据接口创建实现类 在实现类中自动调用mapper中定义好的sql语句
    具体操作:
    1.创建接口 定义需要的方法
    2.创建映射文件mapper
    3.编写映射文件
        1).命名空间与指定为接口的完整类名
        2).id必须与接口中的方法一致
        3).参数类型与接口方法一致
        4).返回值类型与接口方法一致
    4.把映射注册到主配置文件
    5.通过session获取接口实现对象
        xxxDAO dao = session.getMapper(接口.class)

Mybatis
    Mappers用于指定映射文件 

 <!-- 指定与映射文件关联的那个接口类名
             要求映射文件和接口名字必须相同 在同一级目录
             <mapper class="com.lanou.dao.UserDao"/>
              -->
        <!-- 指定扫描某个包以及子孙下的所有映射文件
            注意 该方式要求映射文件名与接口名一致

         -->
        <package name="com/lanou/dao"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值