1. 整合SSM
SSM : Spring、SpringMVC、MyBatis
一个SSM项目需要三层共同协作来实现,每层完成各自各功能,这样做有利于将层次模块化,提高解耦合能力。
下面根据SSM来实现一个简答的而学生管理功能。
2. 准备工作
2.1 数据库环境
通过一张简单的学生表来实现SSM的后续工作,SQL语句如下
CREATE TABLE `student`(
`id` INT(10) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(40) NOT NULL,
`password` VARCHAR(20) NOT NULL,
PRIMARY KEY `id` (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `student`(`username`, `password`) VALUES("张三","123456"),("李四","123456"),("王五","123456");
2.2 依赖配置
在pom.xml
中需要配置的依赖有很多,本次用到了11个依赖,分别包括:
junit
:单元测试lombok
:自动资源管理mybatis
:MyBatis数据映射mybatis-spring
:MyBatis SQL映射框架spring-webmvc
:Spring Web MVCspring-jdbc
:Spring JDBCmysql-connector-java
:连接MySQLservlet-api
:Java Servlet APIjsp-api
:JavaServer Pages™ APIjstl
:JSP 标准标签库c3p0
:JDBC连接池/语句缓存库
MyBatis:
mysql-connector-java
、mybatis
Spring:
mybatis-spring
、spring-jdbc
Spring MVC:
spring-webmvc
、servlet-api
、jsp-api
Others:
jstl
、junit
、lombok
、c3p0
2.3 Web/Tomcat
在项目或模块上右键点击Add Framework Support
,选择Web Application
。
在项目或模块上添加Tomcat。
2.4 版本说明
JDK:1.8
Tomcat:8.5.39(不用9是因为在JSTL那出错了)
MySQL:8.0(mysql-connector-java
对应到8)
2.5 资源过滤
在pom.xml
文件中配置Maven资源过滤。
3. MyBatis层
MyBatis层包括:
- 数据库配置文件
database.properties
; - POJO;
- MyBatis配置文件
- Mapper接口/映射
- Service、ServiceImpl
3.1 数据库配置文件
jdbc.driverclass=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?useSSL=true&useUnicode=true&charsetEncoding=utf8&severTimezone=GMT
jdbc.username=root
jdbc.password=xxxx
3.2 POJO
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private int id;
private String username;
private String password;
}
3.3 MyBatis配置文件
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="com.POJO"/>
</typeAliases>
3.4 Mapper接口
public interface StudenMapper {
// 获取全部学生
List<Student> queryAll();
// 根据Username获取学生,模糊查询
List<Student> queryByName(String name);
// 根据ID获取学生信息
Student queryByID(int id);
// 添加学生
int insert(Student student);
// 删除学生
int delete(int id);
// 修改学生信息
int update(Student student);
}
3.5 Mapper映射
<mapper namespace="com.Mapper.StudenMapper">
<select id="queryAll" resultType="student">
select *
from student
</select>
<select id="queryByName" resultType="student">
select *
from student
where id like '%${username}%'
</select>
<select id="queryByID" resultType="student">
select *
from student
where id = #{id}
</select>
<insert id="insert" parameterType="student">
insert into student(username, paswword)
values (#{username}, #{password})
</insert>
<delete id="delete" parameterType="int">
delete
from student
where id = #{id}
</delete>
<update id="update" parameterType="student">
update student
set username = #{username},
password = #{password}
where id = #{id}
</update>
</mapper>
3.6 Service
public interface StudentService {
// 获取全部学生
List<Student> queryAll();
// 根据Username获取学生,模糊查询
List<Student> queryByName(String name);
// 根据ID获取学生信息
Student queryByID(int id);
// 添加学生
int insert(Student student);
// 删除学生
int delete(int id);
// 修改学生信息
int update(Student student);
}
3.7 ServiceImpl
public class StudentServiceImpl implements StudentService{
private StudentMapper studentMapper;
public void setStudentMapper(StudentMapper studentMapper) {
this.studentMapper = studentMapper;
}
@Override
public List<Student> queryAll() {
return studentMapper.queryAll();
}
@Override
public List<Student> queryByName(String name) {
return studentMapper.queryByName(name);
}
@Override
public Student queryByID(int id) {
return studentMapper.queryByID(id);
}
@Override
public int insert(Student student) {
return studentMapper.insert(student);
}
@Override
public int delete(int id) {
return studentMapper.delete(id);
}
@Override
public int update(Student student) {
return studentMapper.update(student);
}
}
4. Spring层
Spring层这里主要配置xml文件:
spring-mapper.xml
:- 配置数据库连接池
- 配置连接属性
- 配置SqlSessionFactory对象
- 配置扫描Mapper接口包
spring-service.xml
:- 为Service配置注解扫描
- 配置ServiceImpl
- 配置事务管理器
4.1 Mapper
4.1.1 关联properties
<context:property-placeholder location="classpath:database.properties"/>
4.1.2 配置连接池
<bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
<property name="driverClass" value="${jdbc.driverclass}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!--配置连接属性-->
<property name="maxPoolSize" value="20"/>
<property name="minPoolSize" value="10"/>
<property name="checkoutTimeout" value="10000"/>
<property name="autoCommitOnClose" value="false"/>
<property name="acquireRetryAttempts" value="2"/>
</bean>
maxPoolSize
:最大连接条数
minPoolSize
:最小连接条数
checkoutTimeout
:连接超时时间
autoCommitOnClose
:当值为false时为关闭自动提交
acquireRetryAttempts
:连接失败重复次数
4.1.3 SqlSessionFactory
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.XML"/>
<property name="mapperLocations" value="classpath*:com/Mapper/*.xml"/>
</bean>
4.1.4 MapperScannerConfigurer
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" id="mapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.Mapper"/>
</bean>
4.2 Service
4.2.1 注解扫描
<context:component-scan base-package="com.Service"/>
4.2.2 注入StudentServiceImpl
<bean class="com.Service.StudentServiceImpl" id="studentService">
<property name="studentMapper" ref="studentMapper"/>
</bean>
4.2.3 事务管理
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="dataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
5. Spring MVC 层
Spring MVC 层包括:
web.xml
:- 映射servlet
- 配置DispatcherServlet
- 配置ApplicationContext
- 配置加载级别
- 过滤器处理乱码
- 设置Session过期时间
spring-mvc
:- 配置扫描Controller、注解驱动、不加载静态资源
- 配置视图解析器、前缀、后缀
ApplicationContext
:- 整合配置文件
5.1 web.xml
5.1.1 配置Servlet
<servlet>
<servlet-name>SpringMVC_Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:ApplicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC_Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
5.1.2 配置Filter
<filter>
<filter-name>CharacherEnconding-Filter</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>CharacherEnconding-Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
5.2 spring-mvc
5.2.1 配置扫描、驱动、禁止静态资源
<context:component-scan base-package="com.Controller"/>
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
5.2.2 ViewResolver
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
5.3 ApplicationContext
<import resource="spring-service.xml"/>
<import resource="spring-mapper.xml"/>
<import resource="spring-mvc.xml"/>
6. Controller&View
下面更具具体更共能将Controller与View串起来。
6.1 全查功能
6.1.1 index.jsp
<a href="${pageContext.request.contextPath}/queryAll">前往学生管理页面</a>
6.1.2 Controller
@Controller
public class StudentController {
@Autowired
@Qualifier("studentService")
private StudentService studentService;
@RequestMapping("/queryAll")
public String queryAll(Model model) {
List<Student> studentList = studentService.queryAll();
model.addAttribute("studentList",studentList);
return "allStudent";
}
}
6.1.3 allStudent.jsp
全查页面通过jstl来获取Controller过来的list,并利用for each输出。
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<table style="border: 1px #424242; background-color: aliceblue">
<tr>
<td>学生编号</td>
<td>学生姓名</td>
<td>学生密码</td>
<td>操作</td>
</tr>
<tbody>
<c:forEach var="student" items="${studentList}">
<tr>
<td>${student.id}</td>
<td>${student.username}</td>
<td>${student.password}</td>
<td>
<a href="${pageContext.request.contextPath}/delete/${student.id}">删除</a>
/
<a href="${pageContext.request.contextPath}/updatePage?id=${student.id}">修改</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
6.1.4 输出测试
6.2 模糊查询
6.2.1 allStudent.jsp
<form method="post" action="${pageContext.request.contextPath}/queryByName">
<input name="queryByName" type="text" placeholder="请输入要查询的姓名">
<input type="submit" value="查询">
</form>
6.2.2 Controller
@RequestMapping("/queryByName")
public String queryByName(String queryByName, Model model) {
if(queryByName.trim().equals("")){
return "redirect:/queryAll";
}
List<Student> studentList = studentService.queryByName(queryByName);
model.addAttribute("studentList", studentList);
return "allStudent";
}
⚠️ 注意:向前端页面返回的list放在model里,尽量保持Attribute的ID与全查一直,避免更改jsp。
6.2.3 页面测试
6.3 添加学生
6.3.1 allStudent.jsp
<a href="${pageContext.request.contextPath}/insertPage">添加学生</a><br/>
6.3.2 Controller
@RequestMapping("/insertPage")
public String insertPage() {
return "insertPage";
}
⚠️ 注意:其实这一步可以省略,a标签可以直接放jsp页面,如果jsp在web-inf下基于只能这么写了。
6.3.3 insertPage.jsp
<h3>添加学生</h3>
<form action="${pageContext.request.contextPath}/insert" method="post">
学生姓名:<input type="text" name="username"><br/>
学生密码:<input type="text" name="password"><br/>
<input type="submit" value="确认添加">
</form>
6.3.4 Controller
@RequestMapping("/insert")
public String insert(Student student) {
System.out.println(student);
studentService.insert(student);
return "redirect:/queryAll";
}
6.3.5 页面测试
6.4 删除学生
说明:
- 对学生的删除和修改操作都需要对应到具体的某一学生,所以在url上需要传入该学生的id
- 传值又两种方式,这里用一种,修改那用另一种
6.4.1 allStudent.jsp
<a href="${pageContext.request.contextPath}/delete/${student.id}">删除</a>
6.4.2 Controller
@RequestMapping("/delete/{id}")
public String delete(@PathVariable("id") int id) {
studentService.delete(id);
return "redirect:/queryAll";
}
6.4.3 页面测试
6.5 修改学生
说明:
- 修改学生时,需要获取该学生的ID
- 跳转页面的Controller页面需要根据ID查询该学生的信息
- 修改页面需要显示学生的信息,且ID不可修改,就放到隐藏域里
6.5.1 allStudent.jsp
<a href="${pageContext.request.contextPath}/updatePage?id=${student.id}">修改</a>
6.5.2 Controller
@RequestMapping("/updatePage")
public String updatePage(int id, Model model) {
Student student = studentService.queryByID(id);
model.addAttribute("student", student);
return "updatePage";
}
6.5.3 updatePage.jsp
<h3>修改学生信息</h3>
<form action="${pageContext.request.contextPath}/update" method="post">
<input type="hidden" name="id" value="${student.id}">
学生姓名:<input type="text" name="username" value="${student.username}"><br/>
学生密码:<input type="text" name="password" value="${student.password}"><br/>
<input type="submit" value="确认修改">
</form>
6.5.4 Controller
@RequestMapping("/update")
public String update(Student student, Model model) {
studentService.update(student);
return "redirect:/queryAll";
}
6.5.5 页面测试
7. 写在最后
还是挺复杂的,关键是分清不同层所配置的信息,滤清思路其实没那么难。