分析一下,要想整合,那就要满足Spring中的IOC容器先加载Service,之后Spring MVC中的IOC容器加载Controller。这是因为加载Controller的前提是要获取Service中的Bean的自动装配。而Spring MVC中的IOC容器的初始化是在DispatcherServlet中,所以Service的加载必须在这之前。
各个组件初始化执行顺序:
监听器→过滤器→Servlet
所以自然想到,把获取Spring的IOC容器的方法放到监听器初始化中。
Spring提供了监听器ContextLoaderListener,实现ServletContextListener接口,可监听ServletContext的状态,在web服务器的启动,读取Spring的配置文件,创建Spring的IOC容器。
监听器常见的类型:
ServletContextListener:监听ServletContext的状态
HttpSessionListener:监听HttpSession的状态
HttpSessionAttributeListener:监听HttpSession的状
而看源码,ContextLoaderListener就是接口ServletContextListener的实现类。
public class ContextLoaderListener extends ContextLoader implements ServletContextListener {}
之后我们看initWebApplicationContext方法
往下拉继续看
web应用中必须在web.xml中来配置监听器。
org.springframework.web.context.ContextLoaderListener contextConfigLocation classpath:spring.xml
那我们先来看下监听器的应用
Name:spring-integration-listener
GroupId:com.atguigu
pom.xml配置打包形式
war
pom.xml剩下的依赖和之前的文件一样
org.springframework spring-webmvc 5.3.1 ch.qos.logback logback-classic 1.2.3 javax.servlet javax.servlet-api 3.1.0 provided org.thymeleaf thymeleaf-spring5 3.0.12.RELEASE
修改web.xml的路径
F:\javawebwork\SSM\spring-integration-listener\src\main\webapp\WEB-INF\web.xml
配置web.xml
CharacterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding UTF-8 forceEncoding true CharacterEncodingFilter /* HiddenHttpMethodFilter org.springframework.web.filter.HiddenHttpMethodFilter HiddenHttpMethodFilter /* DispatcherServlet org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:springmvc.xml 1 DispatcherServlet / contextConfigLocation classpath:spring.xml org.springframework.web.context.ContextLoaderListener
springmvc.xml拷贝之前的项目配置即可
创建spring.xml
配置扫描业务层组件,先自动装配Spring中的Service组件
创建控制层组件创建com.atguigu.controller.HelloController
package com.atguigu.controller;import com.atguigu.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;/*** @ClassName: HelloController* @Description:* @Author: wty* @Date: 2023/2/3*/
@Controller
public class HelloController {@Autowiredprivate HelloService helloService;
}
创建接口com.atguigu.service.HelloService
package com.atguigu.service;/*** @InterfaceName: HelloService* @Description:* @Author: wty* @Date: 2023/2/3*/public interface HelloService {
}
创建实现类HelloServiceImpl.java
package com.atguigu.service.impl;import com.atguigu.service.HelloService;/*** @ClassName: HelloServiceImpl* @Description:* @Author: wty* @Date: 2023/2/3*/
@Service
public class HelloServiceImpl implements HelloService {
}
创建首页index.html
首页
index.html
重新配置Tomcat
启动Tomcat,首页加载成功
这里如果我们把监听器的那段配置注释会怎么样呢?
注释掉web.xml的代码
这里注意2个配置文件的自动装配的范围不一样
重新启动Tomcat,直接报错,没有任何一个匹配的bean完成自动装配
这里我们不禁会问,为啥spring的ioc容器初始化和spring mvc的ioc容器初始化可以整合呢,我们看一下源代码。
FrameworkServlet.class
新建Module
Name:ssm
GroupId:com.atguigu.ssm
pom.xml中设置打包方式
war
pom.xml中继续配置
SSM org.example 1.0-SNAPSHOT 4.0.0 war com.atguigu.ssm ssm 8 8 5.3.1 org.springframework spring-context ${spring.version} org.springframework spring-beans ${spring.version} org.springframework spring-web ${spring.version} org.springframework spring-webmvc ${spring.version} org.springframework spring-jdbc ${spring.version} org.springframework spring-aspects ${spring.version} org.springframework spring-test ${spring.version} org.mybatis mybatis 3.5.7 org.mybatis mybatis-spring 2.0.6 com.alibaba druid 1.0.9 junit junit 4.12 test mysql mysql-connector-java 5.1.20 log4j log4j 1.2.17 com.github.pagehelper pagehelper 5.2.0 ch.qos.logback logback-classic 1.2.3 javax.servlet javax.servlet-api 3.1.0 provided com.fasterxml.jackson.core jackson-databind 2.12.1 commons-fileupload commons-fileupload 1.3.1 org.thymeleaf thymeleaf-spring5 3.0.12.RELEASE
建表语句如下:
CREATE TABLE `t_emp` (`emp_id` INT(11) NOT NULL AUTO_INCREMENT,`emp_name` VARCHAR(20) DEFAULT NULL,`age` INT(11) DEFAULT NULL,`gender` CHAR(1) DEFAULT NULL,`email` VARCHAR(50) DEFAULT NULL,PRIMARY KEY (`emp_id`)
) ENGINE=INNODB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8
配置web.xml
正确路径如下:
F:\javawebwork\SSM\ssm\src\main\webapp\WEB-INF\web.xml
web.xml文件配置如下
CharacterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding UTF-8 forceEncoding true CharacterEncodingFilter /* HiddenHttpMethodFilter org.springframework.web.filter.HiddenHttpMethodFilter HiddenHttpMethodFilter /* SpringMVC org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:springmvc.xml 1 SpringMVC / org.springframework.web.context.ContextLoaderListener contextConfigLocation classpath:spring.xml
创建springmvc.xml
error
在这里插入代码片
实体类Employee
com.atguigu.pojo.Employee
package com.atguigu.pojo;/*** @ClassName: Employee* @Description:* @Author: wty* @Date: 2023/2/3*/public class Employee {private Integer empId;private String empName;private Integer age;private String gender;private String email;public Employee() {}public Employee(Integer empId, String empName, Integer age, String gender, String email) {this.empId = empId;this.empName = empName;this.age = age;this.gender = gender;this.email = email;}public Integer getEmpId() {return empId;}public void setEmpId(Integer empId) {this.empId = empId;}public String getEmpName() {return empName;}public void setEmpName(String empName) {this.empName = empName;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}@Overridepublic String toString() {return "Employee{" +"empId=" + empId +", empName='" + empName + '\'' +", age=" + age +", gender='" + gender + '\'' +", email='" + email + '\'' +'}';}
}
创建控制层组件EmployeeController
com.atguigu.controller.EmployeeController
@Controller
public class EmployeeController {
}
创建接口EmployeeService
public interface EmployeeService {
}
创建实现类EmployeeServiceImpl
@Service
public class EmployeeServiceImpl implements EmployeeService {
}
创建ExceptionController.java
// 将当前类标识为异常处理的组件
@ControllerAdvice
public class ExceptionController {// 设置要处理的异常信息@ExceptionHandler(ArithmeticException.class)// ex表示控制器方法出现的异常public ModelAndView handleException(Throwable ex) {ModelAndView mav = new ModelAndView();//向请求域共享数据mav.addObject("ex", ex);//设置视图,实现页面跳转mav.setViewName("error");return mav;}
}
创建首页index.html
首页
index.html
创建错误页面error.html
错误
error.html
部署Tomcat
配置重启设置
启动Tomcat看一下
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.username=root
jdbc.password=hsp
用模板创建即可
com.atguigu.mapper.EmployeeMapper
在这里插入代码片
创建映射文件ssm/src/main/resources/com/atguigu/mapper/EmployeeMapper.xml
修改spring.xml
增加代码
看一下SqlSessionFactoryBean的源码
public class SqlSessionFactoryBean implements FactoryBean, InitializingBean, ApplicationListener {}
其父类是
public interface FactoryBean {}
修改EmployeeServiceImpl.java
这里可以看到,可以从业务层直接调用SqlSessionFactory进行装配,当然这里了解一下即可,我们最终的实现方案比这个简单。
@Service
public class EmployeeServiceImpl implements EmployeeService {@Autowiredprivate SqlSessionFactory sqlSessionFactory;
}
删除这段代码即可
继续修改spring.xml,加上数据源的引用
mybatis-config.xml中关于数据源的配置就可以删除了
继续配置spring.xml
配置类型别名的包
那么mybatis-config.xml对别名的配置可以删除了
修改spring.xml
这个设置时,映射文件对应的包和mapper接口对应的包不一致的时候才配置。
配置如下:
删除mybatis-config.xml的配置
当然这里只是演示一下不一样的情况,spring.xml还是注释掉
在mybatis-config.xml中配置分页插件
当然在spring.xml也可以配置(这里看一下如何配置即可,注释掉)
注释掉
现在mybatis-config.xml只剩下
继续配置spring.xml
把bean配置的所有Mapper接口,通过SqlSessionFactory创建的sqlSession创建代理实现类对象,并将这些对象交给IOC容器管理。
在spring.xml中配置
开启事务注解驱动,要注意选择tx结尾的。
修改EmployeeServiceImpl.java
@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService {
}
拷贝static
修改com.atguigu.controller
@Controller
public class EmployeeController {@Autowiredprivate EmployeeService employeeService;@RequestMapping(value = "/employee", method = RequestMethod.GET)public String getAllEmployee(ModelMap map) {// 查询所有的员工信息List list = employeeService.getAllEmployee();// 在请求域中共享map.addAttribute("list", list);// 跳转界面return "employee_list";}
}
修改EmployeeService.java
public interface EmployeeService {/*** @param* @return java.util.List* @description //查询所有员工信息* @date 2023/2/3 13:32* @author wty**/List getAllEmployee();
}
修改EmployeeServiceImpl.java
@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService {@Autowiredprivate EmployeeMapper employeeMapper;@Overridepublic List getAllEmployee() {return employeeMapper.getAllEmployee();}
}
修改EmployeeMapper.java
public interface EmployeeMapper {/*** @param* @return java.util.List* @description //查询所有员工* @date 2023/2/3 13:35* @author wty**/List getAllEmployee();
}
修改EmployeeMapper.xml
创建employee_list.html
员工列表
看一下target中没有加载static
执行后点击package
修改index.html
首页
index.html
查询员工信息
之后部署Tomcat
点击查询员工信息
修改主页index.html,增加分页的入口
查询员工信息(分页)
修改EmployeeController.java
@RequestMapping(value = "/employee/page/{pageNum}", method = RequestMethod.GET)public String getEmployeePage(Map map, @PathVariable("pageNum") Integer pageNum) {// 获取员工的分页信息PageInfo pageInfo = employeeService.getEmployeePage(pageNum);// 在请求域中共享map.put("pageInfo", pageInfo);// 跳转界面return "employee_list_page";}
修改EmployeeService.java
/*** @param* @return com.github.pagehelper.PageInfo* @description //查询所有员工信息(分页)* @param: pageNum* @date 2023/2/3 14:21* @author wty**/PageInfo getEmployeePage(Integer pageNum);
修改EmployeeServiceImpl.java
@Overridepublic PageInfo getEmployeePage(Integer pageNum) {// 开启分页功能,2个参数是当前页页码pageNum以及每页的条数6Page
修改employee_list_page.html
员工列表(分页)
重新部署Tomcat
点击超链接后跳转
更改地址,可以实现页面的跳转
http://localhost:8080/ssm/employee/page/2
这种方式明显是不可取的,我们不能让用户手动输入。
那我们需要修改employee_list_page.html
员工列表(分页)
重新部署Tomcat,看第二页即可
设置导航分页employee_list_page.html
重新部署
为当前选定页改变样式,修改employee_list_page.html
重新部署Tomcat
后续完善添加和删除还有修改功能
员工列表中添加超链接跳转
employee_list_page.html
操作(+)
修改springmvc.xml增加跳转添加的页面
新增添加员工的页面employee_add.html
添加员工
修改EmployeeController.java
添加方法
@RequestMapping(value = "/employee", method = RequestMethod.POST)public String insertEmployee(Employee employee) {// 保存员工的信息employeeService.insertEmployee(employee);return "redirect:/employee/page/1";}
修改EmployeeService.java,增加方法
/*** @param* @return int* @description //添加员工信息* @param: employee* @date 2023/2/3 16:02* @author wty**/int insertEmployee(Employee employee);
修改EmployeeServiceImpl.java增加方法
@Overridepublic int insertEmployee(Employee employee) {return employeeMapper.insertEmployee(employee);}
修改EmployeeMapper.java,增加方法
/*** @param* @return int* @description //保存员工信息* @param: employee* @date 2023/2/3 16:01* @author wty**/int insertEmployee(Employee employee);
修改EmployeeMapper.xml
insert into t_empvalues (null, #{empName}, #{age}, #{gender}, #{email})
最后部署Tomcat
单击+的超链接跳转
跳转后输入信息
最后点击添加,跳转后,发现添加成功
修改employee_list_page.html
修改增加超链接
修改
修改EmployeeController.java增加跳转页面
@RequestMapping(value = "/employee/{empId}", method = RequestMethod.GET)public String toUpdateEmployee(ModelMap map, @PathVariable("empId") Integer empId) {// 获取员工的分页信息Employee employee = employeeService.getEmployeeByEmpId(empId);// 在请求域中共享map.put("employeeUpdate", employee);// 跳转界面return "employee_update";}
新增界面employee_update.html
添加员工
修改EmployeeController.java增加修改提交
@RequestMapping(value = "/employee", method = RequestMethod.PUT)public String updateEmployee(Employee employee) {// 修改员工信息employeeService.updateEmployee(employee);// 跳转界面return "redirect:/employee/page/1";}
部署Tomcat
点击之后跳转
修改之后
修改employee_list_page.html
增加删除的超链接
删除
增加form表单
employee_list_page.html
引入vue
修改EmployeeController.java
@RequestMapping(value = "/employee/{empId}", method = RequestMethod.DELETE)public String deleteEmployee(@PathVariable("empId") Integer empId) {// 修改员工信息employeeService.deleteEmployeeByEmpId(empId);// 跳转界面return "redirect:/employee/page/1";}
修改EmployeeService.java
/*** @param* @return int* @description //根据员工ID删除员工信息* @param: empId* @date 2023/2/3 17:32* @author wty**/int deleteEmployeeByEmpId(Integer empId);
修改EmployeeServiceImpl.java
@Overridepublic int deleteEmployeeByEmpId(Integer empId) {return employeeMapper.deleteEmployeeByEmpId(empId);}
修改EmployeeMapper.java
/*** @param* @return int* @description //根据员工ID删除员工信息* @param: empId* @date 2023/2/3 17:33* @author wty**/int deleteEmployeeByEmpId(Integer empId);
修改EmployeeMapper.xml
deletefrom t_empwhere emp_id = #{empId}
重新部署Tomcat
点击删除后,弹出对话框
点击确定后,删除
至此所有功能写完,这里附上项目结构
前台界面如下
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.username=root
jdbc.password=hsp
error
首页
index.html
查询员工信息
查询员工信息(分页)
添加员工
员工列表
员工列表(分页)
修改员工信息
错误
error.html
package com.atguigu.controller;import com.atguigu.pojo.Employee;
import com.atguigu.service.EmployeeService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;import java.util.List;
import java.util.Map;/*** @ClassName: EmployeeController* @Description: 查询所有员工的信息-->/employee-->GET* 更改成分页后:查询所有员工的信息-->/employee/page/1-->GET* 根据id查询某个员工的信息-->/employee/id-->GET* 跳转到添加界面-->/to/add-->GET* 添加员工信息-->/employee-->POST* 修改员工的信息-->/employee-->PUT* 删除员工的信息-->/employee/1-->DELETE* @Author: wty* @Date: 2023/2/3*/
@Controller
public class EmployeeController {@Autowiredprivate EmployeeService employeeService;@RequestMapping(value = "/employee", method = RequestMethod.GET)public String getAllEmployee(ModelMap map) {// 查询所有的员工信息List list = employeeService.getAllEmployee();// 在请求域中共享map.addAttribute("list", list);// 跳转界面return "employee_list";}@RequestMapping(value = "/employee/page/{pageNum}", method = RequestMethod.GET)public String getEmployeePage(Map map, @PathVariable("pageNum") Integer pageNum) {// 获取员工的分页信息PageInfo pageInfo = employeeService.getEmployeePage(pageNum);// 在请求域中共享map.put("pageInfo", pageInfo);// 跳转界面return "employee_list_page";}@RequestMapping(value = "/employee", method = RequestMethod.POST)public String insertEmployee(Employee employee) {// 保存员工的信息employeeService.insertEmployee(employee);return "redirect:/employee/page/1";}@RequestMapping(value = "/employee/{empId}", method = RequestMethod.GET)public String toUpdateEmployee(ModelMap map, @PathVariable("empId") Integer empId) {// 获取员工的分页信息Employee employee = employeeService.getEmployeeByEmpId(empId);// 在请求域中共享map.put("employeeUpdate", employee);// 跳转界面return "employee_update";}@RequestMapping(value = "/employee", method = RequestMethod.PUT)public String updateEmployee(Employee employee) {// 修改员工信息employeeService.updateEmployee(employee);// 跳转界面return "redirect:/employee/page/1";}@RequestMapping(value = "/employee/{empId}", method = RequestMethod.DELETE)public String deleteEmployee(@PathVariable("empId") Integer empId) {// 修改员工信息employeeService.deleteEmployeeByEmpId(empId);// 跳转界面return "redirect:/employee/page/1";}
}
package com.atguigu.controller;import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;/*** @ClassName: ExceptionController* @Description:* @Author: wty* @Date: 2023/2/3*/
// 将当前类标识为异常处理的组件
@ControllerAdvice
public class ExceptionController {// 设置要处理的异常信息@ExceptionHandler(ArithmeticException.class)// ex表示控制器方法出现的异常public ModelAndView handleException(Throwable ex) {ModelAndView mav = new ModelAndView();//向请求域共享数据mav.addObject("ex", ex);//设置视图,实现页面跳转mav.setViewName("error");return mav;}
}
package com.atguigu.interceptor;import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** @ClassName: FirstInterceptor* @Description:* @Author: wty* @Date: 2023/2/3*/
@Component
public class FirstInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("FirstInterceptor.preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("FirstInterceptor.postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("FirstInterceptor.afterCompletion");}
}
package com.atguigu.mapper;import com.atguigu.pojo.Employee;
import com.github.pagehelper.PageInfo;import java.util.List;/*** @InterfaceName: EmployeeMapper* @Description:* @Author: wty* @Date: 2023/2/3*/public interface EmployeeMapper {/*** @param* @return java.util.List* @description //查询所有员工* @date 2023/2/3 13:35* @author wty**/List getAllEmployee();/*** @param* @return int* @description //保存员工信息* @param: employee* @date 2023/2/3 16:01* @author wty**/int insertEmployee(Employee employee);/*** @param* @return com.atguigu.pojo.Employee* @description //根据EmpId获取员工信息* @param: empId* @date 2023/2/3 16:38* @author wty**/Employee getEmployeeByEmpId(Integer empId);/*** @param* @return int* @description //更新员工信息* @param: employee* @date 2023/2/3 17:01* @author wty**/int updateEmployee(Employee employee);/*** @param* @return int* @description //根据员工ID删除员工信息* @param: empId* @date 2023/2/3 17:33* @author wty**/int deleteEmployeeByEmpId(Integer empId);
}
package com.atguigu.pojo;/*** @ClassName: Employee* @Description:* @Author: wty* @Date: 2023/2/3*/public class Employee {private Integer empId;private String empName;private Integer age;// 1:男,0女private String gender;private String email;public Employee() {}public Employee(Integer empId, String empName, Integer age, String gender, String email) {this.empId = empId;this.empName = empName;this.age = age;this.gender = gender;this.email = email;}public Integer getEmpId() {return empId;}public void setEmpId(Integer empId) {this.empId = empId;}public String getEmpName() {return empName;}public void setEmpName(String empName) {this.empName = empName;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}@Overridepublic String toString() {return "Employee{" +"empId=" + empId +", empName='" + empName + '\'' +", age=" + age +", gender='" + gender + '\'' +", email='" + email + '\'' +'}';}
}
package com.atguigu.service.impl;import com.atguigu.mapper.EmployeeMapper;
import com.atguigu.pojo.Employee;
import com.atguigu.service.EmployeeService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;/*** @ClassName: EmployeeImpl* @Description:* @Author: wty* @Date: 2023/2/3*/
@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService {@Autowiredprivate EmployeeMapper employeeMapper;@Overridepublic List getAllEmployee() {return employeeMapper.getAllEmployee();}@Overridepublic PageInfo getEmployeePage(Integer pageNum) {// 开启分页功能,2个参数是当前页页码pageNum以及每页的条数6Page
package com.atguigu.service;import com.atguigu.pojo.Employee;
import com.github.pagehelper.PageInfo;import java.util.List;/*** @InterfaceName: EmployeeService* @Description:* @Author: wty* @Date: 2023/2/3*/public interface EmployeeService {/*** @param* @return java.util.List* @description //查询所有员工信息* @date 2023/2/3 13:32* @author wty**/List getAllEmployee();/*** @param* @return com.github.pagehelper.PageInfo* @description //查询所有员工信息(分页)* @param: pageNum* @date 2023/2/3 14:21* @author wty**/PageInfo getEmployeePage(Integer pageNum);/*** @param* @return int* @description //添加员工信息* @param: employee* @date 2023/2/3 16:02* @author wty**/int insertEmployee(Employee employee);/*** @param* @return com.atguigu.pojo.Employee* @description //根据EmpId获取员工信息* @param: empId* @date 2023/2/3 16:37* @author wty**/Employee getEmployeeByEmpId(Integer empId);/*** @param* @return int* @description //更新员工信息* @param: employee* @date 2023/2/3 17:00* @author wty**/int updateEmployee(Employee employee);/*** @param* @return int* @description //根据员工ID删除员工信息* @param: empId* @date 2023/2/3 17:32* @author wty**/int deleteEmployeeByEmpId(Integer empId);}
上一篇:热门API接口它来啦 新鲜出炉
下一篇:Linux常见指令大全(二)