SpringMVC
ssm整合(一)整合步骤分析
什么是SSM整合?
- Spring SpringMVC Mybatis ,简称ssm
- Spring整合SpringMVC
- Spring整合Mybatis
整合方案
-
注解 + XML 【推荐】
注解: 自定义的类(dao、service)
XML: jar包中的类(DataSource,DataSourceTransactionManager)
-
纯XML
-
纯注解
整合流程
- 单独搭建Spring开发环境
- 单独搭建SpringMVC开发环境
- Spring整合SpringMVC
- 单独搭建mybatis环境
- Spring整合Mybatis [ssm整合完成]
ssm整合(二)单独Spring环境
实现步骤
- 创建项目:springmvc03_ssm,添加依赖
- 编写User实体类,封装数据
- 编写UserService接口、实现
- 编写applicationContext.xml
- 测试
实现代码
1、创建项目:springmvc03_ssm,添加依赖
<dependencies>
<!--Spring核心支持包-->
<!--SpringMVC支持包-->
<!--SpringJDBC支持包-->
<!--Spring事务支持包-->
<!--Aop支持包-->
<!--Spring的Junit支持包-->
<!--MyBatis支持包-->
<!--Spring整合MyBatis支持包-->
<!--数据库驱动包、连接池-->
<!--jstl支持包-->
<!--lombok支持包-->
</dependencies>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>xxx.xxx</groupId>
<artifactId>springmvc03_ssm</artifactId>
<version>1.0-SNAPSHOT</version>
<!--统一定义版本号-->
<properties>
<spring_version>5.1.8.RELEASE</spring_version>
<aspectj_version>1.9.4</aspectj_version>
</properties>
<dependencies>
<!--Spring核心支持包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring_version}</version>
</dependency>
<!--SpringMVC支持包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring_version}</version>
</dependency>
<!--SpringJDBC支持包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring_version}</version>
</dependency>
<!--Spring事务支持包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring_version}</version>
</dependency>
<!--Aop支持包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj_version}</version>
</dependency>
<!--Spring的Junit支持包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring_version}</version>
</dependency>
<!--MyBatis支持包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!--Spring整合MyBatis支持包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
<!--数据库驱动包、连接池-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<!--jstl支持包、junit-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
2、编写User实体类,封装数据
@Getter
@Setter
@ToString
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
}
3、编写UserSevice接口、实现
public interface UserService {
// 查询全部用户
List<User> findAll();
}
// 创建对象加入容器,加入容器的对象的名称默认是类名称,首字母小写
@Service
public class UserServiceImpl implements UserService {
@Override
public List<User> findAll() {
System.out.println("service查询全部。。。");
return null;
}
}
4、编写applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解扫描, 注意:这里要扫描到service包,而在springmvc.xml中扫描web包,各司其职互不干扰-->
<context:component-scan base-package="xxx.xxx"/>
</beans>
5、测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test1_Spring {
// 运行junit时候自动创建ioc容器,所以这里注入容器中的指定类型的对象
@Autowired
private UserService userService;
@Test
public void findAll() {
userService.findAll();
}
}
ssm整合(三)单独SpringMVC环境
步骤
- web.xml配置前端控制器
- springMVC.xml
- UserController控制器
- list.jsp页面
- 测试
代码
1、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_2_5.xsd"
version="2.5">
<!--配置SpringMVC前端控制器,拦截springmvc的请求-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--springmvc的解决中文乱码的编码过滤器-->
<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>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
2、springMVC.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--1. 注解扫描,扫描web包-->
<context:component-scan base-package="xxx.xxx.web"/>
<!--2. 配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--3. 开启springmvc注解驱动-->
<mvc:annotation-driven/>
<!--4. 放行静态资源的访问(因为web.xml拦截的请求路径是/)-->
<mvc:default-servlet-handler/>
</beans>
3、UserController控制器
@Controller
@RequestMapping("/user")
public class UserController {
/**
* 查询全部用户
*/
@RequestMapping("/list")
public String list(){
System.out.println("处理查询请求..");
return "list";
}
}
4、list.jsp页面
5、测试
目前controller中不能注入service对象
ssm整合(四)Spring整合SpringMVC
关键点
在项目启动时候,加载web.xml;然后在web.xml中要加载applicationContext.xml
步骤
- 配置web.xml,配置spring提供的ServletContext监听器: ContextLoaderListener
- 修改controller,注入service
代码
1、配置web.xml,配置spring提供的ServletContext监听器: ContextLoaderListener
<?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_2_5.xsd"
version="2.5">
<!--Spring提供了一个ServletContext监听器,用来在项目启动时候时候加载spring配置文件-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--配置SpringMVC前端控制器,拦截springmvc的请求-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--springmvc的解决中文乱码的编码过滤器-->
<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>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
2、修改controller,注入service
@Controller
@RequestMapping("/user")
public class UserController {
// 控制器中注入service对象,要求容器中必须要有service对象
@Autowired
private UserService userService; // ............添加的代码
/**
* 查询全部用户
*/
@RequestMapping("/list")
public String list(Model model){
// 调用service方法,实现查询
List<User> list = userService.findAll();
// 保存数据
model.addAttribute("list",list);
return "list";
}
}
观察打印结果,说明调用service成功!
ssm整合(五)单独Mybatis环境
实现步骤
- 编写dao接口
- 编写SqlMapConfig.xml
- 编写测试类
实现代码
-
编写dao接口
public interface UserDao { /** * 查询用户,sql语句通过注解实现映射 */ @Select("select * from user") List<User> findAll(); }
-
编写SqlMapConfig.xml
需要先引入jdbc.properties、log4j.properties(可选)
<?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> <!--加载配置文件--> <properties resource="jdbc.properties"/> <!--default 表示默认使用哪个数据库的环境配置--> <environments default="mysql"> <!--mysql数据库环境的配置--> <environment id="mysql"> <transactionManager type="JDBC"></transactionManager> <dataSource type="pooled"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <!--加载接口文件、或接口的映射文件--> <mappers> <!--加载指定目录下的映射文件、接口文件,都会加载. 要求:文件名要一致--> <package name="xxx.xxx.dao"/> </mappers> </configuration>
-
编写测试类
public class Test2_MyBatis { public static void main(String[] args) throws Exception { //创建文件流、创建工厂构造器、创建SqlSession的工厂、创建SqlSession、对接口生成代理、调用代理方法、关闭 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(in); SqlSession sqlSession = factory.openSession(); // 关键代码: 对接口生成代理.... UserDao userDao = sqlSession.getMapper(UserDao.class); List<User> list = userDao.findAll(); System.out.println("list = " + list); sqlSession.close(); in.close(); } }
ssm整合(六)Spring整合Mybatis环境
目标
- 完成Spring整合Mybatis。配置:applicationContext.xml
- 关键点: 把SqlSessionFactory的创建,交给Spring完成。
实现步骤
- 配置applicationContext.xml
- 修改service,注入dao,直接调用dao方法
代码实现
1、配置applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--1. 开启注解扫描, 注意:这里要扫描到service包,而在springmvc.xml中扫描web包,各司其职互不干扰-->
<context:component-scan base-package="xxx.xxx.service"/>
<!--2. 加载配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--3. 创建连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--4. Spring整合MyBatis配置(1)把SqlSessionFactory对象的创建交给spring容器-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--5.Spring整合MyBatis配置(2) 映射扫描配置 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--A. 自动加载指定目录下的映射文件 (支持xml中编写sql语句)-->
<!--B. 自动加载指定包下的所有的接口文件 (支持注解开发)-->
<!--C. 自动对指定包下的所有接口生成代理对象,加入容器(所以,service中可以注入容器中的dao的代理)-->
<property name="basePackage" value="xxx.xxx.dao"/>
</bean>
<!--6. Spring声明式事务配置-->
<!--6.1 事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--6.2 事务通知规则的配置: 拦截的方法后,对指定的方法如何控制事务(必须有事务环境、只读)-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<!--find等开头的方法;运行时期事务可有可无;支持查询操作-->
<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="select*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="load*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="query*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="search*" propagation="SUPPORTS" read-only="true"/>
<!--其他所有方法;运行时期必须要有事务;支持crud操作。-->
<tx:method name="*" propagation="REQUIRED" read-only="false"/>
</tx:attributes>
</tx:advice>
<!--6.3 Aop配置-->
<aop:config>
<!--A. 切入点表达式; 拦截容器中所有以ServiceImpl结尾的bean对象,生成代理,拦截其所有方法-->
<aop:pointcut id="pt" expression="bean(*ServiceImpl)"/>
<!--B. 建立切入点表达式与事务通知规则的对应关系-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config>
</beans>
2、修改service,注入dao,直接调用dao方法
// 创建对象加入容器,加入容器的对象的名称默认是类名称,首字母小写
@Service
public class UserServiceImpl implements UserService {
// 注入容器中的dao对象(代理)
@Autowired
private UserDao userDao;
@Override
public List<User> findAll() {
return userDao.findAll();
}
}
测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test3_SM {
// 运行junit时候自动创建ioc容器,所以这里注入容器中的指定类型的对象
@Autowired
private UserService userService;
@Test
public void findAll() {
System.out.println(userService.getClass());
List<User> list = userService.findAll();
System.out.println(list);
}
}
ssm整合开发中,分别对应的扫描是:
ssm整合(七)ssm整合,页面实现
控制器代码(已经完成)
@Controller
@RequestMapping("/user")
public class UserController {
// 控制器中注入service对象,要求容器中必须要有service对象
@Autowired
private UserService userService;
/**
* 查询全部用户
*/
@RequestMapping("/list")
public String list(Model model){
// 调用service方法,实现查询
List<User> list = userService.findAll();
// 保存数据
model.addAttribute("list",list);
return "list";
}
}
列表页面
list.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>用户列表</title>
</head>
<body>
<table border="1">
<tr>
<td>用户编号</td>
<td>用户名称</td>
<td>生日</td>
<td>性别</td>
<td>地址</td>
</tr>
<c:forEach var="user" items="${list}">
<tr>
<td>${user.id}</td>
<td>${user.username}</td>
<td>${user.birthday}</td>
<td>${user.sex}</td>
<td>${user.address}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
优化
优化日期格式:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -- 添加的代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>用户列表</title>
</head>
<body>
<table border="1">
<tr>
<td>用户编号</td>
<td>用户名称</td>
<td>生日</td>
<td>性别</td>
<td>地址</td>
</tr>
<c:forEach var="user" items="${list}">
<tr>
<td>${user.id}</td>
<td>${user.username}</td>
<td>
<%--引入jstl中的格式化标签库,对日期进行格式化--%> -- 添加的代码
<fmt:formatDate value="${user.birthday}" pattern="yyyy-MM-dd"/>
</td>
<td>${user.sex}</td>
<td>${user.address}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
总结
加载流程
想了解项目加载流程,最主要的是看web.xml, 加载顺序: listener > filter > servlet
为了证明这一点,现在做2件事情: 1、引入log4j.properties; 2、引入servlet支持包(最好)
<!--servlet包-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!--日志支持包-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
现在,启动项目: ( listener > filter > servlet )
其他
1、SSM 整合可以把applicationContext.xml中内容全部移动到springMVC.xml中
,此时就不需要配置listener。
但是最好:
监听器加载所有spring配置文件、spring整合其他框架的配置文件
DispatcherServlet只加载springmvc.xml配置
2、Spring 的 IOC 容器和 SpringMVC 的 IOC 容器扫描的包有重合的部分,会导致有问题。
加载属性: listener > servlet
后面加载会覆盖前面。
基于RESTFUL案例(一)部署UI
修改控制器
因为我们使用restful风格的地址,一个地址表示多次请求,通过请求方式区分。 所以这里我们修改一下访问 路径、以及控制器方法返回值。
@Controller
public class UserController {
// 控制器中注入service对象,要求容器中必须要有service对象
@Autowired
private UserService userService;
/**
* 查询全部用户
* http://localhost:8080/pages/user/user-list.jsp
* 前缀:/pages/
* 后缀:.jsp
*/
@GetMapping("/user")
public String list(Model model){
// 调用service方法,实现查询
List<User> list = userService.findAll();
// 保存数据
model.addAttribute("list",list);
return "user/user-list";
}
}
修改页面
user-list.jsp 页面修改取值:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 注意:要引入
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="../base.jsp"%>
<!DOCTYPE html>
<html>
<head>
<!-- 页面meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>数据 - AdminLTE2定制版</title>
<meta name="description" content="AdminLTE2定制版">
<meta name="keywords" content="AdminLTE2定制版">
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width,initial-scale=1,maximum-scale=1,factory-scalable=no" name="viewport">
</head>
<body>
<div id="frameContent" class="content-wrapper" style="margin-left:0px;">
<section class="content-header">
<h1>
系统管理
<small>用户管理</small>
</h1>
<ol class="breadcrumb">
<li><a href="all-admin-index.html"><i class="fa fa-dashboard"></i> 首页</a></li>
</ol>
</section>
<section class="content">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">用户列表</h3>
</div>
<div class="box-body">
<div class="table-box">
<div class="pull-left">
<div class="form-group form-inline">
<div class="btn-group">
<button type="button" class="btn btn-default" title="添加" οnclick='location.href="${pageContext.request.contextPath}/pages/factory/findByAddress.jsp"'>
<i class="fa fa-file-o"></i> 添加
</button>
</div>
</div>
</div>
<div class="box-tools pull-right">
<div class="has-feedback">
<input type="text" class="form-control input-sm" placeholder="搜索">
<span class="glyphicon glyphicon-search form-control-feedback"></span>
</div>
</div>
<table id="dataList" class="table table-bordered table-striped table-hover dataTable">
<thead>
<tr>
<th class="sorting">用户编号</th>
<th class="sorting">用户名称</th>
<th class="sorting">生日</th>
<th class="sorting">性别</th>
<th class="sorting">地址</th>
</tr>
</thead>
<tbody>
<c:forEach var="user" items="${list}">
<tr>
<td>${user.id}</td>
<td>${user.username}</td>
<td>
<%--引入jstl中的格式化标签库,对日期进行格式化--%>
<fmt:formatDate value="${user.birthday}" pattern="yyyy-MM-dd"/>
</td>
<td>${user.sex}</td>
<td>${user.address}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
<div class="box-footer">
</div>
</div>
</section>
</div>
</body>
</html>
此时,list.jsp就可以删除了,查看最终效果…
基于RESTFUL案例(二)添加用户
流程
添加用户流程如下:
1、页面点击添加,
2、进入添加页面,
3、添加保存后,提交后台处理,最终重定向到列表
步骤
1、user-add.jsp检查表单提交地址
2、编写控制器
3、编写service
4、编写dao
5、编写日期类型转换器、配置转换器
实现
先修改user-list.jsp 中点击添加的地址:
1、user-add.jsp检查表单提交地址
<form id="editForm" action="${pageContext.request.contextPath}/user" method="post">
....
2、编写控制器, 添加add()方法, 处理请求类型是post
路径为/user
的请求
@Controller
public class UserController {
// 控制器中注入service对象,要求容器中必须要有service对象
@Autowired
private UserService userService;
/**
* 查询全部用户
* http://localhost:8080/pages/user/user-list.jsp
* 前缀:/pages/
* 后缀:.jsp
*/
@GetMapping("/user")
public String list(Model model){
// 调用service方法,实现查询
List<User> list = userService.findAll();
// 保存数据
model.addAttribute("list",list);
return "user/user-list";
}
/**
* 添加用户
* @param user
* @return
*/
@PostMapping("/user")
public String add(User user){
// 调用service保存用户
userService.add(user);
// 添加成功,重定向到用户列表 (请求方式默认是get)
return "redirect:/user";
}
}
3、编写service
public interface UserService {
// 查询全部用户
List<User> findAll();
// 添加
void add(User user);
}
@Service
public class UserServiceImpl implements UserService {
// 注入容器中的dao对象(代理)
@Autowired
private UserDao userDao;
@Override
public List<User> findAll() {
return userDao.findAll();
}
@Override
public void add(User user) {
userDao.add(user);
}
}
4、编写dao
public interface UserDao {
/**
* 查询用户,sql语句通过注解实现映射
*/
@Select("select * from user")
List<User> findAll();
/**
* 添加
* @param user
*/
@Insert("insert into user(username,birthday,sex,address) " +
"values(#{username},#{birthday},#{sex},#{address})")
void add(User user);
}
5、编写日期类型转换器、配置转换器
// 自定义类型转换器
@Component
public class StringToDateConverter implements Converter<String,Date> {
@Override
public Date convert(String source) {
try {
if (StringUtils.isEmpty(source)){
return null;
}
return new SimpleDateFormat("yyyy-MM-dd").parse(source);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
注意:要修改springMVC.xml
配置文件:1、配置转换器;2、引用转换器; 3、扫描转换器类
基于RESTFUL案例(二)删除用户
需求
异步删除用户信息,每次只能删除一个用户。
步骤
1、页面删除js,异步发送delete请求
2、编写控制器
3、编写service
4、编写dao
实现
1、页面删除js,异步发送delete请求
user-list.jsp 添加删除按钮
<button type="button" class="btn btn-default" title="删除"
onclick='deleteUser()'>
<i class="fa fa-file-o"></i> 删除
</button>
<script>
function deleteUser() {
// 获取选中的radio的值
var userId = $("input:radio:checked").val();
if (userId){
// 异步请求
$.ajax({
url : "/user/"+userId, // rest请求
type : "delete", // 请求类型: delete,在jQuery的异步请求中可以直接发送delete请求
success:function (result) {
if (result == "ok") {
alert("删除成功!");
// 重新刷新页面
window.location.reload();
}
}
})
}else{
alert("请先选中一条记录,再点击删除!");
}
}
</script>
2、编写控制器
/**
* 删除用户
*/
@DeleteMapping("/user/{userId}")
@ResponseBody // 返回字符串
public String delete(@PathVariable("userId") Integer userId){
userService.delete(userId);
// 添加成功,重定向到用户列表 (请求方式默认是get)
return "ok";
}
3、编写service
public interface UserService {
...
// 删除
void delete(Integer userId);
}
@Service
public class UserServiceImpl implements UserService {
// 注入容器中的dao对象(代理)
@Autowired
private UserDao userDao;
....
@Override
public void delete(Integer userId) {
userDao.delete(userId);
}
}
4、编写dao
public interface UserDao {
.....
/**
* 删除
* @param userId
*/
@Delete("delete from user where id=#{userId}")
void delete(Integer userId);
}
小贴士
关于异步的delete请求,有2种写法:
1、 本例中写法
$.ajax({
url:"/user/"+id,
type:"delete",
success:function (result) {
}
})
直接这样写就可以了!
后台处理delete请求:@RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
2、或者
2.1、请求方式设置为type:"post",
2.2、在data中加入 _method:"DELETE"参数 ,
2.3、后台的controller 仍为对应的DELETE 请求
2.4、配置HiddenHttpMethodFilter过滤器
2.4、参考如下
$.ajax({
url:"/user/"+id,
type:"POST",
data:{"_method":"DELETE"},
dataType:"json",
success:function(result){
}
}
新增下拉部门列表功能
需求
添加用户时候,要指定一个部门:(部门列表,需要异步加载)
列表要显示部门名称:
步骤
1、分析需求
部门列表: select * from 部门
添加用户: 同时保存用户的部门
用户列表: 显示部门名称
2、数据库设计
-- 创建部门表
CREATE TABLE dept(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(50)
);
INSERT INTO dept(NAME)VALUES('开发部'),('测试部');
SELECT * FROM dept
SELECT * FROM USER
-- 修改用户表: 添加一个部门id的字段
ALTER TABLE USER ADD COLUMN dept_id INT;
-- 修改用户表: 设置外键
ALTER TABLE `user` ADD CONSTRAINT fk_user_dept_id FOREIGN KEY(dept_id) REFERENCES dept(id);
3、开发步骤
A. 先完成用户列表显示部门名称
A1. 创建Dept实体类, 修改User对象,添加dept部门属性
A2. 修改dao,2表关联查询,查询用户、部门
A3. 测试dao查询 (..)
A4. user-list.jsp 显示部门
B. 再实现添加用户,异步加载部门下拉列表
B1. 查询所有部门:SELECT * FROM dept
B2. 部门dao
B3. 部门service
B4. 部门controller、依赖
B5. user-add.jsp 异步加载下拉列表
C. 保存用户,同时保存用户的部门
C1. 检查user-add.jsp 页面部门请求参数名称: dept.id
C2. 控制器,不用改
C3. service,不用改
C4. dao 修改sql语句