项目搭建
1)创建一个web工程
2)引入项目依赖的jar包
<dependencies>
<!--引入pageHelper分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.0.0</version>
</dependency>
<!-- MBG -->
<!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- 返回json字符串的支持 -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.8</version>
</dependency>
<!--JSR303数据校验支持;tomcat7及以上的服务器,
tomcat7以下的服务器:el表达式。额外给服务器的lib包中替换新的标准的el
-->
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
<!-- Spring-Jdbc -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!--Spring-test -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- Spring面向切面编程 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!--MyBatis -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
<!-- MyBatis整合Spring的适配包 -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!-- 数据库连接池、驱动 -->
<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.41</version>
</dependency>
<!-- (jstl,servlet-api,junit) -->
<!-- https://mvnrepository.com/artifact/jstl/jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.2.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!-- junit -->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
3)引入bootstrap前端框架
<%
pageContext.setAttribute("APP_PATH", request.getContextPath());
%>
<script type="text/javascript"
src="${APP_PATH}/static/js/jquery-1.12.4.min.js"></script>
<link
href="${APP_PATH}/static/bootstrap-3.3.7-dist/css/bootstrap.min.css"
rel="stylesheet">
<script
src="${APP_PATH}/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
4)编写ssm整合的关键配置文件
i:web.xml
<!-- 1.启动spring的容器-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--2、springmvc的前端控制器,拦截所有请求 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 3、字符编码过滤器,一定要放在所有过滤器之前 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 4、使用Rest风格的URI,将页面普通的post请求转为指定的delete或者put请求 -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--5.请求方式支持PUT请求-->
<filter>
<filter-name>HttpPutFormContentFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpPutFormContentFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
ii:Spring的配置文件
<!--开启注解扫描-->
<context:component-scan base-package="com.ll">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--spring配置文件-->
<!--=================== 数据源,事务控制================-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--配置和mybatis的整合-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 指定mybatis全局配置文件的位置 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<property name="dataSource" ref="pooledDataSource"></property>
<!-- 指定mybatis,mapper文件的位置 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>
<!-- 配置扫描器,将mybatis接口的实现加入到ioc容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--扫描所有dao接口的实现,加入到ioc容器中 -->
<property name="basePackage" value="com.ll.crud.dao"></property>
</bean>
<!-- 配置一个可以执行批量的sqlSession -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
<constructor-arg name="executorType" value="BATCH"></constructor-arg>
</bean>
<!-- ===============事务控制的配置 ================-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--控制住数据源 -->
<property name="dataSource" ref="pooledDataSource"></property>
</bean>
<!--开启基于注解的事务,使用xml配置形式的事务(必要主要的都是使用配置式) -->
<aop:config>
<!-- 切入点表达式 -->
<aop:pointcut expression="execution(* com.ll.crud.service..*(..))" id="txPoint"/>
<!-- 配置事务增强 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
</aop:config>
<!--配置事务增强,事务如何切入 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 所有方法都是事务方法 -->
<tx:method name="*"/>
<!--以get开始的所有方法 -->
<tx:method name="get*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- Spring配置文件的核心点(数据源、与mybatis的整合,事务控制) -->
iii:SpirngMVC配置文件
<!--SpringMVC的配置文件,包含网站跳转逻辑的控制,配置 -->
<context:component-scan base-package="com.ll.crud.controller" ></context:component-scan>
<!--配置视图解析器,方便页面返回 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--两个标准配置 -->
<!-- 将springmvc不能处理的请求交给tomcat -->
<mvc:default-servlet-handler/>
<!-- 能支持springmvc更高级的一些功能,JSR303校验,快捷的ajax...映射动态请求 -->
<mvc:annotation-driven/>
iiii:MyBatis配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--驼峰自动转换-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<package name="com.ll.crud.bean"/>
</typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!--分页参数合理化 -->
<property name="reasonable" value="true"/>
</plugin>
</plugins>
</configuration>
v:测试Mapper
//加载spring test与junit的整合
@RunWith(SpringJUnit4ClassRunner.class)
//加载配置类信息
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class MapperTest {
@Autowired
DepartmentMapper departmentMapper;
@Autowired
EmployeeMapper employeeMapper;
@Autowired
SqlSession sqlSession;
@Test
public void testCRUD() {
//添加部门
departmentMapper.insertSelective(new Department(null,"开发部"));
departmentMapper.insertSelective(new Department(null,"测试部"));
// 2.生成员工数据,测试员工插入
employeeMapper.insertSelective(new Employee(null, "xx", "M", "[email protected]", 1));
//3.批量插入多个员工
EmployeeMapper sqlSessionMapper = sqlSession.getMapper(EmployeeMapper.class);
for (int i = 0; i < 1000; i++) {
String name = UUID.randomUUID().toString().substring(0, 5) + i;
sqlSessionMapper.insertSelective(new Employee(null, name, "M", name + "@xxx.com", 1));
}
}
Rest风格
• /emp/{id} GET 查询员工
• /emp POST 保存员工
• /emp/{id} PUT 修改员工
• /emp/{id} DELETE 删除员工
查询
显示所有员工信息
• 1、访问index.jsp页面
• 2、index.jsp页面发送出查询员工列表请求
• 3、EmployeeController来接受请求,查出员工数据
• 4、来到list.jsp页面进行展示
• 5、pageHelper分页插件完成分页查询功能
查询方法
//查询所有员工
@ResponseBody
@RequestMapping("/emps")
public Msg getEmpsWithJson(@RequestParam(value = "pn", defaultValue = "1") Integer pn) {
//这不是分页查询
//引入pagehelper分页插件
//再查询之前,只需要调用,传入页码,以及每页的大小
PageHelper.startPage(pn, 5);
//startPage后面紧跟的这个查询就是分页查询
List<Employee> emps = employeeService.getAll();
//使用PageInfo包装查询后的结果,只需要将PageInfo交过页面
//封装了详细的信息,包括查询出来的数据,传入连续显示的页数
PageInfo page = new PageInfo(emps, 5);
return Msg.success().add("pageInfo", page);
}
//Description:根据员工id查询员工
@RequestMapping(value = "/emp/{id}", method = RequestMethod.GET)
@ResponseBody
public Msg getEmp(@PathVariable("id") Integer id) {
Employee employee = employeeService.getEmp(id);
return Msg.success().add("emp", employee);
}
添加
• 1、在index.jsp页面点击”新增” • 2、弹出新增对话框
• 3、去数据库查询部门列表,显示在对话框中
• 4、用户输入数据,并进行校验
• jquery前端校验,ajax用户名重复校验,重要数据(后端校验(JSR303),唯一约束);
• 5、完成保存
//检查用户名是否 可用
@ResponseBody
@RequestMapping("/checkuser")
public Msg checkuser(@RequestParam("empName") String empName) {
//先判断用户名是否是合法的表达式
String regName = "/(^[a-zA-Z0-9_-]{6,16}$)|(^[\\u2E80-\\u9FFF]{2,5})/";
if (empName.matches(regName)) {
return Msg.fail().add("va_msg", "用户名必须是6-16位数字组合,或者2-5位中文");
}
//数据库用户名校验
boolean b = employeeService.checkuser(empName);
if (b) {
return Msg.success();
} else {
return Msg.fail().add("va_msg", "用户名不可用");
}
}
//添加员工
@RequestMapping(value = "/emp", method = RequestMethod.POST)
@ResponseBody
public Msg saveEmp(@Valid Employee employee, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
//校验失败,返回失败,再模态框中显示校验失败的错误信息
Map<String, Object> map = new HashMap<>();
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
System.out.println("错误的字段名" + fieldError.getField());
System.out.println("错误信息" + fieldError.getDefaultMessage());
map.put(fieldError.getField(), fieldError.getDefaultMessage());
}
return Msg.fail().add("errorField", map);
} else {
employeeService.saveEmp(employee);
return Msg.success();
}
}
修改
• 1、点击编辑
• 2、弹出用户修改的模态框(显示用户信息)
• 3、点击更新,完成用户修改
@ResponseBody
@RequestMapping(value = "emp/{empId}", method = RequestMethod.PUT)
public Msg saveEmp(Employee employee) {
employeeService.updateEmp(employee);
return Msg.success();
}
/*
* Description:根据员工id查询员工
* @param id
* @return com.ll.crud.bean.Msg
*/
@RequestMapping(value = "/emp/{id}", method = RequestMethod.GET)
@ResponseBody
public Msg getEmp(@PathVariable("id") Integer id) {
Employee employee = employeeService.getEmp(id);
return Msg.success().add("emp", employee);
}
请求方式为PUT的时候,请求中带的id参数
如果为{id} springmvc封装的时候不会将这个字段封装到对象中
如果为{empId} springmvc封装的时候会将这个字段封装到对象中
- 问题:请求体中有数据,但是employee对象封装不上
* 原因:tomcat
* 1.将请求体中的数据,封装一个map
* 2.request.getParameter(“employeeName”)就会从这个map中取值
* 3.springMVC封装POJO对象的时候
* 会把pojo中每个属性值,request.getParameter(email);
* ajax不能直接发put请求
* put请求,请求体中的数据,request.getParameter(“employeeName”)拿不到
* tomcat一看是put请求 不会封装请求体中的数据为map,只有post形式的请求才封装请求为map
必须要配置过滤器才可以使用put请求
<filter>
<filter-name>HttpPutFormContentFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpPutFormContentFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
删除
• 1、单个删除
• URI:/emp/{id} DELETE
• 2、批量删除
@RequestMapping(value = "/emp/{ids}", method = RequestMethod.DELETE)
@ResponseBody
public Msg deleteEmp(@PathVariable("ids") String ids) {
//批量删除
if (ids.contains("-")) {
List<Integer> list = new ArrayList();
String[] str_ids = ids.split("-");
for (String str_id : str_ids) {
list.add(Integer.parseInt(str_id));
}
employeeService.deleteBatch(list);
//单个删除
} else {
int id = Integer.parseInt(ids);
employeeService.deleteEmp(id);
}
return Msg.success();
}