文章目录
SSM整合开发(实现增删改)
SpringMVC+Spring+Mybatis—>视图+service+dao(持久层)
SpringMVC:视图层,表示层。负责接收请求,显示处理结果的
Spring:业务层,管理service,dao,工具类对象的
Mybatis:持久层,访问数据库的
SSM整合也叫做SSI(I是Ibatis的意思,是Mybatis的前身),整合中有容器
- 第一个容器是SpringMVC,管理Controller控制器对象的
- 第二个容器是Spring,管理Service,Dao,工具类对象的
我们要做的把使用的对象交给合适的容器创建,管理。
那么两个容器之间怎么进行沟通呢?
两者是有关系的,并且是确定好的,SpringMVC是Spring的子容器,类似java的继承,子容器中的controller可以访问父容器的service
实现步骤
0.使用Springdb的mysql库,使用表stu(id auto_increment,name,age)
1.新建maven项目
2.加入依赖
springmvc spring mybatis jackson mysql druid jsp servlet
3.写web.xml
1)注册中央调度器:目的 1.创建sevlet接收请求
2.创建springmvc容器,才能创建并转发给controller
2)注册spring的监听器:ContextLoaderListener,目的:创建spring的容器对象,才能创建service,dao等对象
3)注册字符集过滤器
4.创建包,controller service dao 实体类
5.写springmvc spring mybatis的配置文件
1)springmvc配置文件
2)spring配置文件
3)mybatis配置文件
4)数据库的配置文件
6.写代码,dao和mapper文件,service和实现类,controller,实体类
7.jsp视图
sql表
CREATE TABLE `stu` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(80) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
pom.xml加入依赖
<dependencies>
<!-- 单元测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- spring依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- springmvc依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- mybatis和spring联合依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!-- mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!-- 事务依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- 事务依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- jackson依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<!-- sql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<!-- druid数据连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<!-- jsp-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
web.xml
注册中央调度器
<!--配置中央调度器-->
<servlet>
<servlet-name>myweb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--自定义springmvc读取配置文件的位置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/dispatcherServlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>myweb</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
tip:中央调度器的处理路径是“*.do”或者“/”的区别?
当项目中使用了 / ,他会替代tomcat中的default,导致所有的静态资源都给DispatcherServlet处理,默认情况下DispatcherServlet是不处理静态文件的。所以此时对静态资源的访问都是404
动态资源some.do可以访问,因为我们程序中与对应的controller来处理some.do的请求
那如果想访问静态资源呢?
<!--方法一-->
在springmvc中加入标签<mvc:default-servlet-handler/>
因为在使用了这个标签之后,框架在容器中会创建一个DefaultServletHttpRequestHandler处理器对象,该对象可以把接收的请求给tomcat的default的servlet
<!--方法二-->
<mvc:resources/>
使用了该标签之后,框架在同其中会创建一个ResourceHttpRequestHandler处理器对象,不依赖tomcat服务器,自己去处理静态资源的访问
参数:
mapping:访问静态资源的uri地址,使用通配符**
lacation:静态资源在你项目中的目录位置
<mvc:resources mapping="/images/**" location="/images"/>
<mvc:resources mapping="/html/**" location="/html"/>
<mvc:resources mapping="/js/**" location="/js"/>
项目中一般会把静态资源文件放在static包下,统一管理,所以配置文件中只需要一行
<mvc:resources mapping="/static/**" location="/static"/>
注册spring监听器
<!-- 注册spring监听器,spring容器只需要创建一次,如果tomcat运行,将容器对象放在全局作用域对象中,就创建spring容器-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/contextLoaderListener.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
注册字符集过滤器
<!-- 注册字符集过滤器-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--设置属性CharacterEncodingFilter-->
<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>
springmvc配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<!--组件扫描器,找controller注解的类-->
<context:component-scan base-package="com.bjpowernode.controller"/>
<!--视图解析器,用来简化视图的输出路径-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--注解驱动
功能:1.底层调用 消息转换器 HttpMessageConverter 响应ajax来完成java对象到json,xml,text以及二进制等数据格式的转换
2.处理静态资源也要使用到该注解驱动-->
<mvc:annotation-driven/>
</beans>
特别注意
上边的驱动注册,需要指定的annotation-driven是==springframework.org/schema/mvc==下的
spring配置文件
<?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配置文件,声明service,dao,工具类等对象-->
<!--声明数据源,连接数据库-->
<context:property-placeholder location="classpath:conf/jdbc.properties"/> <!--sql属性文件的路径位置-->
<!--声明数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <!--后两个是固定方法声明-->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--SqlSessionFactoryBean 目的:mybatis的SqlSessionFactory的创建-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/> <!--设置数据源-->
<property name="configLocation" value="classpath:conf/mybatis.xml"/> <!--设置mybatis配置文件位置,mybatis配置文件可以进
setting-editor-file and code templates 进行创建-->
</bean>
<!--声明mybatis的扫描器,创建dao对象,让对应包下的所有接口都可以创建dao对象,从而访问数据库-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.bjpowernode.dao"/>
</bean>
<!--声明service的注解 @Service所在的包名位置-->
<context:component-scan base-package="com.bjpowernode.service"/>
<!--事务的配置:注解的配置和 aspectj的配置-->
<!--小型项目使用@Transactional接口-->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"/>
<!--需要在对应的方法上加@Transactional注解-->
<!--大型项目使用aspectj框架,将业务和事务配置完全分离开-->
<tx:advice id="myAdvice" transaction-manager="dataSourceTransactionManager">
<tx:attributes>
<tx:method name="addStudent" isolation="DEFAULT" propagation="REQUIRED"
rollback-for="java.lang.NullPointerException"/>
</tx:attributes>
</tx:advice>
</beans>
mybatis.xml配置文件
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!-- 设置别名-->
<typeAliases>
<!-- name:实体类所在的报名-->
<package name="com.bjpowernode.domain"/>
</typeAliases>
<mappers>
<!-- name:报名,这个包中的所有mapper.xml一次都能加载-->
<package name="com.bjpowernode.dao"/>
<!--使用package的要求
1.mapper文件名称和dao接口名必须完全一样,包括大小写
2.mapper文件和dao接口必须在同一个目录
-->
</mappers>
</configuration>
代码目录结构
src
-main
-java
-com
-bjpowernode
-controller
StudentController.class//控制类
-dao
StudentDao.class //dao接口
StudentDao.xml //配置对应的mapper
-domain
Student //实体类
-service
StudentService //业务接口
-impl
StudentServiceImpl
-resources
-cong
contextLoaderListener.xml //spring.xml
dispatcherServlet.xml //springmvc.xml
jdbc.properties //数据库信息配置文件
mybatis.xml //mybatis.xml
-webapp
-images
-js
jquery //ajax
-jsp
regiester.jsp//注册页面
listStudent.jsp//查询页面
-WEB-INF
-jsp
result.jsp
web.xml
index.jsp
实体类
package com.bjpowernode.domain;
public class Student {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
dao持久层
package com.bjpowernode.dao;
import com.bjpowernode.domain.Student;
import java.util.List;
public interface StudentDao {
int insertStudent(Student student);
List<Student> selectStudents();
}
<?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="com.bjpowernode.dao.StudentDao">
<select id="selectStudents" resultType="Student">
select id,name,age from stu order by id desc
</select>
<insert id="insertStudent">
insert into stu(name,age) values (#{name},#{age})
</insert>
</mapper>
service业务层
package com.bjpowernode.service;
import com.bjpowernode.domain.Student;
import java.util.List;
public interface StudentService {
int addStudent(Student student);
List<Student> findStudents();
}
package com.bjpowernode.service.impl;
import com.bjpowernode.dao.StudentDao;
import com.bjpowernode.domain.Student;
import com.bjpowernode.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service //对应spring.xml中的注解扫描器
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentDao studentDao;
@Override
public int addStudent(Student student) {
int nums=studentDao.insertStudent(student);
return nums;
}
@Override
public List<Student> findStudents() {
List<Student> students=new ArrayList<>();
students=studentDao.selectStudents();
return students;
}
}
controller视图层
package com.bjpowernode.controller;
import com.bjpowernode.domain.Student;
import com.bjpowernode.service.StudentService;
import com.bjpowernode.service.impl.StudentServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import java.util.ArrayList;
import java.util.List;
@Controller
@RequestMapping("/student") //请求映射包 /student
public class StudentController {
@Autowired
StudentService service=new StudentServiceImpl();
//注册学生
@RequestMapping("/addStudent.do")
public ModelAndView addStudent(Student student){
ModelAndView mv=new ModelAndView();
String tips="注册失败";
//调用service处理student
int nums=service.addStudent(student);
if (nums>0){
//注册成功
tips="学生"+student.getName()+"注册成功";
}
//添加数据
mv.addObject("tips",tips);
mv.setViewName("result");
return mv;
}
@RequestMapping(value = "/queryStudents.do") //请求映射,将中央调度器得到对应请求就来找该方法
@ResponseBody
//处理查询,响应ajax
public List<Student> queryStudents(){
List<Student> list=new ArrayList<>();
list=service.findStudents();
return list;
}
}
js
jquery-3.4.1.js
可访问静态资源
index.jsp
<%--
Created by IntelliJ IDEA.
User: asus
Date: 2022/3/13
Time: 15:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<% String basePath = request.getScheme()+"://"+ <!--用来获取项目路径-->
request.getServerName()+":"+request.getServerPort()+
request.getContextPath()+"/";%>
<head>
<title>功能入口</title>
<base href="<%=basePath%>"/>
</head>
<body>
<div align="center">
<img src="images/机车.jpg" alt="我是一个静态资源,不能显示" height="100" width="200"/>
<p>学生注册系统(SSM)</p>
<table>
<tr>
<td >
<a href="jsp/regiester.jsp">注册学生</a>
</td>
</tr>
<tr>
<td>
<a href="jsp/listStudent.jsp">浏览学生</a>
</td>
</tr>
</table>
</div>
</body>
</html>
regiester.jsp
<%--
Created by IntelliJ IDEA.
User: asus
Date: 2022/3/13
Time: 16:37
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<% String basePath = request.getScheme()+"://"+
request.getServerName()+":"+request.getServerPort()+
request.getContextPath()+"/";%>
<head>
<title>注册学生</title>
<base href="<%=basePath%>"/>
</head>
<body>
<div align="center">
<form action="student/addStudent.do" method="post">
<table border="1" >
<tr>
<td>学生姓名</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>学生年龄</td>
<td><input type="text" name="age"></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="注册提交"></td>
</tr>
</table>
</form>
</div>
</body>
</html>
listStudent.jsp
<%--
Created by IntelliJ IDEA.
User: asus
Date: 2022/3/13
Time: 17:02
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<%
String basePath = request.getScheme()+"://"+
request.getServerName()+":"+request.getServerPort()+
request.getContextPath()+"/";
%>
<head>
<title>学生查询</title>
<base href="<%=basePath%>"/>
<script type="text/javascript" src="js/jquery-3.4.1.js"></script>
<script type="text/javascript">
$(function (){ <!--入口函数-->
// $("#btn").click(function (){<!--按钮点击函数-->
$.ajax({ <!--ajax请求-->
url:"student/queryStudents.do",
type:"get",
dataType:"json",
success:function (data){//如果成功则,这个函数的参数可以任意定义名称
//清楚就出局
$("#info").html("");
// 清理之后加载数据
$.each(data,function (i,n){
$("#info").append("<tr>") //在body
.append("<td>"+n.id+"</td>")
.append("<td>"+n.name+"</td>")
.append("<td>"+n.age+"</td>")
.append("</tr>")
})
}
})
})
// })
function help(){
$.ajax({
url:"student/queryStudents",
type: "get",
dataType: "json",
success:function(data){
$("#info").html("");
$.each(data,function (i,n){
$("#info").append("<tr>")
.append("<td>"+n.id+"</td>")
.append("<td>"+n.name+"</td>")
.append("<td>"+n.age+"</td>")
.append("</tr>")
})
}
})
}
</script>
</head>
<body>
<div align="center">
<table>
<thead>
<tr>
<td>学号</td>
<td>姓名</td>
<td>年龄</td>
</tr>
</thead>
<tbody id="info">
</tbody>
</table>
<input type="button" id="btn" value="查询数据">
</div>
</body>
</html>
禁止访问静态资源
result.jsp
<%--
Created by IntelliJ IDEA.
User: asus
Date: 2022/3/13
Time: 15:44
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
result.jsp 结果页面
注册结果 ${tips}
</body>
</html>
tips:没写展示表单之前可以使用简单测试的方法,直接访问对应的jsp地址看时候得到对应的json数据