SSM项目
(Spring + SpringMVC + Mybatis)
使用到的技术栈:
spring,springMVC,mybatis,jQuery,ajax,bootstrap(前端框架),mysql数据库,基于maven创建工程
项目选型:
商品管理系统:
商品表:
品牌表:
类别表:
需求:
SSM项目整合的时候会出现的问题:
1、我们都知道,mybatis框架中,持久层实现类是通过代理创建出来的,那如何将持久层的实例装进spring中?
我们在ssm项目整合的时候会去导入一个spring整合mybatis的包,这个包有一个扫描器设置,该扫描器会去扫描持久层所有的接口,并为该接口创建代理对象,然后将该实例装进spring中
maven坐标
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<!--mybatis核心包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--mybatis/spring包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!--java ee jar包-->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<!--mysql数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!--日志-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--连接池-->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.5</version>
</dependency>
</dependencies>
由于导入了mybatis整合spring的包,以及数据库连接池的包,mybatis的配置文件可以不配置
我们将spring和springMVC的配置文件给拆分开来,因此我们要在web.xml中为spring核心容器与springMVC另作配置
注意:==在spring核心配置文件和MVC配置文件中都要开启扫描包==
基础配置
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--配置前端总控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--绑定springMVC核心配置文件-->
<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>
<!--设置全局属性,绑定spring核心配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value>
</context-param>
<!--配置一个监听器,让项目在启动的时候就去加载spring核心容器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置一个编码过滤器,拦截所有的资源,将所有资源的字符集设置成utf-8-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--将字符集设置成utf-8-->
<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>
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启扫描包-->
<context:component-scan base-package="com.os467.shop"></context:component-scan>
<!--读取配置文件中的数据,获取数据源信息-->
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<!--配置数据源-->
<bean id="basicDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<!--注入源数据-->
<property name="driverClassName" value="${db.driver}"></property>
<property name="url" value="${db.url}"></property>
<property name="username" value="${db.username}"></property>
<property name="password" value="${db.password}"></property>
</bean>
<!--配置mybatis需要的会话工厂,使用mybatis整合spring的会话工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入数据源-->
<property name="dataSource" ref="basicDataSource"></property>
<!--匹配mapper配置文件-->
<property name="mapperLocations" value="classpath:com/os467/shop/controller/*.xml"></property>
</bean>
<!--mybatis扫描器的配置-->
<bean id="configurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--扫描此包下所有持久层接口,并且通过代理模式创建出每个接口对应的代理对象,并交由spring管理-->
<property name="basePackage" value="com.os467.shop.mapper"></property>
</bean>
</beans>
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--开启mvc注解的支持-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--过滤静态资源-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!--扫描包-->
<context:component-scan base-package="com.os467.shop"></context:component-scan>
<!--配置视图解析器-->
<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>
数据源
db.url=jdbc:mysql://localhost:3306/web_test?serverTimezone=GMT&characterEncoding=utf-8
db.driver=com.mysql.cj.jdbc.Driver
db.username=root
db.password=root
SSM详细配置过程(Model)
1、首先在pom.xml文件中引入maven坐标,见上文
刷新pom.xml文件,让maven导入配置
为工程添加web项目支持
2、创建包结构
2.1、在java文件下创建包结构
com.os467.ssm
controller
mapper
- UserMapper
pojo
- User
service
impl
- UserServiceImpl
UserService
2.2在resource文件下创建文件夹,创建映射配置文件
com/os467/ssm/mapper/UserMapper.xml
2.3在resource文件夹下创建数据源文件db.properties,加入数据源信息,见上文
3、在resource文件夹下创建spring核心配置文件 beans.xml,配置核心配置文件
3.1、引入核心配置文件所对应的xml约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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/context
http://www.springframework.org/schema/context/spring-context.xsd">
3.2、加入开启扫描包标签,指定需要被扫描的包路径
<!--开启扫描包-->
<context:component-scan base-package="com.os467"></context:component-scan>
3.3、读取数据源配置文件中的数据,获取数据源信息,能够在本配置文件中用el表达式取到值
<!--读取配置文件中的数据,获取数据源信息-->
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
配置数据源信息,我们使用dbcp连接池提供的BasicDataSource类来创建数据源实例,通过池的思想来创建持久层实例
<!--配置数据源-->
<bean id="basicDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<!--注入源数据-->
<property name="driverClassName" value="${db.driver}"></property>
<property name="url" value="${db.url}"></property>
<property name="username" value="${db.username}"></property>
<property name="password" value="${db.password}"></property>
</bean>
3.4、配置mybatis所需要的会话工厂,工厂实例装载进spring容器中,选用mybatis.spring包下的SqlSessionFactoryBean类创建会话工厂
需要提供之前配置的数据源实例
然后需要提供映射文件的配置路径
<!--配置mybatis需要的会话工厂,使用mybatis整合spring的会话工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入数据源-->
<property name="dataSource" ref="basicDataSource"></property>
<!--匹配mapper配置文件-->
<property name="mapperLocations" value="classpath:com/os467/shop/mapper/*.xml"></property>
</bean>
3.5、mybatis扫描器的配置,引入MapperScannerConfigurer类
添加属性,配置需要被代理的持久层接口的包路径
<!--mybatis扫描器的配置-->
<bean id="configurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--扫描此包下所有持久层接口,并且通过代理模式创建出每个接口对应的代理对象,并交由spring管理-->
<property name="basePackage" value="com.os467.shop.mapper"></property>
</bean>
4、在resource文件夹下创建mvc框架配置文件 springmvc.xml
4.1、引入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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
4.2、开启扫描包
<!--扫描包-->
<context:component-scan base-package="com.os467.shop"></context:component-scan>
4.3、添加标签开启springmvc对注解的支持,过滤前端传来的静态资源
<!--开启mvc对注解的支持-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--过滤静态资源-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
4.4、配置视图解析器,引入类InternalResourceViewResolver
配置视图前缀,jsp文件路径,配置视图后缀,文件格式
<!--配置视图解析器-->
<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>
5、配置web.xml文件
5.1、配置前端总控制器,引入类DispatcherServlet,绑定springMVC核心配置文件,配置初始化属性数据,设置启动级别
拦截前端请求资源
<!--配置前端总控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--绑定springMVC核心配置文件-->
<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>
5.2、设置全局属性,绑定spring核心配置文件,同时配置一个监听器ContextLoaderListener,让项目在启动的时候就去加载核心容器
<!--设置全局属性,绑定spring核心配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value>
</context-param>
<!--配置一个监听器,让项目在启动的时候就去加载spring核心容器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
5.3、配置一个编码过滤器,将所有资源的字符集改成utf-8,同时拦所有资源,对静态资源也生效
<!--配置一个编码过滤器,拦截所有的资源,将所有资源的字符集设置成utf-8-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--将字符集设置成utf-8-->
<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>
6、配置UserMapper.xml文件
引入mybatis相关xml约束,注册命名空间,编写测试sql语句
<?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.os467.ssm.mapper.UserMapper">
<select id="findUserList" resultType="com.os467.ssm.pojo.User" >
select * from tb_user
</select>
</mapper>
7、完善三层架构配置
持久层UserMapper
package com.os467.ssm.mapper;
import com.os467.ssm.pojo.User;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserMapper {
List<User> findUserList();
}
业务层实现类UserServiceImpl
package com.os467.ssm.service.impl;
import com.os467.ssm.mapper.UserMapper;
import com.os467.ssm.pojo.User;
import com.os467.ssm.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
public List<User> findUserList() {
return userMapper.findUserList();
}
}
表现层UserController
package com.os467.ssm.controller;
import com.os467.ssm.pojo.User;
import com.os467.ssm.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.util.List;
@Controller
@RequestMapping("user")
public class UserController {
@Resource(name = "userServiceImpl")
private UserService userService;
@RequestMapping("list")
public String findUserList(Model model){
List<User> userList = userService.findUserList();
model.addAttribute("userList",userList);
return "test";
}
}
分页功能
select * from ssm_goods limit 0,3
分页需要的参数:
- 首页 startPage
- 上一页 prevPage
- 下一页 nextPage
- 尾页 lastPage
- 起始索引位置 startIndex
- 分页单位 pageSize
如果需要给持久层传递多个不同数据,我们选择将数据先封装到集合中
/**
* 实现商品列表
* currentPage 当前页的页码值
*/
@RequestMapping("/list")
public String getGoodsList(Model model,String currentPage){
//接收当前页的页码值
if (currentPage == null || currentPage.equals("")){
currentPage = "1";
}else {
System.out.println("当前页的页码值为 "+currentPage);
}
//计算上一页的页码值
Integer prevPage = 0;
if (currentPage.equals("1")){
prevPage = 1;
}else {
prevPage = Integer.parseInt(currentPage) - 1;
}
//计算尾页的值
Integer lastPage = 0;
//获取商品的总记录条数
Integer count = goodsService.getCount();
System.out.println("总记录条数为 "+count);
//指定分页单位
Integer pageSize = 2;
if (count % pageSize == 0){
lastPage = count / pageSize;
}else {
lastPage = (count / pageSize) + 1;
}
//计算下一页的值
Integer nexPage = 0;
if (currentPage.equals(lastPage+"")){
nexPage = lastPage;
}else {
nexPage = Integer.parseInt(currentPage) + 1;
}
//起始索引位置
Integer startIndex = (Integer.parseInt(currentPage) - 1) * pageSize;
//创建一个map集合,用于存放数据
HashMap<Object, Object> hashMap = new HashMap();
//将分页所需要的条件传到集合里
hashMap.put("startIndex",startIndex);
hashMap.put("pageSize",pageSize);
//查询商品数据
List<Goods> goodsList = goodsService.getGoodsList(hashMap);
//查询品牌数据
List<Brand> brandList = goodsService.getBrandList();
//查询类别的数据
List<Cate> cateList = goodsService.getCateList();
//将数据存到model中
model.addAttribute("goodsList",goodsList);
model.addAttribute("brandList",brandList);
model.addAttribute("cateList",cateList);
model.addAttribute("nexPage",nexPage);
model.addAttribute("lastPage",lastPage);
model.addAttribute("prevPage",prevPage);
return "goodsList";
}
GoodsMapper
<!--查询所有的商品信息-->
<select id="getGoodsList" parameterType="hashMap" resultMap="goodsVo">
select * from ssm_goods limit #{startIndex},#{pageSize}
</select>
前端
<script>
//分页函数
function page(currentPage){
location.href = "<%=path%>/goods/list?currentPage="+currentPage;
}
</script>
<tr>
<td colspan="12" align="center">
<a onclick="page(1)">首页</a>
<a onclick="page(${prevPage})">上一页</a>
<a onclick="page(${nexPage})">下一页</a>
<a onclick="page(${lastPage})">尾页</a>
</td>
</tr>
分页工具类
initPage()
初始化分页工具类的时候需要从前端获取字符串类型的当前页码,需要提供分页单位,需要提供数据总记录条数
我们通过将分页工具类放进model域中来从前端获取分页数据
package com.os467.shop.utils;
import org.springframework.stereotype.Component;
@Component
public class PageUtils {
//当前页
private String currentPage;
//上一页
private Integer prevPage;
//下一页
private Integer nextPage;
//尾页(也可以表示总页数)
private Integer lastPage;
//总记录条数
private Integer count;
//起始索引位置
private Integer startIndex;
//分页单位
private Integer pageSize;
public String getCurrentPage() {
return currentPage;
}
public void setCurrentPage(String currentPage) {
this.currentPage = currentPage;
}
public Integer getPrevPage() {
return prevPage;
}
public void setPrevPage(Integer prevPage) {
this.prevPage = prevPage;
}
public Integer getNextPage() {
return nextPage;
}
public void setNextPage(Integer nextPage) {
this.nextPage = nextPage;
}
public Integer getLastPage() {
return lastPage;
}
public void setLastPage(Integer lastPage) {
this.lastPage = lastPage;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public Integer getStartIndex() {
return startIndex;
}
public void setStartIndex(Integer startIndex) {
this.startIndex = startIndex;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
//计算上一页的值
private void initPrevPage(){
prevPage = currentPage.equals("1")?1:Integer.parseInt(currentPage)-1;
}
//计算尾页的值
private void initLastPage(){
lastPage = count % pageSize == 0 ? count / pageSize : (count / pageSize)+1;
}
//计算下一页的值
private void initNextPage(){
nextPage = currentPage.equals(lastPage+"") ? lastPage : Integer.parseInt(currentPage) + 1;
}
//计算起始索引位置
private void initStartIndex(){
startIndex = (Integer.parseInt(currentPage) - 1) * pageSize;
}
//初始化的方法
private void init(String currentPage,Integer pageSize,Integer count){
if (currentPage == null || currentPage.equals("")){
currentPage = "1";
}
this.currentPage = currentPage;
this.pageSize = pageSize;
this.count = count;
}
//调用的方法
public void initPage(String currentPage,Integer pageSize,Integer count){
init(currentPage,pageSize,count);
initStartIndex();
initPrevPage();
initLastPage();
initNextPage();
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1300452403@qq.com