SSM——整合Spring+SpringMVC+Mybatis

2018-12-04 23:43:38     

基本概要

Spring:用到注解和自动装配,就是Spring的两个精髓IOC(反向控制)和 AOP(面向切面编程)。

SpringMVC:用到了MVC模型,将流程控制代码放到Controller层处理,将业务逻辑代码放到Service层处理。

Mybatis:用到了与数据库打交道的层面,dao(mapper)层,放在所有的逻辑之后,处理与数据库的CRUD相关的操作。

jar包准备,这里提供SSM的相关jar包:lib.rar

Spring+Mybatis

新建一张老师表(teacher),插入三条数据

CREATE TABLE `teacher` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;


INSERT INTO `teacher` VALUES ('1', '数学老师');
INSERT INTO `teacher` VALUES ('2', '语文老师');
INSERT INTO `teacher` VALUES ('3', '英语老师');
新建一个普通的web项目,导入相关的jar包

在【src/top.bounds.pojo】目录下创建Teacher实体类,用来对应数据库里的表

package top.bounds.pojo;

public class Teacher {
	private int id;
	private String name;

	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;
	}

	@Override
	public String toString() {
		return "Teacher [id=" + id + ", name=" + name + "]";
	}
}

在dao(mapper)层【src/top.bounds.mapper】目录下设计TeacherMapper接口,主要负责与数据库进行交互设计,用来处理数据的持久化工作

package top.bounds.mapper;

import java.util.List;

import top.bounds.pojo.Teacher;

public interface TeacherMapper {
	
	public List<Teacher> listTeacher();
}

在【src/top.bounds.mapper】目录下创建teacher.xml,teacher.xml需要和TeacherMapper放在同一个包下面,并且namespace必须写TeacherMapper的完整类名

<?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="top.bounds.mapper.TeacherMapper">
	<select id="listTeacher" resultType="Teacher">
		select * from teacher
	</select>
</mapper>

在【src/top.bounds.config】目录下新建spring配置文件springConfig.xml,主要用来配置数据源、SqlSessionFactory、mapper扫描器...

<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
     http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

	<!-- 配置Druid连接池 -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
       <!-- 基本属性 url、user、password -->
       <property name="url" value="jdbc:mysql://localhost:3306/transaction?characterEncoding=UTF-8" />
       <property name="username" value="root" />
       <property name="password" value="123456" />
       <property name="driverClassName" value="com.mysql.jdbc.Driver" />

       <!-- 配置初始化大小、最小、最大 -->
       <property name="initialSize" value="3" />
       <property name="minIdle" value="3" />
       <property name="maxActive" value="20" />

       <!-- 配置获取连接等待超时的时间 -->
       <property name="maxWait" value="60000" />

       <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
       <property name="timeBetweenEvictionRunsMillis" value="60000" />

       <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
       <property name="minEvictableIdleTimeMillis" value="300000" />

       <property name="validationQuery" value="SELECT 1" />
       <property name="testWhileIdle" value="true" />
       <property name="testOnBorrow" value="false" />
       <property name="testOnReturn" value="false" />

       <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
       <property name="poolPreparedStatements" value="true" />
       <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
   </bean>
	<!-- 扫描存放SQL语句的XML配置文件 -->
	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="typeAliasesPackage" value="top.bounds.pojo" />
		<!-- 注入数据库连接信息 -->
		<property name="dataSource" ref="dataSource" />
		<property name="mapperLocations" value="classpath:top/bounds/mapper/*.xml" />
	</bean>
	<!-- 扫描Mapper类 ,并将其生命周期纳入Spring的管理-->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="top.bounds.mapper" />
	</bean>
</beans>

在【src/top.bounds.test】目录下新建SSMTest测试类,用来测试spring+mybatis整合后的效果

package top.bounds.test;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import top.bounds.mapper.TeacherMapper;
import top.bounds.pojo.Teacher;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:top/bounds/config/springConfig.xml")
public class SSMTest {
	@Autowired
	TeacherMapper teacherMapper;

	@Test
	public void testOne() {

		List<Teacher> list = teacherMapper.listTeacher();
		for (Teacher t : list) {
			System.out.println(t);
		}
	}
}

运行测试类,执行结果:spring+mybatis整合成功

DEBUG [main] - ==>  Preparing: select * from teacher 
DEBUG [main] - ==> Parameters: 
Teacher [id=1, name=语文老师]
Teacher [id=2, name=数学老师]
Teacher [id=3, name=英语老师]

Spring+Mybatis+SpringMVC

上面已经整合了spring+mybatis,接下来就要把SpringMVC整合到一起去

service层

在【src/top.bounds.service】目录下定义TeacherService接口,为控制层提供服务,接受控制层的参数,完成相应的功能,并返回给控制层。这层就是用 Spring 来管理 service 接口,我们会使用 xml 配置的方式来将 service 接口配置到 spring 配置文件中。而且事务控制也是在 service 层进行配置

package top.bounds.service;

import java.util.List;

import top.bounds.pojo.Teacher;

public interface TeacherService {
	
	public List<Teacher> listTeacher();
}

在【src/top.bounds.impl】目录下新建TeacherImpl实现类,TeacherImpl被注解@Service标示为一个Service并且装配了TeacherMapper

package top.bounds.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import top.bounds.mapper.TeacherMapper;
import top.bounds.pojo.Teacher;
import top.bounds.service.TeacherService;

@Service
public class TeacherImpl implements TeacherService {

	@Autowired
	TeacherMapper teacherMapper;

	@Override
	public List<Teacher> listTeacher() {

		return teacherMapper.listTeacher();
	}

}

这里需要回到spring的配置文件springConfig.xml,加入扫描包,将该Service的生命周期纳入Spring的管理,在springConfig.xml文件中添加如下配置:

<!-- 扫描包,通过注解,将Service的生命周期纳入Spring的管理-->
<context:component-scan base-package="top.bounds.impl" />

SpringMVC层

在controller控制层【src/top.bounds.controller】目录下新建TeacherController控制类主要负责具体的业务模块流程控制

TeacherController被@Controller标示为了控制器自动装配了teacherService通过@RequestMapping映射访问路径/listTeacher路径到方法listTeacher()

package top.bounds.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import top.bounds.pojo.Teacher;
import top.bounds.service.TeacherService;

@Controller
public class TeacherController {

	@Autowired
	TeacherService teacherService;

	@RequestMapping(value = "/listTeacher")
	public ModelAndView listTeacher() {
		ModelAndView mav = new ModelAndView();
		List<Teacher> list = teacherService.listTeacher();
		mav.addObject("teacher", list);
		mav.setViewName("listTeacher");
		return mav;
	}
}

在【src/top.bounds.config】目录下新建SpringMVC配置文件springmvcConfig.xml,主要是配置处理器映射器 、 适配器、视图解析器、扫描Controller,并将其生命周期纳入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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
     http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

	<!-- 扫描Controller,并将其生命周期纳入Spring管理 -->
	<context:component-scan
		base-package="top.bounds.controller">
		<!-- 扫描top.bounds.controller包下@Controller注解 -->
		<context:include-filter type="annotation"
			expression="org.springframework.stereotype.Controller" />
	</context:component-scan>
	<!-- 注解驱动,以使得访问路径与方法的匹配可以通过注解配置 -->
	<mvc:annotation-driven />
	<!-- 视图定位 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>

</beans>

配置web.xml,这个web.xml有两个作用

  • 通过ContextLoaderListener在web启动的时候,获取contextConfigLocation配置文件的文件名springConfig.xml,并进行Spring相关初始化工作
  • 有任何访问,都被DispatcherServlet所拦截,这就是Spring MVC那套工作机制了
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	id="WebApp_ID" version="3.1">
	<display-name>ssmTest01</display-name>
	<!-- spring的配置文件 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:top/bounds/config/springConfig.xml</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<!-- spring mvc核心:分发servlet -->
	<servlet>
		<servlet-name>springmvcConfig</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- spring mvc的配置文件 -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath*:top/bounds/config/springmvcConfig.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvcConfig</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
    <!-- 解决post提交中文乱码 -->
	<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>

View层

在【WebContent/WEB-INF/jsp】目录下新建listTeacher.jsp,负责前台jsp页面的展示,此层需要与Controller层结合起来开发。Jsp发送请求,controller接收请求,处理,返回,jsp回显数据

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" isELIgnored="false"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<table align="center" border="1" cellspacing="0">
		<tr>
			<th>id</th>
			<th>name</th>
		</tr>
		<c:forEach items="${teacher}" var="teacher">
			<tr>
				<td>${teacher.id}</td>
				<td>${teacher.name}</td>
			</tr>
		</c:forEach>
	</table>
</body>
</html>

启动Tomcat运行测试,访问http://localhost:8080/ssmTest01/listTeacher 观察效果

总结

1. 首先浏览器上访问路径 /listTeacher

2. tomcat根据web.xml上的配置信息,拦截到了/listTeacher,并将其交由DispatcherServlet处理。

3. DispatcherServlet 根据springMVC的配置,将这次请求交由TeacherController类进行处理,所以需要进行这个类的实例化

4. 在实例化TeacherController的时候,注入TeacherImpl (自动装配实现了TeacherService接口的的实例,只有TeacherImpl实现了TeacherService接口,所以就会注入TeacherImpl)

5. 在实例化TeacherImpl的时候,又注入TeacherMapper

6. 根据springConfig.xml中的配置信息,将TeacherMapper和teacher.xml关联起来了。

7. 这样拿到了实例化好了的TeacherController,并调用 listTeacher方法

8. 在listTeacher方法中,访问TeacherService并获取数据,并把数据放在"teacher"上,接着服务端跳转到listTeacher.jsp

9. 最后在listTeacher.jsp 中显示数据

ps:本篇博客源码下载链接:https://pan.baidu.com/s/1ht6COBwYXg7jIxeyFcvZiQ 密码:dtpt
MyBatis——(五)缓存

正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存:基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空 二级缓存:与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache

【经典收藏】掌握这些命令,玩转Linux小黑框!!

ls [选项] [目录名 | 列出相关目录下的所有目录和文件-a 列出包括.a开头的隐藏文件的所有文件 -A 通-a,但不列出"."和".." -l 列出文件的详细信息 -c 根据ctime排序显示 -t 根据文件修改时间排序 ---color[=WHEN] 用色彩辨别文件类型 WHEN 可以是'never'、'always'或'auto'其中之一 白色:表示普通文件 蓝色:表示目录 绿色:表示可执行文件 红色:表示压缩文件 浅蓝色:链接文件 红色闪烁:表示链接的文件有问题 黄色:表示设备文件 灰色:表示其它文件mv [选项] 源文件或目录 目录或多个源文件 | 移动或重命名文件-b 覆盖前做备份 -f 如存在不询问而强制覆盖 -i 如存在则询问是否覆盖 -u 较新才覆盖 -t

 发表评论