第一章:三层架构和MVC
1. 三层架构
- 咱们开发服务器端程序,一般都基于两种形式,一种C/S架构程序,一种B/S架构程序
- 使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构
- 三层架构
-
- 表现层:WEB层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型
-
- 业务层:处理公司具体的业务逻辑的
-
- 持久层:用来操作数据库的
2. MVC模型
- MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。
- Model:数据模型,JavaBean的类,用来进行数据封装。
- View:指JSP、HTML用来展示数据给用户
- Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等。
第二章:SpringMVC的入门案例
1. SpringMVC的概述
- 是一种基于Java实现的MVC设计模型的请求驱动类型的轻量级WEB框架。
- Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。
- 使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts2等。
2.快速入门
- 创建WEB工程,引入开发的jar包
具体的坐标如下
<!-- 版本锁定 -->
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
- 配置核心的控制器(配置DispatcherServlet)
<!-- SpringMVC的核心控制器:配置DispatcherServlet(请求分发器) -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置Servlet的初始化参数,加载springmvc.xml的配置文件,创建spring容器 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 配置servlet启动时加载springmvc.xml对象,启动级别:1 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<!-- /:只匹配所有的请求,不会匹配jsp-->
<!-- /*:匹配所有请求,包括jsp页面-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- 编写springmvc.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--启动tomcat就会加载springMVC.xml-->
<!-- 处理器映射器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- 处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 配置视图解析器:模拟引擎 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀后缀-->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- BeanNameUrlHandlerMapping:bean-->
<bean id="/hello" class="快速入门.Controller.HelloController"/>
</beans>
- 编写index.jsp和HelloController控制器类
//实现Controller接口,这个类就是控制器了
public class HelloController implements Controller {
//这是用ModelAndView返回的方式
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv=new ModelAndView();
//业务代码
String result="helloSpringMVC";
mv.addObject("msg",result);
//视图跳转
mv.setViewName("hello");
return mv;
}
}
- hello.jsp
<body>
<h3>入门案例</h3>
${msg}
</body>
注意:代码正确的情况下,有时候可能出现404,排查步骤:
1、查看控制台输出,看一下是不是缺少什么jar包
2、如果jar包存在,显示无法输出,就在idea项目中,添加lib依赖。
3、重启tomcat既可解决
3.流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FL0Smc5i-1587223551227)(mvc流程.png)]
具体流程:
(1)首先浏览器发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
(2)DispatcherServlet——>HandlerMapping,处理器映射器将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器对象、多个HandlerInterceptor拦截器)对象;
(3)DispatcherServlet——>HandlerAdapter,处理器适配器将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
(4)HandlerAdapter——>调用处理器相应功能处理方法,并返回一个ModelAndView对象(包含模型数据、逻辑视图名);
(5)ModelAndView对象(Model部分是业务对象返回的模型数据,View部分为逻辑视图名)——> ViewResolver, 视图解析器将把逻辑视图名解析为具体的View;
(6)View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构;
(7)返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。
4.入门案例中的组件分析
- 前端控制器(DispatcherServlet)
dispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet 的存在降低了组件之间的耦合性。
- 处理器映射器(HandlerMapping)
处理器映射器有三种,三种可以共存,相互不影响,分别是BeanNameUrlHandlerMapping、SimpleUrlHandlerMapping和ControllerClassNameHandlerMapping.
1、BeanNameUrlHandlerMapping:默认映射器,即使不配置,默认就使用这个来映射请求。
2、SimpleUrlHandlerMapping:该处理器映射器可以配置多个映射对应一个处理器.
3、ControllerClassNameHandlerMapping:该处理器映射器可以不用手动配置映射, 通过[类名.do]来访问对应的处理器.
- 处理器(Handler)
- 处理器适配器(HandlAdapter)
处理器适配器有两种,可以共存,分别是SimpleControllerHandlerAdapter和HttpRequestHandlerAdapter。
- 视图解析器(View Resolver)
- 视图(View)
SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。
5.注解使用
springMVC.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--启动tomcat就会加载springMVC.xml-->
<!-- 自动扫描包-->
<context:component-scan base-package="annotation"/>
<!--让springMVC不处理静态资源:静态资源过滤-->
<mvc:default-servlet-handler/>
<!-- 支持mvc注解驱动-->
<!-- 在spring中一般采用@RequestMapping注解来完成映射关系
要想使注解生效,必须注册DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter实例,
这两个实例分别在类级别和方法级别处理,
而annotation-driven配置帮助我们自动完成上述两个实例的注入 -->
<mvc:annotation-driven/>
<!-- 注意:
<mvc:annotation-driven/>为我们注册了映射器和适配器!
<mvc:annotation-driven>会自动注册RequestMappingHandlerMapping与RequestMappingHandlerAdapter两个Bean-->
<!-- 3、配置视图解析器:模拟引擎 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀后缀-->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
Controller类
/**
* 使用注解
*/
@Controller///这标签相当于实现Controller接口,就是控制类
public class annotationController {
/**
* @RequestMapping("/annotation")可以放在类上,表示类所有方法都必须经过这个路径
* 放在方法上,只表示这个方法经过这个路径
* 作用:用于建立请求 URL 和处理请求方法之间的对应关系。代替了<bean id="/annotation" class="annotation.Controller.HelloController"/>
*/
@RequestMapping("/annotation")
public String annotation(Model model) {
System.out.println("进入controller");
//封装数据(model是往前端发送数据)
model.addAttribute("msg","hello springMVC");
return "annotation";//会被视图解析器处理
}
}
注解案例的执行流程
1. 当启动Tomcat服务器的时候,因为配置了load-on-startup标签,所以会创建DispatcherServlet对象,就会加载springmvc.xml配置文件
2. 开启了注解扫描,那么HelloController对象就会被创建
3. 从(Controller类)/annotation全路径发送请求,请求会先到达DispatcherServlet核心控制器,根据配置@RequestMapping注解找到执行的具体方法
4. 根据执行方法的返回值,再根据配置的视图解析器,去指定的目录下查找指定名称的JSP文件
5. Tomcat服务器渲染页面,做出响应
@Controller注解
被这个注解的类中所有的方法,如果返回值是String类型,并且有具体页面可以跳转,那么就会被视图解析器解析。
注意:@RestController=@Controller+@ResponseBody
RequestMapping注解
1. RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系
2. RequestMapping注解可以作用在方法和类上
1. 作用在类上:第一级的访问目录
2. 作用在方法上:第二级的访问目录
3. 细节:路径可以不编写 / 表示应用的根目录开始
4. 细节:${ pageContext.request.contextPath }也可以省略不写,但是路径上不能写 /
注意:
当RequestMapping一样时,要加个父路径。如@RequestMapping("/t") 和 @RequestMapping("/A/t") //A是父路径,以此来区分
RequestMapping的属性
1. path 指定请求路径的url
2. value value属性和path属性是一样的
3. mthod 指定该方法的请求方式
4. params 指定限制请求参数的条件
5. headers 发送的请求中必须包含的请求头
6、RESTFUL风格
原来的访问风格:/restful?a=1&b=2
restful风格:/restful/1/2
方法里有参数时加上注解@PathVariable。
@PathVariable:路径变量
public String restful(@PathVariable int a, @PathVariable int b, Model model){//这里的a和b对应到@PathVariable注解的a和b。通过 @PathVariable 可以将URL中占位符参数{xxx}绑定到处理器类的方法形参中
restful风格:访问方式:GET、POST、DELETE、PUT以及PATCH
@RequestMapping(value = "/restful/{a}/{b}",method = RequestMethod.GET)
@GetMapping("/restful/{a}/{b}")//与上面的一样,get方式提交数据
restful风格的URL优点
- 结构清晰
- 符合标准
- 易于理解
- 扩展方便
- RESTFUL在传参会更安全。
7、转发和重定向
可以不配置视图解析器
写法
转发:
//跳转到:annotation页面
return "forward:/WEB-INF/jsp/annotation.jsp";//前面加个forward:
//跳转到:annotation路径,不是页面
return "forward:annotation";
重定向:
return "redirect:/index.jsp";//前面加个redirect:
第三章:请求参数的绑定(模块params)
要求:提交表单的name和参数的名称是相同的
注意:如果加注解@RequestParam就可以不一样。加@RequestParam表示是从前端传来的参数。如果不加注解,则参数名必须和表单(前端)传来的参数名一样
支持的数据类型
- 基本数据类型和字符串类型
- 实体类型(JavaBean)
- 集合数据类型(List、map集合等)
注意:
-
区分大小写
-
实体类型(JavaBean)
提交表单的name和JavaBean中的属性名称需要一致
如果一个JavaBean类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性 例如:
address.name -
给集合属性数据封装
-
JSP页面编写方式:list[0].属性
请求参数中文乱码的解决(post提交可能出现中文乱码问题)
- 在web.xml中配置Spring提供的过滤器类
<!-- 配置过滤器,解决中文乱码的问题 ,放在前面才能起作用-->
<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>
日期转换格式
1.在bean中加注解,如@DateTimeFormat(pattern = “yyyy-MM-dd”)
2. 自定义类型转换器
- 表单提交的任何数据类型全部都是字符串类型,但是后台定义Integer类型,数据也可以封装上,说明
Spring框架内部会默认进行数据类型转换。 - 如果想自定义数据类型转换,可以实现Converter的接口
//自定义类型转换器
public class StringToDateConverter implements Converter<String, Date> {
/**
* 用于把 String 类型转成日期类型
*/
@Override
public Date convert(String source) {
DateFormat format = null;
try {
if(StringUtils.isEmpty(source)) {
throw new NullPointerException("请输入要转换的日期");
}
format = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse(source);
return date;
} catch (Exception e) {
throw new RuntimeException("输入日期有误");
}
}
}
- 注册自定义类型转换器,在springmvc.xml配置文件中编写配置
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<!-- 自己写的类型转换器 -->
<bean class="params.StringToDateConverter"/>
</set>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService"/><!--conversion-service="conversionService"是注册日期转换器-->
第四章:常用的注解
@RequestParam注解
作用:把请求中的指定名称的参数传递给控制器中的形参赋值(即使和bean的属性名不一样也能用)
属性
value:请求参数中的名称
required:请求参数中是否必须提供此参数,默认值是true,必须提供
defaultValue:默认值
@PathVariable注解
作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符
属性
1. value:指定url中的占位符名称
@ResponseBody注解
作用:将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body去。
通常用来返回JSON数据或者是XML数据,需要注意的呢,在使用此注解之后不会再走试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。
第五章:json
json是一种字符串格式
要实现从JSON字符串转换为JavaScript对象,使用 JSON.parse() 方法:
要实现从JavaScript对象转换为JSON字符串,使用 JSON.stringify() 方法:
ResponseBody 响应 json数据
- 使用JackSon,导入jar包
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.3</version>
</dependency>
- 配置SpringMVC配置
<!-- 扫描包 -->
<context:component-scan base-package="annotation,RestFul,重定向,params,Json"/>
<mvc:annotation-driven>
<!-- 解决乱码问题 -->
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="utf-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperBuilder">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
乱码问题
方法一:使用(produces = “application/json; charset=utf-8”):
方法二 使用RequestMappingHandlerAdapter:
<!-- 解决@ResponseBody返回中文乱码,必须放在<mvc:annotation-driven>之前 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="writeAcceptCharset" value="false" /> <!-- 用于避免响应头过大 -->
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
<value>applicaiton/javascript;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
例子
//jackson
ObjectMapper mapper = new ObjectMapper();//固定写法
//创建一对象
user user = new user(1,"麦","123");
String string = mapper.writeValueAsString(user);
// return user.toString();
return string;//固定写法,返回json字符串
}
附注: FastJson也是非常好用的
第六章:Ajax
-
配置web.xml 和 springmvc的配置文件,复制上面案例的即可。 记得静态资源过滤和注解驱动配置上
<mvc:default-servlet-handler /> <mvc:annotation-driven />
-
经常用到jquery,所以记住导入jquery包。
导入jquery , 可以使用在线的CDN , 也可以下载导入<!-- 这里使用在线的CDN导入 --> <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
-
ajax一般写法:
<script> function a1(){ $.post({ url:"${pageContext.request.contextPath}/ajax/ajaxTest", data:{'name':$("#username").val()},//注意:name是后台的参数,username是前端的参数(id名) success:function (data) { //根据Controller类的方法传进来的值来判断颜色 if (data=='ok'){ $("#userInfo").css("color","green"); }else { $("#userInfo").css("color","red"); } $("#userInfo").html(data); } }); } </script> 用户名:<input type="text" id="username" onblur="a1()"/> <span id="userInfo"></span>
-
后台
public String ajaxTest(String name){ String msg=""; //模拟数据库中存在数据 if (name!=null){ if ("admin".equals(name)){ msg="ok"; }else { msg="用户名输入错误"; } } return msg;
参考练习见模块Ajax
注意:前端的参数和后台参数需要对应。如://注意:name是后台的参数,username是前端的参数(id名)
第七章:拦截器(interceptor)
拦截器配置
<mvc:interceptors>
<mvc:interceptor>
<!-- /**:包括这个请求下面的所有请求都会被拦截-->
<mvc:mapping path="/**"/>
<bean class="interceptor.Config.myInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
拦截器需继承接口HandlerInterceptor
/**
* 自定义的拦截器,需继承接口
*/
//继承HandlerInterceptor接口
public class myInterceptor implements HandlerInterceptor {
/**
* 这三个方法是实现HandlerInterceptor接口的方法.不是强制必须实现的
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override//前置拦截器
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("=======处理前=========");
//return true:执行下一个拦截器
//return false:不执行下一个拦截器
return false;
}
@Override//核心拦截器
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("=======处理后=========");
}
@Override//后置拦截器
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("=======清理=========");
}
}
第八章:文件上传
Servlet3.0规范已经提供方法来处理文件上传,但这种上传需要在Servlet中完成。
而Spring MVC则提供了更简单的封装。
Spring MVC为文件上传提供了直接的支持,这种支持是用即插即用的MultipartResolver实现的。
Spring MVC使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。因此,SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件。
一、导入文件上传的jar包
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<!--servlet-api导入高版本的-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
二、配置bean:multipartResolver
<!--文件上传配置-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
<property name="defaultEncoding" value="utf-8"/>
<!-- 上传文件大小上限,单位为字节(10485760=10M) -->
<property name="maxUploadSize" value="10485760"/>
<property name="maxInMemorySize" value="40960"/>
</bean>
CommonsMultipartFile类 的 常用方法:
String getOriginalFilename():获取上传文件的原名
InputStream getInputStream():获取文件流
void transferTo(File dest):将上传文件保存到一个目录文件中
三、编写前端页面
<form action="/upload" enctype="multipart/form-data" method="post">
<input type="file" name="file"/>
<input type="submit" value="upload">
</form>
四、Controller
@Controller
public class FileController {
//@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象
//批量上传CommonsMultipartFile则为数组即可
@RequestMapping("/upload")
public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {
//获取文件名 : file.getOriginalFilename();
String uploadFileName = file.getOriginalFilename();
//如果文件名为空,直接回到首页!
if ("".equals(uploadFileName)){
return "redirect:/index.jsp";
}
System.out.println("上传文件名 : "+uploadFileName);
//上传路径保存设置
String path = request.getServletContext().getRealPath("/upload");
//如果路径不存在,创建一个
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
System.out.println("上传文件保存地址:"+realPath);
InputStream is = file.getInputStream(); //文件输入流
OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流
//读取写出
int len=0;
byte[] buffer = new byte[1024];
while ((len=is.read(buffer))!=-1){
os.write(buffer,0,len);
os.flush();
}
os.close();
is.close();
return "redirect:/index.jsp";
}
}
SSM练习模块
导入依赖
<dependencies>
<!-- 依赖:junit、数据库驱动、连接池、servlet、jsp、mybatis、mybatis-spring、spring-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- 数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!-- 连接池-->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!--
https://mvnrepository.com/artifact/org.mybatis/mybatis
-->
<!-- mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.3</version>
</dependency>
<!-- spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<!--servlet、jsp-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
<!-- 前端网页需要引入jstl美化界面-->
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
Maven资源过滤设置
<!-- mybatis:所有的maven项目都需要加进去这个文件,在父,子pom.xml里都需要加入一下代码 -->
<!--在build中配置resources,来防止我们资源导出失败的问题-->
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
- mybatis-config.xml
<?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核心配置文件 -->
<configuration>
<!-- 不知道为什么用database.properties不行,所以不用了-->
<!-- <properties resource="database.properties"/> -->
<typeAliases>
<package name="ssm_springMVC.POJO"/>
</typeAliases>
<!-- 在spring-dao配置 -->
<!--<environments default="development">-->
<!-- <environment id="development">-->
<!-- <transactionManager type="JDBC"/>-->
<!-- <dataSource type="POOLED">-->
<!-- <property name="driver" value="com.mysql.jdbc.Driver"/>-->
<!-- <property name="url" value="jdbc:mysql://localhost:3306/ssm?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai"/>-->
<!-- <property name="username" value="root"/>-->
<!-- <property name="password" value="3105311"/>-->
<!-- </dataSource>-->
<!-- </environment>-->
<!--</environments>-->
<!--每一个Mapper.xml都需要在mybatis-config.xml核心配置文件中注册-->
<mappers>
<mapper class="SSM1.dao.bookMapper"/>
</mappers>
</configuration>
- Spring整合Mybatis的相关的配置文件(spring-dao)
<?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">
<!-- Spring整合Mybatis的相关的配置文件; spring-dao.xml-->
<!-- 不知道为什么用database.properties不行,所以不用了-->
<!--关连数据库配置文件-->
<!-- <context:property-placeholder location="classpath:database.properties"/> -->
<!-- 2、连接池
dbcp:半自动化操作,不能自动连接
C3P0:自动化操作(自动化的加载配置文件,并且可以自动设置到对象中)
druid
hikari
-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ssm?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai"/>
<property name="user" value="root"/>
<property name="password" value="475035"/>
</bean>
<!-- 3、sqlSessionFactory,这是mybatis工具类-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 绑定mybatis的配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!-- 4、配置dao接口扫描包,动态实现dao接口可以注入到spring容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- 扫描dao包-->
<property name="basePackage" value="SSM1.dao"/>
</bean>
</beans>
注意:没实现类时用动态扫描接口
<!-- 4、配置dao接口扫描包,动态实现dao接口可以注入到spring容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- 扫描dao包-->
<property name="basePackage" value="SSM1.dao"/>
</bean>
MapperScannerConfigurer类的作用:相当于核心配置文件的包注册-<package name="mapper"/>
- springMVC配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置SpringMVC -->
<!--注解驱动-->
<mvc:annotation-driven/>
<!--静态资源过滤-->
<mvc:default-servlet-handler/>
<!--扫描包-->
<context:component-scan base-package="ssm_springMVC.Controller"/>
<!--视图解析器-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
- spring-service.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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd" >
<!--1、扫描service下的包-->
<context:component-scan base-package="ssm_springMVC.service"/>
<!-- 2、将我们所有业务类注入到spring,可以通过配置或者注解实现-->
<bean id="bookServiceImpl" class="ssm_springMVC.service.bookServiceImpl">
<property name="bookMapper" ref="bookMapper"/>
</bean>
<!-- 3、 声明式事务管理-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 4、 注入数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
- 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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd" >
<!-- 将dao、service和mvc全部导进到spring核心配置文件 -->
<import resource="spring_dao.xml"/>
<import resource="spring_service.xml"/>
<import resource="spring_mvc.xml"/>
</beans>
SSM整合:Mybatis
实现图书查询管理功能
- book——(实体bean)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class book {
private int id;
private String name;
private int counts;
private String detail;
}
- bookMapper接口
public interface bookMapper {
//增加
int addBook(book book);
//删除一本书
int deleteBook(int id);
//更新
int updateBook(book book);
//查询
book queryBook(int id);
//查询所有书
List<book> queryAllBook();
}
- bookMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="bookMapper">
<insert id="addBook" parameterType="book">
insert into ssm.book (name, counts, detail) values (#{name},#{counts},#{detail});
</insert>
<delete id="deleteBook" parameterType="int">
delete from ssm.book where id=#{id};
</delete>
<update id="updateBook" parameterType="book">
update ssm.book set name=#{name},counts=#{counts},detail=#{detail}
where id=#{id};
</update>
<select id="queryBook" parameterType="int">
select * from ssm.book where id=#{id};
</select>
<select id="queryAllBook" resultType="book">
select * from ssm.book;
</select>
</mapper>
- service层(和dao层相似内容)
- service接口
public interface bookService {
//增加
int addBook(book book);
//删除一本书
int deleteBook(int id);
//更新
int updateBook(book book);
//查询
book queryBook(int id);
//查询所有书
List<book> queryAllBook();
//查询框功能
book queryBookByName(String name);
}
- service实现类
public class bookServiceImpl implements bookService{
// service调用dao层:组合dao
private bookMapper bookMapper;
public bookServiceImpl(SSM1.dao.bookMapper bookMapper) {
this.bookMapper = bookMapper;
}
public void setBookMapper(SSM1.dao.bookMapper bookMapper) {
}
@Override
public int addBook(book book) {
System.out.println("增加书本");
return bookMapper.addBook(book);
}
@Override
public int deleteBook(int id) {
System.out.println("减少书本");
return bookMapper.deleteBook(id);
}
@Override
public int updateBook(book book) {
System.out.println("更新书本");
return bookMapper.updateBook(book);
}
@Override
public book queryBook(int id) {
System.out.println("查询书本");
return bookMapper.queryBook(id);
}
@Override
public List<book> queryAllBook() {
System.out.println("查询所有书本");
return bookMapper.queryAllBook();
}
@Override
public book queryBookByName(String name) {
System.out.println("想查询什么书籍");
return bookMapper.queryBookByName(name);
}
}
整合springMVC
control层
@Controller
@RequestMapping("/book")
public class bookController {
//Controller调service层
@Autowired
@Qualifier("bookServiceImpl")
public bookService bookService;
//查询全部书籍,并且返回前端书籍展示页面
@RequestMapping("/allBook")
public String list(Model model){
List<book> books = bookService.queryAllBook();//bookService—>bookMapper——>book(由bookService一直找到book对象,操作到数据库)
model.addAttribute("list",books);
return "allBook";//跳转到allBook.jsp
}
/**
* 前面带to字段的方法都是跳转页面的方法
* @return
*/
//跳转到增加书籍页面
@RequestMapping("/toAddBook")//前端新增书籍按钮跳转到这个方法并返回addBook字符串
public String toAddBook(){
return "addBook";
}//跳进addBook.jsp页面
//增加书籍方法
@RequestMapping("/addBook")
public String addBook(book book){//addBook.jsp页面传来book数据
System.out.println("addBook"+book);
bookService.addBook(book);
return "redirect:/book/allBook";//重定向到上面的allBook请求。达到方法复用
}
//跳转到修改书籍页面,并附带要修改的书籍信息
@RequestMapping("/toUpdateBook")
public String toUpdateBook(int id,Model model){
book queryBook = bookService.queryBook(id);//将要修改书本的id和其他信息传到model并返回updateBook页面
model.addAttribute("QBook",queryBook);//返回book对象,query方法必须添加resultType="book"
return "updateBook";
}
//修改书籍方法
@RequestMapping("/updateBook")
public String updateBook(book book){
System.out.println("updateBook"+book);
bookService.updateBook(book);//需要提交事务,否则修改无效
return "redirect:/book/allBook";//重定向到上面的allBook请求。达到方法复用
}
//前端删除按钮跳转到该方法实现删除功能
// @RequestMapping("/toDeleteBook")
// public String toDeleteBook(int id){
// int deleteBook = bookService.deleteBook(id);
// return "redirect:/book/allBook";//重定向到上面的allBook请求。达到方法复用
// }
/**
* restful风格实现delete
* @param id
* @return
*/
@RequestMapping("/toDeleteBook/{id}")
public String toDeleteBook(@PathVariable("id") int id){
bookService.deleteBook(id);
return "redirect:/book/allBook";//重定向到上面的allBook请求。达到方法复用
}
//查询功能
@RequestMapping("/toQueryBook")
public String toQueryBook(String queryBookName, Model model){
book book = bookService.queryBookByName(queryBookName);
List<book> list = new ArrayList<book>();
list.add(book);
//查询优化
if (book==null){
list= bookService.queryAllBook();
model.addAttribute("error","未查到书籍");
}
model.addAttribute("list",list);//list到时候会在allBook遍历用到
// return "redirect:/book/allBook";//不能重定向到上面的allBook请求。因为会重新查询所有书籍
return "allBook";//只能转发,才能查询单一书籍
}
}