SpringBoot应用MyBatis

SpringBoot应用MyBatis

  1. 添加SpringBoot对MyBatis整合包

    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>1.2.2</version>
    </dependency>
    
  2. 定义实体类

    属性名和类型与数据表字段名和类型保持一致。

    public class User implements Serializable{
        private Integer id;                                
        private String login_name;                      
        private String nick_name;                       
        private String real_name;   
    
        //省略setter和getter
    }
    
  3. 定义SQL语句

    <?xml version="1.0" encoding="UTF-8" ?>  
    <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
     "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
    <mapper namespace="cn.xdl.springboot.dao.UserMapper">
        <select id="findAll" resultType="cn.xdl.springboot.entity.User">
        select * from xdl_user
        </select>
    
    </mapper>
    
  4. 定义Mapper映射接口

    @Mapper//标注是一个Mapper映射器接口
    public interface UserMapper {
    
        public List<User> findAll();
    
    }
    
  5. 在application.properties加载定义sql的xml文件

    mybatis.mapper-locations=classpath:cn/xdl/sql/*.xml
    
  6. 测试代码,直接注入UserMapper对象

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes={BootApplication.class})
    public class TestUserMapper {
    
        @Autowired
        private UserMapper userMapper;
    
        @Test
        public void test1(){
            List<User> list = userMapper.findAll();
            for(User user:list){
                System.out.println(user.getId()+" "+user.getNick_name());
            }
        }
    
    }
    

案例1: SpringBoot应用JdbcTemplate实现DAO

一、SpringBoot环境搭建

  1. 创建一个maven project
  2. 在pom.xml中添加boot环境依赖的jar包定义

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.2.RELEASE</version>
        <relativePath/> 
    </parent>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.7</java.version>
    </properties>
    
    <dependencies>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    
    </dependencies>
    
  3. 在src/main/resources下添加主配置文件application.properties

  4. 创建cn.xdl.springboot包,添加一个boot主入口类

    package cn.xdl.springboot;
    
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class BootMainApplication {
    
    }
    

二、SpringBoot默认连接池构建

  1. 在pom.xml中追加spring-boot-starter-jdbc和ojdbc包的依赖

    <!-- tomcat连接池、jdbcTemplate支持 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
      <groupId>com.oracle</groupId>
      <artifactId>ojdbc6</artifactId>
      <version>11.2.0.3</version>
    </dependency>
    
  2. 在application.properties添加连接池参数定义

    spring.datasource.username=zxh
    spring.datasource.password=123
    spring.datasource.url=jdbc:oracle:thin:@localhost:1521/XE
    #spring.datasource.driver-class-name=
    

    SpringBoot会自动创建DataSource对象和JdbcTemplate对象。

三、利用JdbcTemplate实现DAO

  1. 编写实体类

    public class Evaluation implements Serializable{
        private Integer  id;                           
        private Integer  user_id;               
        private Integer  product_id;                     
        private Integer  order_id;              
        //省略setter和getter方法
    }
    
  2. 编写DAO接口

    public interface EvaluationDao {
        public List<Evaluation> findAll();
    }
    
  3. 编写DAO实现类

    @Repository
    public class JdbcEvaluationDao implements EvaluationDao{
    
        @Autowired
        private JdbcTemplate template;
    
        public List<Evaluation> findAll() {
            String sql = "select * from Evaluation";
            List list = template.query(
                sql, new BeanPropertyRowMapper(Evaluation.class));
            return list;
        }
    
    }
    

四、测试DAO

  1. 在src/test/java下编写测试类

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes={BootMainApplication.class})
    public class TestEvaluationDao {
    
        @Autowired
        private EvaluationDao evalDao;
    
        @Test
        public void test1(){
            List<Evaluation> list = evalDao.findAll();
            for(Evaluation eval:list){
                System.out.println(eval);
            }
        }
    
    }
    

案例2: SpringBoot应用MyBatis实现DAO

一、SpringBoot环境的搭建

  1. 创建maven project
  2. 在pom.xml中添加boot框架jar包定义
  3. 在src/main/resources下创建application.propertie文件
  4. 在cn.xdl.springboot包下创建入口类

二、SpringBoot默认数据源的连接池

  1. 在pom.xml中添加spring-boot-starter-jdbc和ojdbc包定义
  2. 在application.properties定义连接参数

三、添加Mybatis框架元素

  1. 在pom.xml中添加mybatis-spring-boot-starter包依赖

    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>1.2.2</version>
    </dependency>
    
  2. 定义实体类

    public class Evaluation implements Serializable{
        private Integer  id;                           
        private Integer  user_id;               
        private Integer  product_id;                     
        private Integer  order_id;              
        //省略setter和getter方法
    }
    
  3. 定义Mapper接口和SQL

    SQL语句(支持XML定义或注解定义)

    @Mapper
    public interface EvaluationMapper {
    
        @Select("select * from product_evaluation")
        public List<Evaluation> findAll();
    
    }
    
  4. 在主入口类BootMainApplication.java中添加@MapperScanner扫描Mapper接口

    @SpringBootApplication
    @MapperScan(basePackages={"cn.example.springboot.dao"})//mybatis.mapper-locations=classpath:cn/example/sql/*.xml
    public class BootMainApplication {
    
    }
    

四、测试Mapper对象

@RunWith(SpringRunner.class)
@SpringBootTest(classes={BootMainApplication.class})
public class TestEvaluationMapper {

    @Resource
    private EvaluationMapper evalMapper;

    @Test
    public void test1(){
        List<Evaluation> list = evalMapper.findAll();
        for(Evaluation eval:list){
            System.out.println(eval);
        }
    }

}

案例3: SpringBoot应用MyBatis实现插入并返回ID值

  1. Oracle数据库采用序列生成主键ID

    @Mapper
    public interface EvaluationMapper {

    @Insert("insert into product_evaluation (id,user_id,product_id,order_id,title,score) values (#{id},#{user_id},#{product_id},#{order_id},#{title},#{score})")
    @SelectKey(keyProperty="id",before=true,
        statement="select eval_seq.nextval from dual",
        resultType=Integer.class)
    public int save(Evaluation eval);
    

    }

  2. 测试插入后,ID是否返回

    @Test
    public void test2(){
        Evaluation eval = new Evaluation();
        eval.setOrder_id(1);
        eval.setProduct_id(1);
        eval.setTitle("SpringBoot444");
        eval.setScore(5.0);
        eval.setUser_id(1);
        evalMapper.save(eval);
        System.out.println("ID值:"+eval.getId());
    }
    

案例4: SpringBoot应用MyBatis实现分页操作

  1. 在pom.xml中添加pagehelper包的定义
  2. 在cn.xdl.springboot.config包添加注册类

    创建PageHelper对象,放入Spring容器。

    package cn.example.springboot.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import com.github.pagehelper.PageHelper;
    
    @Configuration
    public class PageHelperConfig {
    
        @Bean
        public PageHelper createPageHelper(){
            PageHelper page = new PageHelper();
            return page;
        }
    
    }
    
  3. 在调用Mapper对象方法前,使用PageHelper.startPage()方法

    @Test//分页
    public void test3(){
        Page page = PageHelper.startPage(2, 5);//startPage(第几页,一页几条)
        List<Evaluation> list = evalMapper.findAll();
        for(Evaluation eval:list){
            System.out.println(eval.getId()+" "+eval.getTitle());
        }
        System.out.println("总记录数:"+page.getTotal());
        System.out.println("总页数:"+page.getPages());
    }
    

案例5: SpringBoot应用Redis存取数据

  1. 在pom.xml中添加spring-boot-starter-redis包的定义

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-redis</artifactId>
    </dependency>
    
  2. 在application.properties中定义redis连接参数

    spring.redis.port=6379
    spring.redis.host=127.0.0.1
    
  3. 注入RedisTemplate对象进行应用

    注意:RedisTemplate对象有两个实例,id分别为redisTemplate和stringRedisTemplate

    • redisTemplate作用:用于对象存取。
    • stringRedisTemplate作用:用于字符串存取。

    示例代码:

    @Repository
    public class RedisDao implements IRedisDao {
    
        @Autowired
        @Qualifier("redisTemplate")//指定泛型后可省略
        private RedisTemplate<Object, Object> template;
    
        public void saveObject(String key,Object value){
            template.opsForValue().set(key, value);
        }
    
        public Object getObject(String key){
            Object value = template.opsForValue().get(key);
            return value;
        }
    
    }
    
  4. 测试

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes={BootMainApplication.class})
    public class TestRedisDao {
    
        @Autowired
        private IRedisDao redisDao;
    
        @Test//存储信息
        public void test1(){
            redisDao.saveObject("boot", "SpringBoot");
            Evaluation eval = new Evaluation();
            eval.setId(100);
            eval.setTitle("Java SpringBoot");
            eval.setOrder_id(1);
            eval.setProduct_id(1);
            redisDao.saveObject("eval_100",eval);
        }
    
        @Test//获取信息
        public void test2(){
            String value = (String)redisDao.getObject("boot");
            System.out.println(value);
        }
    }
    

SpringBoot之Web应用开发

Web准备工作

  1. 在项目pom.xml中追加spring-boot-starter-web包定义

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    

    作用:支持springwebmvc、restful、内置tomcat等功能

  2. 启动Tomcat服务器和Spring容器实例化

    在入口类中添加main方法启动tomcat,默认端口8080、项目为/。

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

    如果需要修改端口和项目名,可以在application.properties文件添加配置

    server.port=8888
    server.context-path=/boot
    

SpringWebMVC开发

原有SpringWebMVC中的DispatcherServlet、HandlerMapping等全部由自动配置完成实例化和加载。

  1. RESTFUL应用

    常用标记:@RestController、@RequestMapping、@RequestParam、@PathVariable等

    • 案例1:定义一个RESTFUL服务接口,实现查询所有评价信息

      接口地址:
      http://localhost:8888/boot/evals?p=xxx
          使用@RequestParam("p") int page
      http://localhost:8888/boot/evals/p/{p}
          使用@PathVariable("p") int page
      提交类型:GET  
      响应结果:JSON类型 例如[{},{}]
      
    • 实现代码

      @RestController//控制层
      public class EvaluationController {
      
          @Resource
          private EvaluationService evalService;
      
          @RequestMapping(value="/evals",method=RequestMethod.GET)
          public List<Evaluation> loadAll(
              @RequestParam(required=false,value="p",defaultValue="1")int page){
      
              return evalService.loadEvals(page);
          }
      
          @RequestMapping(value="/evals/p/{p}",method=RequestMethod.GET)
          public List<Evaluation> loadAll1(
              @PathVariable("p") int page){
      
              return evalService.loadEvals(page);
          }
      
      }
      

      为了代码重用性和灵活性,可以将Controller代码提取出来,封装到Service组件中,然后Controller调用Service,Service再调用Dao组件。

    • 测试web程序

      启动主入口类的main方法,然后浏览器发送URL请求测试

SpringBoot WebMVC JSP应用

案例1:发出/hello.do,显示出/hello.jsp界面

/hello.do–>DispatcherServlet–>HandlerMapping–>HelloController–>ViewResolver–>/hello.jsp

SpringBoot会利用自动配置,完成DispatcherServlet、HandlerMapping和ViewResolver配置及对象创建,然后进行流程实现。

  1. 搭建SpringBoot WebMVC 开发环境

    • 创建maven project
    • 在pom.xml中添加jar包的定义

      <parent>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-parent</artifactId>
          <version>1.4.2.RELEASE</version>
          <relativePath/> 
      </parent>
      
      <properties>
          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
          <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
          <java.version>1.7</java.version>
      </properties>
      
      <dependencies>
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter</artifactId>
          </dependency>
      
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-test</artifactId>
              <scope>test</scope>
          </dependency>
      
          <!-- 追加springwebmvc -->
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-web</artifactId>
          </dependency>
          <!-- 追加jsp解析器 -->
          <dependency>  
              <groupId>org.apache.tomcat.embed</groupId>  
              <artifactId>tomcat-embed-jasper</artifactId>    
          </dependency> 
      
      </dependencies>
      
    • 在src/main/resources添加application.properties

      #server,默认8080会和oracle冲突
      server.port=8888
      server.context-path=/bootmvc
      #jsp
      spring.mvc.view.prefix=/
      spring.mvc.view.suffix=.jsp
      
    • 在cn.xdl.springboot添加入口类BootApplication.java

      @SpringBootApplication
      public class BootApplication {
      
          public static void main(String[] args){
              SpringApplication.run(BootApplication.class, args);
          }
      
      }
      
  2. 编写Controller和JSP

    • 编写HelloController

      @Controller
      public class HelloController {
      
          @RequestMapping("/hello.do")
          public ModelAndView sayHello(){
              ModelAndView mav = new ModelAndView();
              mav.setViewName("hello");//视图名,对应hello.jsp
              mav.getModel().put("msg", "SpringBoot MVC应用(JSP版本)");
              return mav;
          }
      
      }
      
    • 编写JSP

      在src/main/webapp下添加hello.jsp

      <%@ page language="java" contentType="text/html; charset=UTF-8"
          pageEncoding="UTF-8"%>
      <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
      <html>
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Insert title here</title>
      </head>
      <body>
      <h1>SpringBoot 示例</h1>
      ${msg }
      </body>
      </html>
      

案例2:登录案例

  1. 显示登录页面

    /tologin.do–>/login.jsp

    • 编写LoginController

      @Controller
      public class LoginController {
      
          @RequestMapping("/tologin.do")
          public String index(){
              return "login";//login.jsp
          }
      }
      
    • 编写login.jsp

      <html>
          <head>
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
          <title>Insert title here</title>
          </head>
          <body>
          <h1>登录页面</h1>
          <form action="login.do" method="post">
          用户名:<input type="text" name="username"><br/>
          密码:<input type="password" name="password"><br/>
          <input type="submit" value="登录">
          </form>
          </body>
      </html>
      
  2. 登录按钮处理

    /login.do–>LoginController.checklogin–>成功ok.jsp;失败login.jsp

    • 在LoginController追加checklogin方法,处理/login.do请求

      @RequestMapping("/login.do")
      public ModelAndView checkLogin(
              String username,String password,
              HttpSession session){
          System.out.println(username+" : "+password);
          ModelAndView mav = new ModelAndView();
          if("zxh".equalsIgnoreCase(username) 
                  && "123456".equals(password)){
              session.setAttribute("user", username);
              //mav.setViewName("ok");//ok.jsp
              mav.setView(new RedirectView("hello.do"));//重定向到hello.do
          }else{
              mav.setViewName("login");
              mav.getModel().put("error", "账号或密码错误");
          }
          return mav;
      }
      
    • 添加ok.jsp;修改login.jsp

      ok.jsp中利用${sessionScope.user}取session信息

      <html>
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Insert title here</title>
      </head>
      <body>
      <h1>${sessionScope.user }登录成功</h1>
      <a href="tologin.do">重新登录</a>
      </body>
      </html>
      

      login.jsp中利用${error}显示错误提示信息。

案例3:异常处理

  1. SpringBoot异常处理机制

    • 内置了一个BasicErrorController,其中提供了两个/error请求处理,一个处理json响应;一个处理界面响应
    • 当boot程序内部出了错误后,底层会自动发出一个/error请求
    • 内置了一个BasicErrorController实现了ErrorController接口

  2. (全局错误处理)可以自定义ErrorController组件,自定义后会boot内部会取消BasicErrorController

    @Controller
    public class MyErrorController implements ErrorController{
    
        private static final String ERROR_PATH  = "/error";
    
        @Override
        public String getErrorPath() {
            // TODO Auto-generated method stub
            return ERROR_PATH;
        }
    
        @RequestMapping(value=ERROR_PATH)
        public ModelAndView handleException(){
            ModelAndView mav = new ModelAndView();
            mav.setViewName("error500");//error500.jsp
            mav.getModel().put("error", "ErrorController:内部发生错误");
            return mav;
        }
    
    }
    
  3. (局部错误处理)在Controller中添加@ExceptionHandler注解方法

    @ExceptionHandler//默认处理所有类型异常,也可以指定异常类型
    public ModelAndView handleException(Exception ex){
        ModelAndView mav = new ModelAndView();
        mav.setViewName("error500");
        mav.getModel().put("error", "@ExceptionHandler:系统内部错误");
        return mav;
    }
    
  4. 编写一个Controller,在Controller中添加@ControllerAdvice,然后再加@ExceptionHandler方法

    作用:等价于为每一个Controller都继承了当前Controller一样,不需要再写extends BaseController了。

    @ControllerAdvice//会将异常处理作用到其他Controller请求处理上
    public class BaseController {
    
        @ExceptionHandler//默认处理所有类型异常,也可以指定异常类型
        public ModelAndView handleException(Exception ex){
            ModelAndView mav = new ModelAndView();
            mav.setViewName("error500");
            mav.getModel().put("error", "@ControllerAdvice:系统内部错误");
            return mav;
        }
    
    }
    
  5. 遇到错误后,处理优先级

    出错–>Controller内部的@ExceptionHandler–>@ControllerAdvice的@ExceptionHandler–>ErrorController的处理

案例4:登录检查拦截器

  1. 编写拦截器组件,组件类实现HandlerInterceptor接口

    public class CheckLoginInterceptor implements HandlerInterceptor{
    
        public boolean preHandle(
                HttpServletRequest request, 
                HttpServletResponse response, Object handler)
                throws Exception {
            String user = (String)request.getSession().getAttribute("user");
            if(user == null){//没有登录信息,未登录
                response.sendRedirect("tologin.do");//定位到登录页面
                return false;//阻止controller执行
            }
            return true;//允许执行controller
        }
    
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                ModelAndView modelAndView) throws Exception {
            // TODO Auto-generated method stub
    
        }
    
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            // TODO Auto-generated method stub
    
        }
    
    }
    
  2. 编写InterceptorConfig类,注册拦截器

    @Configuration
    public class InterceptorConfig extends WebMvcConfigurerAdapter{
    
        public void addInterceptors(InterceptorRegistry registry) {
            HandlerInterceptor checklogin = new CheckLoginInterceptor();
            //将拦截器注册,并指定拦截器请求
            registry.addInterceptor(checklogin)
                .addPathPatterns("/hello.do");
        }
    
    }
    

SpringBoot WebMVC HTML应用(动态界面)

  1. thymeleaf模板技术

    模板技术,模板扩展名为.html,可以在模板文件中使用th:text、th:each等表达式动态生成响应界面。

    velocity、freemarker都属于模板技术。boot默认支持thymeleaf模板技术。

  2. 静态资源存储

    在springboot中,提供了以下几个目录,专门用于存放静态资源信息。例如html、css、js、image等

    • src/main/resources/META-INF/resources
    • src/main/resources/resources
    • src/main/resources/static
    • src/main/resources/public

    上面目录/META-INF/resources优先级最高、/public最低。

    内部原理:/**直接映射到上面目录中。

    如果自定义了一个存放静态资源的文件夹,需要进行资源映射,才能够使用URL访问到。
    例如下面代码是将/mystatic/**请求映射到了src/main/resources/mystatic目录下。

    @Configuration
    public class MyResourcesConfig extends WebMvcConfigurerAdapter{
    
        //注册静态资源和请求URL映射
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/mystatic/**")
                .addResourceLocations("classpath:/mystatic/");
        }
    
    }
    
  3. 使用thymeleaf模板技术

    src/main/resources/templates 目录是用于存放html模板文件的位置。这样html中就可以使用模板标记获取模型中的数据。

    如果希望改变模板文件默认存储路径,可以在appliation.properties中进行修改

    //默认设置如下,可以修改
    spring.thymeleaf.prefix=classpath:/templates
    spring.thymeleaf.suffix=.html
    

案例5: 使用html页面做动态响应

/index.do–>DispatcherServlet–>HandlerMapping–>IndexController–>thymeleaf模板引擎–>/templates/index.html–>生成HTML响应结果

  1. 在pom.xml中添加spring-boot-starter-thymeleaf定义

    <!-- html模板支持 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    
  2. 编写IndexController

    @Controller
    public class IndexController {
    
        @RequestMapping("/index.do")
        public ModelAndView index(){
            ModelAndView mav = new ModelAndView();
            mav.setViewName("index");///templates/index.html
            mav.getModel().put("msg", "Hello Spring Boot");
            List<City> list = new ArrayList<City>();
            list.add(new City(1,"北京"));
            list.add(new City(2,"成都"));
            list.add(new City(3,"沈阳"));
            list.add(new City(4,"广州"));
            mav.getModel().put("cities", list);
            return mav;
        }
    
    }
    
  3. 编写index.html(在/templates下创建index.html)

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
    <meta charset="UTF-8"/>
    <title>Insert title here</title>
    </head>
    <body>
        <h1>Templates Hello</h1>
        <p th:text="${msg}"></p>
        <table>
            <tr th:each="city:${cities}">
                <td th:text="${city.id}"></td>
                <td th:text="${city.name}"></td>
            </tr>
        </table>
    </body>
    </html>
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值