springmvc使用

springmvc的使用

介绍

官方解释:Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架。

基本使用

打个比方,如果是用原来的方式进行请求的话,一般我们是以servlet的方式进行请求,以及请求中带参数进行传递参,然后后台利用request和response来进行请求和响应进行处理,通过判断前台请求的方法来进行调用,而springmvc为我们提供了一个很好的方便,springmvc利用requestMapping来进行唯一标识的请求(注意每一个requestMapping的标识都是唯一的,如果出现多个controller,则需要在控制器上面也加一个requestMapping的注解来进行唯一标识),而请求则只需要填写响应的requestMapping唯一标示的名字即可。
下面举个例子来说明springmvc的基本用法:

entity层

package com.yqx.entity;

import java.sql.Timestamp;
import java.util.Date;

public class Student {

	private int id;
	private String name;
	private String username;
	private String password;
	private int sex;
	private int age;
	private Date birthday;
	private Timestamp creatTime;
	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 getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public int getSex() {
		return sex;
	}
	public void setSex(int sex) {
		this.sex = sex;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	public Timestamp getCreatTime() {
		return creatTime;
	}
	public void setCreatTime(Timestamp creatTime) {
		this.creatTime = creatTime;
	}
	public Student(int id, String name, String username, String password, int sex, int age, Date birthday,
			Timestamp creatTime) {
		super();
		this.id = id;
		this.name = name;
		this.username = username;
		this.password = password;
		this.sex = sex;
		this.age = age;
		this.birthday = birthday;
		this.creatTime = creatTime;
	}
	public Student() {
		super();
	}
}

Dao层

package com.yqx.dao;

import java.util.List;

import com.yqx.entity.Student;

public interface StudentDao {

	/**
	 * ��Ӽ�¼
	 * @param student
	 */
	public void add(Student student);
	/**
	 * ������Ӽ�¼
	 * @param list
	 */
	public void addMore(List<Student> list);
	/**
	 * ��������ɾ����¼
	 * @param id
	 */
	public void deleteById(int id);
	/**
	 * ������������ɾ����¼
	 * @param ids
	 */
	public void deleteMore(String ids);
	/**
	 * ���¼�¼
	 * @param student
	 */
	public void update(Student student);
	/**
	 * ����������ѯ������¼
	 * @param id
	 * @return
	 */
	public Student queryById(int id);
	/**
	 * ��ѯ���м�¼
	 * @return
	 */
	public List<Student> queryAll();
	/**
	 * ��ҳ��ѯ��¼
	 * @param currentPage
	 * @param pageSize
	 * @return
	 */
	public List<Student> queryByPage(int currentPage,int pageSize);
	/**
	 * ������ҳ��ѯ��¼
	 * @param currentPage
	 * @param pageSize
	 * @return
	 */
	public List<Student> queryByPage(int currentPage,int pageSize,String condition);
	/**
	 * ��ȡ�ܼ�¼��
	 * @return
	 */
	public int getTotals();
	/**
	 * ����������ȡ�ܼ�¼��
	 * @return
	 */
	public int getTotals(String condition);
}
package com.yqx.daoImpl;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import com.yqx.dao.StudentDao;
import com.yqx.entity.Student;
import com.yqx.util.DBUtil;

public class StudentDaoImpl implements StudentDao{

	@Override
	public void add(Student student) {
		Connection con = DBUtil.getConnection();
		PreparedStatement pst = null;
		String sql = "insert into student(name,username,password,sex,age,birthday,creatTime) values(?,?,?,?,?,?,?)";
		try {
			pst = con.prepareStatement(sql);
			pst.setString(1, student.getName());
			pst.setString(2, student.getUsername());
			pst.setString(3, student.getPassword());
			pst.setInt(4, student.getSex());
			pst.setInt(5, student.getAge());
			pst.setDate(6, new Date(student.getBirthday().getTime()));
			pst.setTimestamp(7,new Timestamp(System.currentTimeMillis()));
			System.out.println("�ɹ�����"+pst.executeUpdate()+"������");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtil.close(con, pst, null);
		}
	}

	@Override
	public void addMore(List<Student> list) {
		Connection con = DBUtil.getConnection();
		PreparedStatement pst = null;
		String sql = "insert into student(name,username,password,sex,age,birthday,creatTime) values(?,?,?,?,?,?,?)";
		try {
			pst = con.prepareStatement(sql);
			for(int i=0;i<list.size();i++) {
				Student student = list.get(i);
				pst.setString(1, student.getName());
				pst.setString(2, student.getUsername());
				pst.setString(3, student.getPassword());
				pst.setInt(4, student.getSex());
				pst.setInt(5, student.getAge());
				pst.setDate(6, new Date(student.getBirthday().getTime()));
				pst.setTimestamp(7,new Timestamp(System.currentTimeMillis()));
				pst.addBatch();
				if(i%300==0) {
					pst.executeBatch();
					pst.clearBatch();
				}
			}
			pst.executeBatch();
			pst.clearBatch();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtil.close(con, pst, null);
		}
	}

	@Override
	public void deleteById(int id) {
		Connection con = DBUtil.getConnection();
		PreparedStatement pst = null;
		String sql = "delete from student where id=?";
		try {
			pst = con.prepareStatement(sql);
			pst.setInt(1, id);
			System.out.println("�ɹ�ɾ��"+pst.executeUpdate()+"������");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtil.close(con, pst, null);
		}
	}

	@Override
	public void deleteMore(String ids) {
		Connection con = DBUtil.getConnection();
		PreparedStatement pst = null;
		String sql = "delete from student where id in ("+ids+")";
		try {
			pst = con.prepareStatement(sql);
			System.out.println("�ɹ�ɾ��"+pst.executeUpdate()+"������");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtil.close(con, pst, null);
		}
	}

	@Override
	public void update(Student student) {
		Connection con = DBUtil.getConnection();
		PreparedStatement pst = null;
		String sql = "update student set name=?,username=?,password=?,sex=?,age=?,birthday=?,creatTime=? where id=?";
		try {
			pst = con.prepareStatement(sql);
			pst.setString(1, student.getName());
			pst.setString(2, student.getUsername());
			pst.setString(3, student.getPassword());
			pst.setInt(4, student.getSex());
			pst.setInt(5, student.getAge());
			pst.setDate(6, new Date(student.getBirthday().getTime()));
			pst.setTimestamp(7,new Timestamp(System.currentTimeMillis()));
			pst.setInt(8, student.getId());
			System.out.println("�ɹ��޸�"+pst.executeUpdate()+"������");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtil.close(con, pst, null);
		}
	}

	@Override
	public Student queryById(int id) {
		Connection con = DBUtil.getConnection();
		PreparedStatement pst = null;
		ResultSet rs = null;
		String sql = "select * from student where id=?";
		try {
			pst = con.prepareStatement(sql);
			pst.setInt(1, id);
			rs = pst.executeQuery();
			if(rs.next()) {
				Student s = new Student();
				s.setId(rs.getInt("id"));
				s.setName(rs.getString("name"));
				s.setUsername(rs.getString("username"));
				s.setPassword(rs.getString("password"));
				s.setSex(rs.getInt("sex"));
				s.setAge(rs.getInt("age"));
				s.setBirthday(rs.getDate("birthday"));
				s.setCreatTime(rs.getTimestamp("creatTime"));
				return s;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtil.close(con, pst, rs);
		}
		return null;
	}

	@Override
	public List<Student> queryAll() {
		List<Student> list = new ArrayList<>();
		Connection con = DBUtil.getConnection();
		PreparedStatement pst = null;
		ResultSet rs = null;
		String sql = "select * from student order by id";
		try {
			pst = con.prepareStatement(sql);
			rs = pst.executeQuery();
			while(rs.next()) {
				Student s = new Student();
				s.setId(rs.getInt("id"));
				s.setName(rs.getString("name"));
				s.setUsername(rs.getString("username"));
				s.setPassword(rs.getString("password"));
				s.setSex(rs.getInt("sex"));
				s.setAge(rs.getInt("age"));
				s.setBirthday(rs.getDate("birthday"));
				s.setCreatTime(rs.getTimestamp("creatTime"));
				list.add(s);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtil.close(con, pst, rs);
		}
		return list;
	}

	@Override
	public List<Student> queryByPage(int currentPage, int pageSize) {
		List<Student> list = new ArrayList<>();
		Connection con = DBUtil.getConnection();
		PreparedStatement pst = null;
		ResultSet rs = null;
		String sql = "select * from student order by id limit ?,?";
		try {
			pst = con.prepareStatement(sql);
			pst.setInt(1, (currentPage-1)*pageSize);
			pst.setInt(2, pageSize);
			rs = pst.executeQuery();
			while(rs.next()) {
				Student s = new Student();
				s.setId(rs.getInt("id"));
				s.setName(rs.getString("name"));
				s.setUsername(rs.getString("username"));
				s.setPassword(rs.getString("password"));
				s.setSex(rs.getInt("sex"));
				s.setAge(rs.getInt("age"));
				s.setBirthday(rs.getDate("birthday"));
				s.setCreatTime(rs.getTimestamp("creatTime"));
				list.add(s);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtil.close(con, pst, rs);
		}
		return list;
	}

	@Override
	public int getTotals() {
		Connection con = DBUtil.getConnection();
		PreparedStatement pst = null;
		ResultSet rs = null;
		String sql = "select count(*) from student";
		try {
			pst = con.prepareStatement(sql);
			rs = pst.executeQuery();
			if(rs.next()) {
				return rs.getInt(1);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtil.close(con, pst, rs);
		}
		return 0;
	}
	@Override
	public int getTotals(String condition) {
		Connection con = DBUtil.getConnection();
		PreparedStatement pst = null;
		ResultSet rs = null;
		String sql = "select count(*) from student "+condition;
		try {
			pst = con.prepareStatement(sql);
			rs = pst.executeQuery();
			if(rs.next()) {
				return rs.getInt(1);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtil.close(con, pst, rs);
		}
		return 0;
	}

	@Override
	public List<Student> queryByPage(int currentPage, int pageSize, String condition) {
		List<Student> list = new ArrayList<>();
		Connection con = DBUtil.getConnection();
		PreparedStatement pst = null;
		ResultSet rs = null;
		String sql = "select * from student "+condition+" order by id limit ?,?";
		try {
			pst = con.prepareStatement(sql);
			pst.setInt(1, (currentPage-1)*pageSize);
			pst.setInt(2, pageSize);
			rs = pst.executeQuery();
			while(rs.next()) {
				Student s = new Student();
				s.setId(rs.getInt("id"));
				s.setName(rs.getString("name"));
				s.setUsername(rs.getString("username"));
				s.setPassword(rs.getString("password"));
				s.setSex(rs.getInt("sex"));
				s.setAge(rs.getInt("age"));
				s.setBirthday(rs.getDate("birthday"));
				s.setCreatTime(rs.getTimestamp("creatTime"));
				list.add(s);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtil.close(con, pst, rs);
		}
		return list;
	}
}

工具类用来进行连接池

package com.yqx.util;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

public class DBUtil {

	private static String driver;
	private static String url;
	private static String username;
	private static String password;
	
	static {
		Properties p = new Properties();
		try {
			p.load(DBUtil.class.getResourceAsStream("/dbconfig.properties"));
			driver = p.getProperty("driver");
			url = p.getProperty("url");
			username = p.getProperty("username");
			password = p.getProperty("password");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * ��ȡ���ݿ����Ӷ���
	 * @return
	 */
	public static Connection getConnection() {
		try {
			Class.forName(driver);
			return DriverManager.getConnection(url, username, password);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * �ر����ݿ����
	 * @param con
	 * @param pst
	 * @param rs
	 */
	public static void close(Connection con,PreparedStatement pst,ResultSet rs) {
		if(rs!=null) {
			try {
				rs.close();
				rs = null;
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(pst!=null) {
			try {
				pst.close();
				pst = null;
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(con!=null) {
			try {
				con.close();
				con = null;
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

properties文件配置数据库

#mysql
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/yqx?useUnicode=true&characterEncoding=utf-8
username=root
password=root

package com.yqx.controller;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;

import com.yqx.dao.StudentDao;
import com.yqx.daoImpl.StudentDaoImpl;
import com.yqx.entity.Student;
import com.yqx.util.Pager;

@Controller
public class StudentController {

@RequestMapping("/add")
public String add(Student s) {
	StudentDao dao = new StudentDaoImpl();
	dao.add(s);
	return "forward:/queryByPage";
}
@RequestMapping("/deleteById")
public String deleteById(int id) {
	StudentDao dao = new StudentDaoImpl();
	dao.deleteById(id);
	return "forward:/queryByPage";
}
@RequestMapping("/deleteMore")
public String deleteMore(String ids) {
	StudentDao dao = new StudentDaoImpl();
	dao.deleteMore(ids);
	return "forward:/queryByPage";
}
@RequestMapping("/update")
public String update(Student s) {
	StudentDao dao = new StudentDaoImpl();
	dao.update(s);
	return "forward:/queryByPage";
}
@RequestMapping("/queryById")
public String queryById(HttpServletRequest request,int id,String currentPage,Map<String,Object> map) {
	
	String qname = request.getParameter("qname");
	String qusername = request.getParameter("qusername");
	String qsex = request.getParameter("qsex");
	
	StudentDao dao = new StudentDaoImpl();
	Student s = dao.queryById(id);
	map.put("student", s);
	map.put("currentPage", currentPage);
	map.put("qname", qname);
	map.put("qusername", qusername);
	map.put("qsex", qsex);
	
	return "update";
}
@RequestMapping("/queryByPage")
public String queryByPage(HttpServletRequest request,String currentPage,Map<String,Object> map) {
	
	String qname = request.getParameter("qname");
	String qusername = request.getParameter("qusername");
	String qsex = request.getParameter("qsex");

	String condition = " where 1=1 ";
	if (qname != null && !qname.equals("")&&!qname.equalsIgnoreCase("null")) {
		condition += " and name like '%" + qname + "%' ";
	}
	if (qusername != null && !qusername.equals("")&&!qusername.equalsIgnoreCase("null")) {
		condition += " and username like '%" + qusername + "%' ";
	}
	if (qsex != null && !qsex.equals("") && !qsex.equals("-1")&&!qsex.equalsIgnoreCase("null")) {
		condition += " and sex = " + qsex ;
	}
	
	StudentDao dao = new StudentDaoImpl();
	Pager<Student> pager = new Pager<>(dao.getTotals(condition),currentPage);
	List<Student> list = dao.queryByPage(pager.getSp(), pager.getPageSize(),condition);
	pager.setList(list);
	
	map.put("pager", pager);
	map.put("qname", qname);
	map.put("qusername", qusername);
	map.put("qsex", qsex);
	
	return "list";
}

/*
 * �������Ϊ���ڸ�ʽ
 * */
@InitBinder
public void initBinder(ServletRequestDataBinder binder){
    binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),
            true));
}

}
页面显示利用原生的数据显示方法,为了可以和servlet进行对比

<table border=1 id="myTable">
		<tr>
			<th><input type="checkbox"></th>
			<th>编号</th>
			<th>姓名</th>
			<th>账号</th>
			<th>密码</th>
			<th>性别</th>
			<th>年龄</th>
			<th>出生日期</th>
			<th>创建时间</th>
			<th>操作
				<a href="add.jsp">新增</a>
				|
				<a href="#" onclick="deleteMore(${pager.sp },'${qname }','${qusername }','${qsex }');">批量删除</a>
			</th>
		</tr>

		<c:forEach var="student" items="${pager.list }">
			<tr onmouseover="mouseOver(this);" onmouseout="mouseOut(this);">
				<td><input type="checkbox" value="${student.id }"></td>
				<td>${student.id }</td>
				<td>${student.name }</td>
				<td>${student.username }</td>
				<td>${student.password }</td>
				<td>${student.sex==1?"男":"女" }</td>
				<td>${student.age }</td>
				<td>${student.birthday }</td>
				<td>${student.creatTime }</td>
				<td>
					<a href="queryById?id=${student.id }&currentPage=${pager.sp }&qname=${qname }&qusername=${qusername}&qsex=${qsex}">修改</a>
					|
					<a href="#" onclick="deleteById(${student.id},${pager.sp },'${qname }','${qusername }','${qsex }');">删除</a>
				</td>
			</tr>
		</c:forEach>
		
	</table>
	<div id="page">
		总记录数:${pager.totals }&nbsp;&nbsp;总页数:${pager.pageCounts }&nbsp;&nbsp;当前页:${pager.sp }&nbsp;&nbsp;
		<a href="queryByPage?currentPage=1&qname=${qname }&qusername=${qusername}&qsex=${qsex}">首页</a>&nbsp;&nbsp;
		<a href="queryByPage?currentPage=${pager.sp-1 }&qname=${qname }&qusername=${qusername}&qsex=${qsex}">上一页</a>&nbsp;&nbsp;
		<form action="queryByPage?qname=${qname }&qusername=${qusername}&qsex=${qsex}" method="post" style="display: inline;">
			<input type="text" name="currentPage" size="4" value="${pager.sp }">
		</form>
		<a href="queryByPage?currentPage=${pager.sp+1 }&qname=${qname }&qusername=${qusername}&qsex=${qsex}">下一页</a>&nbsp;&nbsp;
		<a href="queryByPage?currentPage=${pager.pageCounts }&qname=${qname }&qusername=${qusername}&qsex=${qsex}">末页</a>&nbsp;&nbsp;
	</div>

add布局以及请求

<body>
	<form action="add"method="post">
		姓名:<input type="text" name="name" ><br/>
		帐号:<input type="text" name="username" ><br/>
		密码:<input type="password" name="password" ><br/>
		性别:<input type="radio" name="sex" value="1" checked="checked">男
			<input type="radio" name="sex" value="0">女<br/>
		年龄:<input type="text" name="age" ><br/>
		出生日期:<input type="date" name="birthday" ><br/>
			<input type="submit" value="提交" ><br/>
	</form>
</body>

update布局以及请求

<body>
	<form action="update" method="post">
			<input type="hidden" name="id" value="${student.id }">
			<input type="hidden" name="currentPage" value="${currentPage }">
			<input type="hidden" name="qname" value="${qname }">
			<input type="hidden" name="qusername" value="${qusername }">
			<input type="hidden" name="qsex" value="${qsex }">
		姓名:<input type="text" name="name" value="${student.name }"><br/>
		帐号:<input type="text" name="username" value="${student.username }"><br/>
		密码:<input type="password" name="password" value="${student.password }"><br/>
		性别:<input type="radio" name="sex" value="1" <c:if test="${student.sex==1 }">checked="checked"</c:if>>男
			<input type="radio" name="sex" value="0" <c:if test="${student.sex==0 }">checked="checked"</c:if>>女<br/>
		年龄:<input type="text" name="age" value="${student.age }"><br/>
		出生日期:<input type="date" name="birthday" value="${student.birthday }"><br/>
			<input type="submit" value="提交"><br/>
	</form>
</body>

这里提供的是原生页面的显示,新增以及更新,为了更好的让刚刚接触了解springmvc和servlet的不同点,以及前台页面请求书写的不同,相比之下springmvc更加的简便,取值和传值都有很大的不同,当然,springmvc同样也可以使用原来servlet的取值传值方式,提供一个方法进行set,让其变为全局变量设置,然后其他的方法可以进行使用,以及对时间格式的处理

/*
	 * 处理时间格式
	 */
	@InitBinder
	public void initBinder(ServletRequestDataBinder binder) {
		binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
	}
/*
*request和response
*/
	@ModelAttribute
	public void setRequestAndResponse(HttpServletRequest request, HttpServletResponse response) {
		this.request = request;
		this.response = response;
		this.response.setContentType("text/html;charset=utf-8");
	}

项目整个结构相信大家都清楚了:
entity — Dao — controller 这是大部分刚接触的
但是为了控制层的清晰,我们可以加入另外一层:
entity — Dao — service — controller
将对象的操作在service层中进行处理,如果后面我放一些框架的小案例,我会以4层操作进行项目流程编写,这也是提供大家的一个建议。

这样与servlet进行对比,可以更加容易去理解,Dao层也是用基础的知识点,没有加入mybatis框架的使用,后续也会做一个mybatis和原生连接的原理和对比。

如果存在不好的地方,欢迎指出评论,谢谢~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值