Java分页技术(二)
来源:互联网 发布:2015西安行知中学官网 编辑:程序博客网 时间:2024/06/18 14:20
演示结果:
(一)项目组成结构示意图
(二)创建包
1.com,imooc.page
package com.imooc.page;public class Constant { public static final int GENDER_MALE = 1; public static final int GENDER_FEMALE = 2; public static final int DEFAULT_PAGE_SIZE = 5; public static final int DEFAULT_PAGE_NUM = 1; public static final int DEFAULT_GENDER = 0;}package com.imooc.page;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;public class EncodingFilter implements Filter { @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); chain.doFilter(request,response); } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub }}
2.com,imooc.page.dao
package com.imooc.page.dao;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;import java.util.Map;import com.imooc.page.Constant;import com.imooc.page.model.Pager;import com.imooc.page.model.Student;import com.imooc.page.util.JdbcUtil;public class JdbcSqlStudentDaoImpl implements StudentDao { @Override public Pager<Student> findStudent(Student searchModel, int pageNum, int pageSize) { Pager<Student> result = null; // 瀛樻斁鏌ヨ鍙傛暟 List<Object> paramList = new ArrayList<Object>(); String stuName = searchModel.getStuName(); int gender = searchModel.getGender(); StringBuilder sql = new StringBuilder( "select * from t_student where 1=1"); StringBuilder countSql = new StringBuilder( "select count(id) as totalRecord from t_student where 1=1 "); if (stuName != null && !stuName.equals("")) { sql.append(" and stu_name like ?"); countSql.append(" and stu_name like ?"); paramList.add("%" + stuName + "%"); } if (gender == Constant.GENDER_FEMALE || gender == Constant.GENDER_MALE) { sql.append(" and gender = ?"); countSql.append(" and gender = ?"); paramList.add(gender); } int fromIndex = pageSize * (pageNum -1); sql.append(" limit " + fromIndex + ", " + pageSize ); List<Student> studentList = new ArrayList<Student>(); JdbcUtil jdbcUtil = null; try { jdbcUtil = new JdbcUtil(); jdbcUtil.getConnection(); List<Map<String, Object>> countResult = jdbcUtil.findResult(countSql.toString(), paramList); Map<String, Object> countMap = countResult.get(0); int totalRecord = ((Number)countMap.get("totalRecord")).intValue(); List<Map<String, Object>> studentResult = jdbcUtil.findResult(sql.toString(), paramList); if (studentResult != null) { for (Map<String, Object> map : studentResult) { Student s = new Student(map); studentList.add(s); } } int totalPage = totalRecord / pageSize; if(totalRecord % pageSize !=0){ totalPage++; } result = new Pager<Student>(pageSize, pageNum, totalRecord, totalPage, studentList); } catch (SQLException e) { } finally { if (jdbcUtil != null) { jdbcUtil.releaseConn(); } } return result; }}----------package com.imooc.page.dao;import com.imooc.page.model.Pager;import com.imooc.page.model.Student;public interface StudentDao { public Pager<Student> findStudent(Student searchModel, int pageNum, int pageSize);}----------package com.imooc.page.dao;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;import java.util.Map;import com.imooc.page.Constant;import com.imooc.page.model.Pager;import com.imooc.page.model.Student;import com.imooc.page.util.JdbcUtil;public class SublistStudentDaoImpl implements StudentDao { @Override public Pager<Student> findStudent(Student searchModel, int pageNum, int pageSize) { List<Student> allStudenList = getAllStudent(searchModel); Pager<Student> pager = new Pager<Student>(pageNum, pageSize, allStudenList); return pager; } private static List<Student> getAllStudent(Student searchModel) { List<Student> result = new ArrayList<Student>(); List<Object> paramList = new ArrayList<Object>(); String stuName = searchModel.getStuName(); int gender = searchModel.getGender(); StringBuilder sql = new StringBuilder( "select * from t_student where 1=1"); if (stuName != null && !stuName.equals("")) { sql.append(" and stu_name like ?"); paramList.add("%" + stuName + "%"); } if (gender == Constant.GENDER_FEMALE || gender == Constant.GENDER_MALE) { sql.append(" and gender = ?"); paramList.add(gender); } JdbcUtil jdbcUtil = null; try { jdbcUtil = new JdbcUtil(); jdbcUtil.getConnection(); List<Map<String, Object>> mapList = jdbcUtil.findResult( sql.toString(), paramList); if (mapList != null) { for (Map<String, Object> map : mapList) { Student s = new Student(map); result.add(s); } } } catch (SQLException e) { } finally { if (jdbcUtil != null) { jdbcUtil.releaseConn(); } } return result; } public static void main(String[] args) { List<Student> lst = getAllStudent(new Student()); for (Student s : lst) { System.out.println(s); } }}
3.com,imooc.page.model
package com.imooc.page.model;import java.io.Serializable;import java.util.List;public class Pager<T> implements Serializable { private static final long serialVersionUID = -8741766802354222579L; private int pageSize; private int currentPage; private int totalRecord; private int totalPage; private List<T> dataList; public Pager(int pageNum, int pageSize, List<T> sourceList){ if(sourceList == null || sourceList.isEmpty()){ return; } this.totalRecord = sourceList.size(); this.pageSize = pageSize; this.totalPage = this.totalRecord / this.pageSize; if(this.totalRecord % this.pageSize !=0){ this.totalPage = this.totalPage + 1; } this.currentPage = this.totalPage < pageNum ? this.totalPage : pageNum; int fromIndex = this.pageSize * (this.currentPage -1); int toIndex = this.pageSize * this.currentPage > this.totalRecord ? this.totalRecord : this.pageSize * this.currentPage; this.dataList = sourceList.subList(fromIndex, toIndex); } public Pager(){ } public Pager(int pageSize, int currentPage, int totalRecord, int totalPage, List<T> dataList) { super(); this.pageSize = pageSize; this.currentPage = currentPage; this.totalRecord = totalRecord; this.totalPage = totalPage; this.dataList = dataList; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getTotalRecord() { return totalRecord; } public void setTotalRecord(int totalRecord) { this.totalRecord = totalRecord; } public int getTotalPage() { return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public List<T> getDataList() { return dataList; } public void setDataList(List<T> dataList) { this.dataList = dataList; }}----------package com.imooc.page.model;import java.io.Serializable;import java.util.Map;public class Student implements Serializable { private static final long serialVersionUID = -7476381137287496245L; private int id; private String stuName; private int age; private int gender; private String address; public Student() { super(); } public Student(int id, String stuName, int age, int gender, String address) { super(); this.id = id; this.stuName = stuName; this.age = age; this.gender = gender; this.address = address; } public Student(Map<String, Object> map){ this.id = (int)map.get("id"); this.stuName = (String)map.get("stu_name"); this.age = (int)map.get("age"); this.gender = (int)map.get("gender"); this.address = (String)map.get("address"); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getGender() { return gender; } public void setGender(int gender) { this.gender = gender; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Student [id=" + id + ", stuName=" + stuName + ", age=" + age + ", gender=" + gender + ", address=" + address + "]"; }}
4.com.imooc.page.service
package com.imooc.page.service;import com.imooc.page.dao.JdbcSqlStudentDaoImpl;import com.imooc.page.dao.StudentDao;import com.imooc.page.model.Pager;import com.imooc.page.model.Student;public class JdbcSqlStudentServiceImpl implements StudentService { private StudentDao studentDao; public JdbcSqlStudentServiceImpl(){ studentDao = new JdbcSqlStudentDaoImpl(); } @Override public Pager<Student> findStudent(Student searchModel, int pageNum, int pageSize) { Pager<Student> result = studentDao.findStudent(searchModel, pageNum, pageSize); return result; }}----------package com.imooc.page.service;import com.imooc.page.model.Pager;import com.imooc.page.model.Student;public interface StudentService { public Pager<Student> findStudent(Student searchModel, int pageNum, int pageSize);}----------package com.imooc.page.service;import com.imooc.page.dao.StudentDao;import com.imooc.page.dao.SublistStudentDaoImpl;import com.imooc.page.model.Pager;import com.imooc.page.model.Student;public class SublistStudentServiceImpl implements StudentService { private StudentDao studentDao; public SublistStudentServiceImpl() { studentDao = new SublistStudentDaoImpl(); } @Override public Pager<Student> findStudent(Student searchModel, int pageNum, int pageSize) { Pager<Student> result = studentDao.findStudent(searchModel, pageNum, pageSize); return result; } public StudentDao getStudentDao() { return studentDao; } public void setStudentDao(StudentDao studentDao) { this.studentDao = studentDao; }}
5.com.imooc.page.servlet
package com.imooc.page.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.imooc.page.Constant;import com.imooc.page.model.Pager;import com.imooc.page.model.Student;import com.imooc.page.service.JdbcSqlStudentServiceImpl;import com.imooc.page.service.StudentService;import com.imooc.page.util.StringUtil;public class JdbcSqlServlet extends HttpServlet { private static final long serialVersionUID = -318134993070614515L; private StudentService studentService = new JdbcSqlStudentServiceImpl(); public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String stuName = request.getParameter("stuName"); int gender = Constant.DEFAULT_GENDER; String genderStr = request.getParameter("gender"); if(genderStr!=null && !"".equals(genderStr.trim())){ gender = Integer.parseInt(genderStr); } String pageNumStr = request.getParameter("pageNum"); if(pageNumStr !=null && !StringUtil.isNum(pageNumStr)){ request.setAttribute("errorMsg", "鍙傛暟浼犺緭閿欒"); request.getRequestDispatcher("jdbcSqlStudent.jsp").forward(request, response); return; } int pageNum = Constant.DEFAULT_PAGE_NUM; if(pageNumStr!=null && !"".equals(pageNumStr.trim())){ pageNum = Integer.parseInt(pageNumStr); } int pageSize = Constant.DEFAULT_PAGE_SIZE; String pageSizeStr = request.getParameter("pageSize"); if(pageSizeStr!=null && !"".equals(pageSizeStr.trim())){ pageSize = Integer.parseInt(pageSizeStr); } Student searchModel = new Student(); searchModel.setStuName(stuName); searchModel.setGender(gender); Pager<Student> result = studentService.findStudent(searchModel, pageNum, pageSize); request.setAttribute("result", result); request.setAttribute("stuName", stuName); request.setAttribute("gender", gender); request.getRequestDispatcher("jdbcSqlStudent.jsp").forward(request, response); }}----------package com.imooc.page.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.imooc.page.Constant;import com.imooc.page.model.Pager;import com.imooc.page.model.Student;import com.imooc.page.service.StudentService;import com.imooc.page.service.SublistStudentServiceImpl;import com.imooc.page.util.StringUtil;public class SublistServlet extends HttpServlet { private static final long serialVersionUID = -3658128508633145268L; private StudentService studentService = new SublistStudentServiceImpl(); public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String stuName = request.getParameter("stuName"); int gender = Constant.DEFAULT_GENDER; String genderStr = request.getParameter("gender"); if(genderStr!=null && !"".equals(genderStr.trim())){ gender = Integer.parseInt(genderStr); } String pageNumStr = request.getParameter("pageNum"); if(pageNumStr !=null && !StringUtil.isNum(pageNumStr)){ request.setAttribute("errorMsg", "鍙傛暟浼犺緭閿欒"); request.getRequestDispatcher("sublistStudent.jsp").forward(request, response); return; } int pageNum = Constant.DEFAULT_PAGE_NUM; if(pageNumStr!=null && !"".equals(pageNumStr.trim())){ pageNum = Integer.parseInt(pageNumStr); } int pageSize = Constant.DEFAULT_PAGE_SIZE; String pageSizeStr = request.getParameter("pageSize"); if(pageSizeStr!=null && !"".equals(pageSizeStr.trim())){ pageSize = Integer.parseInt(pageSizeStr); } Student searchModel = new Student(); searchModel.setStuName(stuName); searchModel.setGender(gender); Pager<Student> result = studentService.findStudent(searchModel, pageNum, pageSize); request.setAttribute("result", result); request.setAttribute("stuName", stuName); request.setAttribute("gender", gender); request.getRequestDispatcher("sublistStudent.jsp").forward(request, response); }}
6.com.imooc.util
package com.imooc.page.util;import java.io.InputStream;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Properties;public class JdbcUtil { private static String USERNAME ; private static String PASSWORD; private static String DRIVER; private static String URL; private Connection connection; private PreparedStatement pstmt; private ResultSet resultSet; static{ loadConfig(); } public static void loadConfig() { try { InputStream inStream = JdbcUtil.class .getResourceAsStream("/jdbc.properties"); Properties prop = new Properties(); prop.load(inStream); USERNAME = prop.getProperty("jdbc.username"); PASSWORD = prop.getProperty("jdbc.password"); DRIVER= prop.getProperty("jdbc.driver"); URL = prop.getProperty("jdbc.url"); } catch (Exception e) { throw new RuntimeException("璇诲彇鏁版嵁搴撻厤缃枃浠跺紓甯革紒", e); } } public JdbcUtil() { } public Connection getConnection() { try { Class.forName(DRIVER); connection = DriverManager.getConnection(URL, USERNAME, PASSWORD); } catch (Exception e) { throw new RuntimeException("get connection error!", e); } return connection; } public boolean updateByPreparedStatement(String sql, List<?> params) throws SQLException { boolean flag = false; int result = -1; pstmt = connection.prepareStatement(sql); int index = 1; if (params != null && !params.isEmpty()) { for (int i = 0; i < params.size(); i++) { pstmt.setObject(index++, params.get(i)); } } result = pstmt.executeUpdate(); flag = result > 0 ? true : false; return flag; } public List<Map<String, Object>> findResult(String sql, List<?> params) throws SQLException { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); int index = 1; pstmt = connection.prepareStatement(sql); if (params != null && !params.isEmpty()) { for (int i = 0; i < params.size(); i++) { pstmt.setObject(index++, params.get(i)); } } resultSet = pstmt.executeQuery(); ResultSetMetaData metaData = resultSet.getMetaData(); int cols_len = metaData.getColumnCount(); while (resultSet.next()) { Map<String, Object> map = new HashMap<String, Object>(); for (int i = 0; i < cols_len; i++) { String cols_name = metaData.getColumnName(i + 1); Object cols_value = resultSet.getObject(cols_name); if (cols_value == null) { cols_value = ""; } map.put(cols_name, cols_value); } list.add(map); } return list; } public void releaseConn() { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if (pstmt != null) { try { pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } public static void main(String[] args) { JdbcUtil jdbcUtil = new JdbcUtil(); jdbcUtil.getConnection(); try { List<Map<String, Object>> result = jdbcUtil.findResult( "select * from t_student", null); for (Map<String, Object> m : result) { System.out.println(m); } } catch (SQLException e) { e.printStackTrace(); } finally { jdbcUtil.releaseConn(); } }}----------package com.imooc.page.util;import java.util.regex.Matcher;import java.util.regex.Pattern;public class StringUtil { public static boolean isNum(String string){ Pattern pattern = Pattern.compile("[1-9]{1}\\d*"); Matcher matcher = pattern.matcher(string); return matcher.matches(); }}
(三)配置文件jdbc.properties
jdbc.username=rootjdbc.password=rootjdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://127.0.0.1:3306/imooc
(四)WebContext下的文件
1.paginationcss
.pagination { font-size: 80%; }.pagination a { text-decoration: none; border: solid 1px #AAE; color: #15B;}.pagination a, .pagination span { display: block; float: left; padding: 0.3em 0.5em; margin-right: 5px; margin-bottom: 5px; min-width:1em; text-align:center;}.pagination .current { background: #26B; color: #fff; border: solid 1px #AAE;}.pagination .current.prev, .pagination .current.next{ color:#999; border-color:#999; background:#fff;}
2.JdbcSqlStudent.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"><%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>学生信息</title></head><% // 获取请求的上下文 String context = request.getContextPath();%><link href="../css/pagination.css" rel="stylesheet" type="text/css"/><script type="text/javascript" src="../js/jquery-1.11.3.js"></script><script type="text/javascript" src="../js/jquery.pagination.js"></script><script type="text/javascript">// 点击分页按钮以后触发的动作function handlePaginationClick(new_page_index, pagination_container) { $("#stuForm").attr("action", "<%=context %>/jdbcSql/JdbcSqlServlet?pageNum=" + (new_page_index+1)); $("#stuForm").submit(); return false;}$(function(){ $("#News-Pagination").pagination(${result.totalRecord}, { items_per_page:${result.pageSize}, // 每页显示多少条记录 current_page:${result.currentPage} - 1, // 当前显示第几页数据 num_display_entries:8, // 分页显示的条目数 next_text:"下一页", prev_text:"上一页", num_edge_entries:2, // 连接分页主体,显示的条目数 callback:handlePaginationClick }); // 设置学生默认性别 $("#gender").val("${gender}");});</script><body> <div style="margin-left: 100px; margin-top: 100px;"> <div> <font color="red">${errorMsg }</font> </div> <div> <form action="<%=context %>/jdbcSql/JdbcSqlServlet" id="stuForm" method="post"> 姓名 <input type="text" name="stuName" id="stu_name" style="width:120px" value="${stuName }"> 性别 <select name="gender" id="gender" style="width:80px"> <option value="0">全部</option> <option value="1">男</option> <option value="2">女</option> </select> <input type="submit" value="查询"> </form> </div> <br> 学生信息列表:<br> <br> <!-- 后台返回结果为空 --> <c:if test="${fn:length(result.dataList) eq 0 }"> <span>查询的结果不存在</span> </c:if> <!-- 后台返回结果不为空 --> <c:if test="${fn:length(result.dataList) gt 0 }"> <table border="1px" cellspacing="0px" style="border-collapse: collapse"> <thead> <tr height="30"> <th width="130">姓名</th> <th width="130">性别</th> <th width="130">年龄</th> <th width="190">家庭地址</th> </tr> </thead> <c:forEach items="${result.dataList }" var="student"> <tr> <td><c:out value="${student.stuName }"></c:out></td> <td> <c:if test="${ student.gender eq 1}">男</c:if> <c:if test="${ student.gender eq 2}">女</c:if> </td> <td><c:out value="${student.age }"></c:out></td> <td><c:out value="${student.address }"></c:out></td> </tr> </c:forEach> </table> <br> <div id="News-Pagination"></div> </c:if> </div></body></html>
3.web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>pager</display-name> <filter> <filter-name>EncodingFilter</filter-name> <filter-class>com.imooc.page.EncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>*</url-pattern> </filter-mapping> <servlet> <servlet-name>SublistServlet</servlet-name> <servlet-class>com.imooc.page.servlet.SublistServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>SublistServlet</servlet-name> <url-pattern>/sublist/SublistServlet</url-pattern> </servlet-mapping> <servlet> <servlet-name>JdbcSqlServlet</servlet-name> <servlet-class>com.imooc.page.servlet.JdbcSqlServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>JdbcSqlServlet</servlet-name> <url-pattern>/jdbcSql/JdbcSqlServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list></web-app>
4.index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> This is my JSP page. <br> </body></html>
阅读全文
0 0
- Java分页技术(二)
- JSP分页技术二
- java分页技术比较
- Java另一种分页技术
- java分页技术
- java分页技术
- Java中的分页技术
- java分页技术
- Java.Web - 分页技术
- Java分页技术
- java 分页技术
- Java web 分页技术
- java分页技术
- 浅谈Java分页技术
- java + struts2 分页技术
- Java分页技术
- java--分页技术(1)
- java--分页技术(2)
- Android 关于自定义View小知识
- 2017 ACM/ICPC Asia Regional Shenyang Online 1005 number number number (HDU6198)
- 一次给python2.7 升级到3.6.1的经历(linux下)
- 协同过滤算法之Apriori介绍
- Clang get started
- Java分页技术(二)
- 多线程的常用操作方法
- android中mvc,mvp,mvvm学习
- [Linux][gerrit]安装gerrit总结
- 安装了新版本的jdk,修改java_home后,jdk版本始终不变
- Java多线程之线程控制(2)
- 遇到msado15 与 dbdaoint.h 有定义冲突
- Python学习日志_2017-09-09
- Android---长时间在后台运行的定时任务