SSM整合(spring-springmvc-mybatis)之CRUD
概述:
加入功能:CRUD、分页、返回json、国际化
配置了访问静态文件;
配置了REST 风格的代码;
一、目录结构:
目录:
jar包说明:
spring核心jar包:
- commons-logging-1.2.jar
- spring-beans-5.3.10.jar
- spring-context-5.3.10.jar
- spring-core-5.3.10.jar
- spring-expression-5.3.10.jar
spring aop:
- spring-aop-5.3.10.jar
- spring-aspects-5.3.10.jar
springmvc jar包:
- spring-web-5.3.10.jar
- spring-webmvc-5.3.10.jar
spring 数据库交互jar包:
- spring-jdbc-5.3.10.jar
- spring-tx-5.3.10.jar
mybatis jar包:
- mybatis-3.5.9.jar
- mysql-connector-java-8.0.27 (1).jar
- log4j-1.2.17.jar
mybatis-spring 适配器包:
- mybatis-spring-1.3.2.jar
c3po:
- c3p0-0.9.5.5.jar
- mchange-commons-java-0.2.19.jar
jstl:
- standard.jar
- jstl.jar
jackson(目的是返回json):
- jackson-annotations-2.9.10.jar
- jackson-core-2.9.10.jar
- jsqlparser-4.3.jar
mybatis 分页:
- jsqlparser-4.3.jar
- pagehelper-5.3.0.jar
二、java源代码
实体类:
普通实体类可以继承通用类,通用类提供了分页所需要的字段;原因是mybatis分页插件pageHelper的使用,这里采用了参数对象分页 。所以需要在对象中提供分页字段,比如:pageNum、pageSize、orderBy;
通用类CommonEntity.java:
1 package ssm.entity; 2 3 public class CommonEntity { 4 private Integer pageNum; 5 private Integer pageSize; 6 private String orderBy = "id desc"; 7 8 public Integer getPageNum() { 9 return pageNum; 10 } 11 12 public void setPageNum(Integer pageNum) { 13 this.pageNum = pageNum; 14 } 15 16 public Integer getPageSize() { 17 return pageSize; 18 } 19 20 public void setPageSize(Integer pageSize) { 21 this.pageSize = pageSize; 22 } 23 24 public String getOrderBy() { 25 return orderBy; 26 } 27 28 public void setOrderBy(String orderBy) { 29 this.orderBy = orderBy; 30 } 31 32 }
实体类:Employee.java:
package ssm.entity; public class Employee extends CommonEntity { private Integer id; private String lastName; private String email; private String gender; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } @Override public String toString() { return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + "]"; } }
Controller部分:
1 package ssm.controller; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.stereotype.Controller; 5 import org.springframework.web.bind.annotation.PathVariable; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 import org.springframework.web.bind.annotation.RequestMethod; 8 import org.springframework.web.bind.annotation.ResponseBody; 9 import org.springframework.web.servlet.ModelAndView; 10 11 import com.github.pagehelper.PageInfo; 12 13 import ssm.entity.Employee; 14 import ssm.service.EmployeeService; 15 16 /** 17 * @author lixiuming 18 * @Description 19 * @Date 2022年3月29日下午3:38:06 20 */ 21 @RequestMapping("/emp") 22 @Controller 23 public class EmployeeController { 24 @Autowired 25 private EmployeeService employeeService; 26 27 /** 28 * 列表页面 29 * 30 * @param employee 31 * @return 32 */ 33 @RequestMapping("/list") 34 public ModelAndView list(Employee employee) { 35 ModelAndView mv = new ModelAndView("index"); 36 PageInfo<Employee> list = employeeService.list(employee); 37 mv.addObject("pages", list); 38 return mv; 39 } 40 41 /** 42 * 添加页面 43 * 44 * @return 45 */ 46 @RequestMapping("/add") 47 public ModelAndView add() { 48 ModelAndView mv = new ModelAndView("update"); 49 return mv; 50 } 51 52 /** 53 * 编辑页面 54 * 55 * @param id 56 * @return 57 */ 58 @RequestMapping(value = "/edit/{id}") 59 public ModelAndView edit(@PathVariable(name = "id", required = false) Integer id) { 60 Employee employee = employeeService.getEmpById(id); 61 ModelAndView mv = new ModelAndView("update"); 62 mv.addObject("employee", employee); 63 return mv; 64 } 65 66 /** 67 * 添加/编辑 68 * 69 * @param employee 70 * @return 71 */ 72 @ResponseBody 73 @RequestMapping(value = "/update", method = RequestMethod.POST) 74 public String update(Employee employee) { 75 System.out.println(employee); 76 return employeeService.update(employee); 77 } 78 79 /** 80 * 详情 81 * 82 * @param id 83 * @return 84 */ 85 @ResponseBody 86 @RequestMapping(value = "/detail", method = RequestMethod.POST) 87 public Employee update(Integer id) { 88 return employeeService.getEmpById(id); 89 } 90 91 }
Service部分:
service接口:
1 package ssm.service; 2 3 import com.github.pagehelper.PageInfo; 4 5 import ssm.entity.Employee; 6 7 /** 8 * 9 * @author lixiuming 10 * @Description 11 * @Date 2022年3月29日下午3:46:33 12 */ 13 public interface EmployeeService { 14 15 /** 16 * 根据ID获取实体 17 * 18 * @param id 19 * @return 20 */ 21 Employee getEmpById(Integer id); 22 23 /** 24 * 获取列表页面 25 * 26 * @param employee 27 * @return 28 */ 29 PageInfo<Employee> list(Employee employee); 30 31 /** 32 * 添加/修改 33 * 34 * @param employee 35 * @return 36 */ 37 String update(Employee employee); 38 39 }
serviceImple实现类:
1 package ssm.service; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.stereotype.Service; 5 6 import com.github.pagehelper.PageInfo; 7 8 import ssm.entity.Employee; 9 import ssm.mapper.EmployeeMapper; 10 11 @Service("employeeService") 12 public class EmployeeServiceImpl implements EmployeeService { 13 14 @Autowired 15 private EmployeeMapper employeeMapper; 16 17 @Override 18 public Employee getEmpById(Integer id) { 19 return employeeMapper.getEmpById(id); 20 } 21 22 @Override 23 public PageInfo<Employee> list(Employee employee) { 24 return employeeMapper.list(employee); 25 } 26 27 @Override 28 public String update(Employee employee) { 29 if (employee.getId() != null && employee.getId() > 0) { 30 employeeMapper.update(employee); 31 } else { 32 employeeMapper.insert(employee); 33 } 34 return "200"; 35 } 36 37 }
Mapper部分:
1 package ssm.mapper; 2 3 import com.github.pagehelper.PageInfo; 4 5 import ssm.entity.Employee; 6 7 /** 8 * 9 * @author lixiuming 10 * @Description 11 * @Date 2022年3月29日下午3:48:45 12 */ 13 public interface EmployeeMapper { 14 15 /** 16 * 根据id 获取 实体对象 17 * 18 * @param id 19 * @return 20 */ 21 Employee getEmpById(Integer id); 22 23 /** 24 * 获取页面 25 * 26 * @param employee 27 * @return 28 */ 29 PageInfo<Employee> list(Employee employee); 30 31 /** 32 * 插入数据 33 * 34 * @param employee 35 */ 36 void insert(Employee employee); 37 38 /** 39 * 修改 40 * 41 * @param employee 42 */ 43 void update(Employee employee); 44 }
sql语句:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 <mapper namespace="ssm.mapper.EmployeeMapper"> 6 7 <!-- 根据id 查询数据数据 --> 8 <select id="getEmpById" resultType="ssm.entity.Employee"> 9 select * from tbl_employee 10 where id=#{id,jdbcType=INTEGER} 11 </select> 12 <!-- 查询列表 --> 13 <select id="list" resultType="ssm.entity.Employee"> 14 select id,last_name as 15 lastName,email,gender from tbl_employee 16 </select> 17 <!-- 插入 --> 18 <insert id="insert" useGeneratedKeys="true"> 19 insert into tbl_employee 20 (last_name,email,gender) values( 21 #{lastName,jdbcType=VARCHAR}, 22 #{email,jdbcType=VARCHAR}, 23 #{gender,jdbcType=VARCHAR} 24 25 ) 26 </insert> 27 <!-- 修改 --> 28 <update id="update"> 29 update tbl_employee set 30 last_name=#{lastName,jdbcType=VARCHAR},email=#{email,jdbcType=VARCHAR},gender=#{gender,jdbcType=VARCHAR} 31 where id=#{id,jdbcType=INTEGER} 32 </update> 33 </mapper>
数据转换:
StringToDateConverter, 把String 转为日期;
应用场景:form表单提交日期到后台,由于传输的数据时String类型的日期,而后台对应的字段为java.util.Date类型;如果需要实现后台传入的数据自动转成对应的java.util.Date类型的字段则需要配置配置数据转换;转换类如下:
1 package ssm.convert; 2 3 import java.text.SimpleDateFormat; 4 import java.util.Date; 5 6 import org.springframework.core.convert.converter.Converter; 7 8 public class StringToDateConverter implements Converter<String, Date> { 9 10 // 日期类型模板:如yyyy-MM-dd,通过配置时注入 11 private String datePattern; 12 13 public void setDatePattern(String datePattern) { 14 this.datePattern = datePattern; 15 } 16 17 // Converter<S,T>接口的类型转换方法 18 @Override 19 public Date convert(String date) { 20 try { 21 SimpleDateFormat dateFormat = new SimpleDateFormat(this.datePattern); 22 // 将日期字符串转换成Date类型返回 23 return dateFormat.parse(date); 24 } catch (Exception e) { 25 e.printStackTrace(); 26 System.out.println("日期转换失败!"); 27 return null; 28 } 29 30 } 31 32 }
StringToIntegerConverter,把String转成Integer
1 package ssm.convert; 2 3 import org.springframework.core.convert.converter.Converter; 4 5 public class StringToIntegerConverter implements Converter<String, Integer> { 6 7 // Converter<S,T>接口的类型转换方法 8 @Override 9 public Integer convert(String intData) { 10 try { 11 // 将日期字符串转换成Date类型返回 12 return Integer.valueOf(intData); 13 } catch (Exception e) { 14 e.printStackTrace(); 15 System.out.println("整型转换失败"); 16 return null; 17 } 18 19 } 20 21 }
分页类:
参考地址:https://github.com/xjs1919/PageHelperExt
PageObjectFactory.java
1 package ssm.utils; 2 3 import org.apache.ibatis.reflection.factory.DefaultObjectFactory; 4 5 import com.github.pagehelper.PageInfo; 6 7 /** 8 * Created by xujiashuai on 2016/6/29. 9 */ 10 public class PageObjectFactory extends DefaultObjectFactory { 11 12 private static final long serialVersionUID = 3963031299778136554L; 13 14 /** 15 * 如果类型为page的话让其也判断为集合 16 */ 17 public <T> boolean isCollection(Class<T> type) { 18 if (type == PageInfo.class) { 19 return true; 20 } 21 return super.isCollection(type); 22 } 23 24 @SuppressWarnings({ "unchecked", "rawtypes" }) 25 public <T> T create(Class<T> type) { 26 if (type == PageInfo.class) { 27 return (T) new PageInfo(); 28 } 29 return create(type, null, null); 30 } 31 }
PageObjectWrapper.java
1 package ssm.utils; 2 3 import java.util.List; 4 5 import org.apache.ibatis.reflection.MetaObject; 6 import org.apache.ibatis.reflection.factory.ObjectFactory; 7 import org.apache.ibatis.reflection.property.PropertyTokenizer; 8 import org.apache.ibatis.reflection.wrapper.ObjectWrapper; 9 10 import com.github.pagehelper.Page; 11 import com.github.pagehelper.PageInfo; 12 13 public class PageObjectWrapper implements ObjectWrapper { 14 15 @SuppressWarnings("rawtypes") 16 private PageInfo pageinfo; 17 18 @SuppressWarnings("rawtypes") 19 public PageObjectWrapper(PageInfo wrapped) { 20 this.pageinfo = wrapped; 21 } 22 23 @SuppressWarnings({ "rawtypes", "unchecked" }) 24 @Override 25 public <E> void addAll(List<E> element) { 26 Page page = (Page) element; 27 pageinfo.setPageNum(page.getPageNum()); 28 pageinfo.setPageSize(page.getPageSize()); 29 pageinfo.setPages(page.getPages()); 30 pageinfo.setList(page); 31 pageinfo.setSize(page.size()); 32 pageinfo.setTotal(page.getTotal()); 33 if (page.size() == 0) { 34 pageinfo.setStartRow(0); 35 pageinfo.setEndRow(0); 36 } else { 37 pageinfo.setStartRow(page.getStartRow() + 1); 38 pageinfo.setEndRow(pageinfo.getStartRow() - 1 + pageinfo.getSize()); 39 } 40 pageinfo.setNavigatePages(5); 41 calcNavigatepageNums(pageinfo, page); 42 calcPage(pageinfo); 43 judgePageBoudary(pageinfo); 44 } 45 46 @SuppressWarnings("rawtypes") 47 private void calcNavigatepageNums(PageInfo pageinfo, com.github.pagehelper.Page page) { 48 int pages = pageinfo.getPages(); 49 int navigatePages = pageinfo.getNavigatePages(); 50 int pageNum = pageinfo.getPageNum(); 51 int[] navigatepageNums = null; 52 if (pages <= navigatePages) { 53 navigatepageNums = new int[pages]; 54 for (int i = 0; i < pages; i++) { 55 navigatepageNums[i] = i + 1; 56 } 57 } else { 58 navigatepageNums = new int[navigatePages]; 59 int startNum = pageNum - navigatePages / 2; 60 int endNum = pageNum + navigatePages / 2; 61 62 if (startNum < 1) { 63 startNum = 1; 64 for (int i = 0; i < navigatePages; i++) { 65 navigatepageNums[i] = startNum++; 66 } 67 } else if (endNum > pages) { 68 endNum = pages; 69 for (int i = navigatePages - 1; i >= 0; i--) { 70 navigatepageNums[i] = endNum--; 71 } 72 } else { 73 for (int i = 0; i < navigatePages; i++) { 74 navigatepageNums[i] = startNum++; 75 } 76 } 77 } 78 pageinfo.setNavigatepageNums(navigatepageNums); 79 } 80 81 @SuppressWarnings("rawtypes") 82 private void calcPage(PageInfo pageinfo) { 83 int[] navigatepageNums = pageinfo.getNavigatepageNums(); 84 int pageNum = pageinfo.getPageNum(); 85 if (navigatepageNums != null && navigatepageNums.length > 0) { 86 if (pageNum > 1) { 87 pageinfo.setPrePage(pageNum - 1); 88 } 89 if (pageNum < pageinfo.getPages()) { 90 pageinfo.setNextPage(pageNum + 1); 91 } 92 } 93 } 94 95 @SuppressWarnings("rawtypes") 96 private void judgePageBoudary(PageInfo pageinfo) { 97 int pageNum = pageinfo.getPageNum(); 98 int pages = pageinfo.getPages(); 99 pageinfo.setIsFirstPage(pageNum == 1); 100 pageinfo.setIsLastPage(pageNum == pages); 101 pageinfo.setHasPreviousPage(pageNum > 1); 102 pageinfo.setHasNextPage(pageNum < pages); 103 } 104 105 @Override 106 public Object get(PropertyTokenizer prop) { 107 return null; 108 } 109 110 @Override 111 public void set(PropertyTokenizer prop, Object value) { 112 113 } 114 115 @Override 116 public String findProperty(String name, boolean useCamelCaseMapping) { 117 return null; 118 } 119 120 @Override 121 public String[] getGetterNames() { 122 return new String[0]; 123 } 124 125 @Override 126 public String[] getSetterNames() { 127 return new String[0]; 128 } 129 130 @Override 131 public Class<?> getSetterType(String name) { 132 return null; 133 } 134 135 @Override 136 public Class<?> getGetterType(String name) { 137 return null; 138 } 139 140 @Override 141 public boolean hasSetter(String name) { 142 return false; 143 } 144 145 @Override 146 public boolean hasGetter(String name) { 147 return false; 148 } 149 150 @Override 151 public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) { 152 return null; 153 } 154 155 @Override 156 public boolean isCollection() { 157 return false; 158 } 159 160 @Override 161 public void add(Object element) { 162 163 } 164 }
PageObjectWrapperFactory.java
1 package ssm.utils; 2 3 import org.apache.ibatis.reflection.MetaObject; 4 import org.apache.ibatis.reflection.ReflectionException; 5 import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory; 6 import org.apache.ibatis.reflection.wrapper.ObjectWrapper; 7 8 import com.github.pagehelper.PageInfo; 9 10 /** 11 * Created by xujiashuai on 2016/6/29. 12 */ 13 public class PageObjectWrapperFactory extends DefaultObjectWrapperFactory { 14 15 @Override 16 public boolean hasWrapperFor(Object object) { 17 if (object instanceof PageInfo) { 18 return true; 19 } 20 return false; 21 } 22 23 @SuppressWarnings("rawtypes") 24 @Override 25 public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) { 26 if (object instanceof PageInfo) { 27 return new PageObjectWrapper((PageInfo) object); 28 } 29 throw new ReflectionException( 30 "The DefaultObjectWrapperFactory should never be called to provide an ObjectWrapper."); 31 } 32 }
页面:
index.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 4 <%@taglib prefix="s" uri="http://www.springframework.org/tags"%> 5 <!DOCTYPE html> 6 <html> 7 <head> 8 <script type="text/javascript" src="/js/jquery.min.js"></script> 9 <meta charset="UTF-8"> 10 <title><s:message code="EMPLOYEE.LIST"></s:message></title> 11 </head> 12 <body> 13 <input type="button" value="添加" id="add"> 14 <table> 15 <tr> 16 <td>id</td> 17 <td><s:message code="EMPLOYEE.LASTNAME"></s:message> </td> 18 <td><s:message code="EMPLOYEE.EMAIL"></s:message></td> 19 <td><s:message code="EMPLOYEE.GENDER"></s:message></td> 20 <td><s:message code="SYS.OPERATE"></s:message></td> 21 </tr> 22 <c:forEach var="item" items="${pages.list}"> 23 <tr class="row"> 24 <td>${item.id}</td> 25 <td>${item.lastName}</td> 26 <td>${item.email}</td> 27 <td>${item.gender}</td> 28 <td > <input type="button" value="<s:message code='SYS.EDIT'></s:message> " class="editRow"> 29 <input type="hidden" value="${item.id}"/> 30 </td> 31 <td > <input type="button" value="<s:message code='SYS.DETAIL'></s:message> " class="detailRow"> 32 <input type="hidden" value="${item.id}"/> 33 </td> 34 35 </tr> 36 </c:forEach> 37 </table> 38 <p> 39 <c:if test="${pages.hasPreviousPage}"> 40 <input type="button" class="page" value="前一页"/> 41 <input type="hidden" value="${pages.prePage}"> 42 </c:if> 43 <c:forEach var="item" items="${pages.navigatepageNums}"> 44 <c:if test="${item==pages.pageNum}"> 45 <input type="button" class="page" style="color: red" value="${item}"> 46 </c:if> 47 <c:if test="${item!=pages.pageNum}"> 48 <input type="button" class="page" value="${item}"> 49 </c:if> 50 <input type="hidden" value="${item}"> 51 </c:forEach> 52 <c:if test="${pages.hasNextPage}"> 53 <input type="button" class="page" value="下一页"/> 54 <input type="hidden" value="${pages.nextPage}"> 55 </c:if> 56 <input type="hidden" id="pageNum" value="${pages.pageNum}"> <input 57 type="hidden" id="pageSize" value="${pages.pageSize}"> 58 </p> 59 </body> 60 <script> 61 $(function() { 62 $(".page").each(function() { 63 $(this).click(function() { 64 var pageNum = $(this).next().val(); 65 var pageSize = 5; 66 window.location = "${pageContext.request.contextPath}/emp/list?pageNum=" 67 + pageNum 68 + "&pageSize=" 69 + pageSize; 70 }) 71 }); 72 $("#add").click(function(){ 73 window.location = "${pageContext.request.contextPath}/emp/add" 74 }) 75 $(".editRow").each(function(){ 76 $(this).click(function(){ 77 var id = $(this).next().val(); 78 window.location = "edit/"+id 79 }) 80 }) 81 $(".detailRow").each(function(){ 82 $(this).click(function(){ 83 var id = $(this).next().val(); 84 $.post("/emp/detail",{id:id},function(data){ 85 alert("姓名:"+data.lastName+",邮箱:"+data.email+",性别:"+data.gender); 86 }) 87 88 }) 89 }) 90 91 }) 92 </script> 93 </html>
update.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4 <%@ taglib prefix="s" uri="http://www.springframework.org/tags" %> 5 <!DOCTYPE html> 6 <html> 7 <head> 8 <script src="/js/jquery.min.js"></script> 9 <meta charset="UTF-8"> 10 <title><s:message code="EMPLOYEE.EDIT"></s:message></title> 11 </head> 12 <body> 13 <form action="/emp/update" method="Post"> 14 <s:message code="EMPLOYEE.LASTNAME"></s:message>:<input type="text" name="lastName" value="${employee.lastName}"/><br> 15 <s:message code="EMPLOYEE.EMAIL"></s:message>:<input type="text" name="email" value="${employee.email}"/><br> 16 <s:message code="EMPLOYEE.GENDER"></s:message>:男<input type="radio" name="gender" value="男"/> 女<input type="radio" name="gender" value="女"/><br> 17 <input type="hidden" name="id" value="${employee.id}"> 18 <input type="submit" value="<s:message code='SYS.SUBMIT'></s:message>"> 19 </form> 20 </body> 21 <script> 22 $(function(){ 23 var gender = '${employee.gender}'; 24 if(!!gender ){ 25 if(gender == "男"){ 26 $('input:radio[name="gender"]:first').attr("checked","checked"); 27 } 28 if(gender == "女"){ 29 $('input:radio[name="gender"]:last').attr("checked","checked"); 30 } 31 } 32 33 }) 34 </script> 35 </html>
三、配置
web.xml配置:
DispatcherServlet(分发器)配置 + ContextLoaderListener整合spring配置+CharacterEncodingFilter请求/响应编码配置;
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns="http://xmlns.jcp.org/xml/ns/javaee" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" 5 version="4.0"> 6 <filter> 7 <filter-name>CharacterEncodingFilter</filter-name> 8 <filter-class>org.springframework.web.filter.CharacterEncodingFilter 9 </filter-class> 10 <init-param> 11 <param-name>encoding</param-name> 12 <param-value>utf-8</param-value> 13 </init-param> 14 </filter> 15 <filter-mapping> 16 <filter-name>CharacterEncodingFilter</filter-name> 17 <url-pattern>/*</url-pattern> 18 </filter-mapping> 19 <context-param> 20 <param-name>contextConfigLocation</param-name> 21 <param-value>classpath:spring.xml</param-value> 22 </context-param> 23 <listener> 24 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 25 </listener> 26 <!-- 配置DispatcherServlet(快捷键 alt +/) --> 27 <servlet> 28 <servlet-name>springDispatcherServlet</servlet-name> 29 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 30 <!-- 配置DispatcherServletd 一个初始化参数:配置springmvc配置文件的位置和名称 --> 31 <!-- 实际上也可以不通过 contextConfigLocation 来配置Springmvc的配置文件,而是用默认的 即默认的配置文件为 32 /WEB-INF/<servlet-name>-servlet.xml 本项目默认位置配置文件即为: /WEB-INF/springDispatcherServlet-servlet.xml --> 33 <init-param> 34 <param-name>contextConfigLocation</param-name> 35 <param-value>classpath:springmvc.xml</param-value> 36 </init-param> 37 <!-- 表示springDispatcherServlet在加载的时候被创建 --> 38 <load-on-startup>1</load-on-startup> 39 </servlet> 40 41 <!-- Map all requests to the DispatcherServlet for handling --> 42 <servlet-mapping> 43 <servlet-name>springDispatcherServlet</servlet-name> 44 <url-pattern>/</url-pattern> 45 </servlet-mapping> 46 </web-app>
如果需要使用put,delete的请求,还需要配置:这个例子中没有这一段;具体教程请看REST( Representational State Transfer )
1 <filter> 2 <filter-name>HiddenHttpMethodFilter</filter-name> 3 <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> 4 </filter> 5 <filter-mapping> 6 <filter-name>HiddenHttpMethodFilter</filter-name> 7 <url-pattern>/*</url-pattern> 8 </filter-mapping>
springmvc配置:
springmvc 只负责网站跳转逻辑;
springmvc.xml:
- spring数据转换:配置了String转 java.util.Date ,实现类是StringToDateConverter;配置了 String 转Integer ,实现类是StringToIntegerConverter
完成后需要加到<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"></mvc:annotation-driven>中; -
<mvc:default-servlet-handler /> 的作用是可以访问到静态文件,比如访问js;如果没有这个配置,页面无法引用js;
参考:https://www.cnblogs.com/lixiuming521125/p/16011536.html
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:mvc="http://www.springframework.org/schema/mvc" 6 xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 9 10 <!-- spirngmvc 只负责 网站跳转逻辑 --> 11 <!-- 配置扫描的包:只扫描Controller 和 Service --> 12 <context:component-scan base-package="ssm" 13 use-default-filters="false"> 14 <context:include-filter type="annotation" 15 expression="org.springframework.stereotype.Controller" /> 16 <context:exclude-filter type="annotation" 17 expression="org.springframework.stereotype.Service" /> 18 </context:component-scan> 19 <!-- 配置视图解析器 解析视图地址: /WEB-INF/views/+视图名称+.jsp --> 20 <bean 21 class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 22 <property name="prefix" value="/WEB-INF/views/"></property> 23 <property name="suffix" value=".jsp"></property> 24 </bean> 25 26 27 <!--配置SpringMVC的数据转换器 --> 28 <bean id="conversionServiceFactoryBean" 29 class="org.springframework.context.support.ConversionServiceFactoryBean"> 30 <property name="converters"> 31 <list> 32 <bean class="ssm.convert.StringToDateConverter"> 33 <property name="datePattern" value="yyyy-MM-dd"></property> 34 </bean> 35 <bean class="ssm.convert.StringToIntegerConverter"> 36 </bean> 37 </list> 38 </property> 39 </bean> 40 41 <!--配置conversion-service属性 指向SpringMVC的数据转换器 --> 42 <mvc:annotation-driven 43 conversion-service="conversionServiceFactoryBean"> 44 </mvc:annotation-driven> 45 46 <!-- 配置访问静态资源 --> 47 <mvc:default-servlet-handler /> 48 49 <!-- 配置国际化文件 --> 50 <bean id="messageSource" 51 class="org.springframework.context.support.ResourceBundleMessageSource"> 52 <property name="basename" value="i18n"></property> 53 </bean> 54 55 56 </beans>
spring配置:
spring 希望管理所有的业务逻辑组件,等
spring.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:tx="http://www.springframework.org/schema/tx" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 8 http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd 9 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd 10 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd"> 11 12 <!-- spring 希望管理所有的业务逻辑组件,等 --> 13 14 <!-- 自动扫描配置 除了扫描Controller 和 Service 外扫描所有其他注解标记的类 --> 15 <context:component-scan base-package="ssm" 16 use-default-filters="false"> 17 <context:include-filter type="annotation" 18 expression="org.springframework.stereotype.Service" /> 19 <context:exclude-filter type="annotation" 20 expression="org.springframework.stereotype.Controller" /> 21 </context:component-scan> 22 23 <!-- spring用来控制业务逻辑。数据源、事务控制、aop... --> 24 <!-- 导入资源文件 --> 25 <context:property-placeholder 26 location="classpath:dbconfig.properties" /> 27 <!-- 配置c3p0数据源 --> 28 <bean id="datasource" 29 class="com.mchange.v2.c3p0.ComboPooledDataSource"> 30 <property name="user" value="${jdbc.username}"></property> 31 <property name="password" value="${jdbc.password}"></property> 32 <property name="driverClass" value="${jdbc.driver}"></property> 33 <property name="jdbcUrl" value="${jdbc.url}"></property> 34 </bean> 35 <!-- spring 事务管理器 --> 36 <bean id="transactionManager" 37 class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 38 <property name="dataSource" ref="datasource"></property> 39 </bean> 40 <!-- 开启基于注解的事务 --> 41 <tx:annotation-driven 42 transaction-manager="transactionManager" /> 43 44 <!-- 整合mybatis目的: 1.spring管理所有组件。mapper的实现类。可以对service中引用dao的内容,可以为@Autowired 45 自动注入mapper; 2.spring用来管理声明式事务, --> 46 <!-- 创建出 sqlSessionFactoryBean对象 --> 47 <bean id="sqlSessionFactoryBean" 48 class="org.mybatis.spring.SqlSessionFactoryBean"> 49 <property name="dataSource" ref="datasource"></property> 50 <!-- configLocation指定全局配置文件的位置 --> 51 <property name="configLocation" 52 value="classpath:mybatis-config.xml"></property> 53 <!-- 指定mapper位置(如果mapper与mapper接口的文件名不一样的话这里需要配置,若一样就可以不配置) --> 54 <property name="mapperLocations" 55 value="classpath:mapper/*.xml"></property> 56 <property name="plugins"> 57 <array> 58 <bean class="com.github.pagehelper.PageInterceptor"> 59 <property name="properties"> 60 <!--使用下面的方式配置参数,一行配置一个 --> 61 <value> 62 helperDialect=mysql 63 reasonable=true 64 supportMethodsArguments=true 65 params=count=countSql 66 autoRuntimeDialect=true 67 </value> 68 </property> 69 </bean> 70 </array> 71 </property> 72 </bean> 73 <!--配置一个可以进行批量执行的sqlSession --> 74 <bean id="sqlSession" 75 class="org.mybatis.spring.SqlSessionTemplate"> 76 <constructor-arg name="sqlSessionFactory" 77 ref="sqlSessionFactoryBean"></constructor-arg> 78 <constructor-arg name="executorType" value="BATCH"></constructor-arg> 79 </bean> 80 <!-- 扫描所有的mapper接口的实现,让这些mapper能够自动注入 --> 81 <!-- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 配置SqlSessionFactoryBean的名称 82 <property name="basePackage" value="ssm.mapper" /> </bean> --> 83 <mybatis-spring:scan base-package="ssm.mapper" /> 84 </beans>
mybatis-config.xml配置:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 <!-- settings包含很多重要的设置项; name:设置项的名字,value设置项的取值 --> 7 <settings> 8 <!-- 开启驼峰命名 比如数据库字段为Last_Name 则 自动变为lastName --> 9 <setting name="mapUnderscoreToCamelCase" value="true" /> 10 <!-- 分步查询配合一下两个配置 实现懒加载(按需加载) --> 11 <setting name="lazyLoadingEnabled" value="true" /> 12 <setting name="aggressiveLazyLoading" value="false" /> 13 <!--开启日志--> 14 <setting name="logImpl" value="STDOUT_LOGGING"/> 15 </settings> 16 <objectFactory 17 type="ssm.utils.PageObjectFactory" /> 18 19 <objectWrapperFactory 20 type="ssm.utils.PageObjectWrapperFactory" /> 21 22 <!-- 配置顺序,properties settings typeAliases typeHandlers objectFactory objectWrapperFactory 23 reflectFactory plugings environment databaseIdProvider mappers --> 24 </configuration>
dbconfig.properties:
1 jdbc.driver=com.mysql.jdbc.Driver 2 jdbc.url=jdbc:mysql://localhost:3306/mybatis 3 jdbc.username=root 4 jdbc.password= 5 6 jdbc2.driver=com.mysql.jdbc.Driver 7 jdbc2.url=jdbc:mysql://localhost:3306/mybatis2 8 jdbc2.username=root 9 jdbc2.password=
i18n_zh_CN.properties
1 EMPLOYEE.LASTNAME=姓名 2 EMPLOYEE.EMAIL=邮箱 3 EMPLOYEE.GENDER=性别 4 EMPLOYEE.LIST=列表 5 EMPLOYEE.EDIT=添加/修改 6 SYS.OPERATE=操作 7 SYS.ADD=添加 8 SYS.EDIT=修改 9 SYS.SUBMIT=提交 10 SYS.DETAIL=详情
运行结果:
访问:http://localhost:8080/emp/list?pageNum=1&pageSize=5,显示列表第一页,数据条数为5条;
访问:http://localhost:8080/emp/list?pageNum=2&pageSize=5,显示列表第二页,数据条数为5条;
目前是id 倒叙的,也可以自定义排序规则;比如:http://localhost:8080/emp/list?pageNum=2&pageSize=5&orderBy=id%20asc,lastName%20asc;
点击添加跳转到跳转页面;点击修改操作,显示修改页面;
点击详情alert弹出详情;