Spring+SpringMVC+Mybatis【SSM】架构整合

原创
小哥 3年前 (2022-11-14) 阅读数 3 #大杂烩

提示:这里所提到的所有概念内容均为精简、个人理解版,想要查看详细官方的解释,请百度百科自行查询。

Spring+SpringMVC+Mybatis【SSM】框架整合

一、SSM框架解析

SSM框架是spring、spring MVC 、和mybatis框架的整合,是标准的MVC模式。标准的SSM框架有四层,分别是dao层(mapper),service层,controller层和pojo层,当然还有控制前台jsp页面展示的View层。

  1. pojo层

作用:主要编写项目的 实体类

  1. 持久层:dao层(mapper)层

作用:编写 接口 ,并且使用 spring配置文件来实现接口 。实现 数据持久层 的工作,负责 与数据库进行联络 的一些任务都封装在此。

在模块中进行接口的调用来进行数据业务的处理。(不在关心接口的实现类是哪个类)。 数据源的配置 以及有关 数据库连接的参数 都在Spring的配置文件 spring-dao.xml 中进行配置。

  1. 业务层:Service层

作用:Service层负责逻辑应用设计。跟Dao层接口的操作没什么区别。

dao层设计接口,然后将dao层接口操作写入service层,再在service层的实现类中引入dao层中方法。 再在Spring的配置文件 spring-service.xml 中配置其实现的关联。
(业务逻辑层的实现具体要调用到自己已经定义好的Dao的接口上)这样就可以在应用中调用Service接口来进行业务处理。
建立好Dao之后再建立service层,service层又要在controller层之下,因为既要调用Dao层的接口又要提供接口给controller层。每个模型都有一个service接口, 每个接口分别封装各自的业务处理的方法

  1. 表现层:Controller层(Handler层)

作用:负责具体的业务模块流程的控制
调用Service层提供的接口来控制业务流程
业务流程的不同会有不同的控制器,在具体的开发中可以将我们的流程进行抽象的归纳,设计出可以重复利用的子单元流程模块。

  1. View层
    作用:主要和控制层紧密结合, 负责前台jsp页面的表示

各层之间的联系

pojo层主要是编写实体类;
Dao层,Service层这两个层次这两层中的方法基本是一样的,但是也完全可以独立进行;
Controller,View层因为耦合度比较高,因而要结合在一起开发。在层与层之前我们只需要知道接口的定义,调用接口即可完成所需要的逻辑单元应用,一切显得非常清晰简单。

1.1 Spring

Spring使用基本的 JavaBean 来完成以前只可能由EJB完成的事情。
简单来说,Spring是一个轻量级的 控制反转(IoC)和面向切面(AOP)的容器框架

1.2 SpringMVC

接收客户端请求并且调用业务层处理,最后将内容传给视图,由视图将结果呈现给客户端。

1.3 Mybatis

MyBatis是一个基于Java的持久层框架,使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的pojo实体类中的对象映射成数据库中的记录。

二、项目整合框架

此流程全部按照从下往上容易理解的思路整合,仅供参考。

2.1 环境搭建

1、创建一个纯净的 maven 项目

2、加入web结构


3、在 pom.xml 中导入所需依赖

 
    
        
        
            junit
            junit
            4.12
        

        
        
              mysql
              mysql-connector-java
              8.0.26
        
        
        
            com.mchange
            c3p0
            0.9.5.5
        
        
        
        
            javax.servlet
            servlet-api
            2.5
            provided
        
        
        
        
            javax.servlet.jsp
            jsp-api
            2.2
            provided
        
        
        
            javax.servlet
            jstl
            1.2
        
        
        
            org.mybatis
            mybatis
            3.5.9
        
        
        
        
            org.springframework
            spring-webmvc
            5.3.18
        
        
        
            org.mybatis
            mybatis-spring
            2.0.7
        

        
        
        
            org.springframework
            spring-jdbc
            5.3.19
        
        
        
         org.aspectj
         aspectjweaver
            1.9.4
        
    

4、在 pom.xml 中进行资源导出设置

 
    
    
        
            
                src/main/resources
                
                    **/*.properties
                    **/*.xml
                
                true
            
            
                src/main/java
                
                    **/*.properties
                    **/*.xml
                
                true
            
        

2.2 代码实战

1、整体项目结构展示

2、创建数据库

ssmbuildbooksCREATE DATABASE ssmbuild;

USE ssmbuild ;

CREATE TABLE books(

bookID INT(10) NOT NULL AUTO_INCREMENT COMMENT 书id,
bookName VARCHAR(100) NOT NULL COMMENT 书名,
bookCounts INT(11) NOT NULL NOT NULL COMMENT 数量,
detail VARCHAR(200) NOT NULL COMMENT 描述,
KEY bookID (bookID) 

)ENGINE=INNODB DEFAULT CHARSET=utf8;

3、Mybatis层编写

1、 编写 com.li.pojo 层数据库的实体类 Books

package com.li.pojo;

public class Books {
    private int bookID;
    private String bookName;
    private int bookCounts;
    private String detail;

//get/set/有参无参构造也可以通过导入lombok依赖,通过直接来使用注解来使用
    public int getBookID() {
        return bookID;
    }

    public void setBookID(int bookID) {
        this.bookID = bookID;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public int getBookCounts() {
        return bookCounts;
    }

    public void setBookCounts(int bookCounts) {
        this.bookCounts = bookCounts;
    }

    public String getDetail() {
        return detail;
    }

    public void setDetail(String detail) {
        this.detail = detail;
    }

    public Books() {
    }

    public Books(int bookID, String bookName, int bookCounts, String detail) {
        this.bookID = bookID;
        this.bookName = bookName;
        this.bookCounts = bookCounts;
        this.detail = detail;
    }

    @Override
    public String toString() {
        return "Books{" +
                "bookID=" + bookID +
                ", bookName=" + bookName +  +
                ", bookCounts=" + bookCounts +
                ", detail=" + detail +  +
                };
    }
}

2、 编写 com.li.dao 层接口 UserMapper

编写与pojo层实体类对应的接口。【作用:将要进行的操作编写成接口】

package com.li.dao;

import com.li.pojo.Books;
import org.apache.ibatis.annotations.Param;

import java.util.List;

//实体类 Books写完以后,来写接口 使其进行一些操作

public interface BookMapper {

    //操作编写 —— 增删改查

    //增加一本书
    int addBook(Books books);//增加一本书 参数(给她一本书)

    //删除一本书 —— 通过id来删除
    int deleteBookById(@Param("bookID") int id);

    //更新 修改 需要传入一整本书
    int updateBook(Books books);

    //查询 —— 会返回来一本书
    //查询 根据Id查询
    Books queryBookById(@Param("bookID")int id);

    //查询全部的书 —— 返回的是一个集合
    List queryAllBook();

/*接口写完以后 这些接口具体怎么做 实现那些操作
需要编写接口的实现类BookMapperImpl
 此处整合spring,则可以直接编写BookMapper.xml配置文件来实现   **/

    //新增了一个查询的功能

    Books queryBookByName(@Param("bookName") String bookName);

}

3、 编写 com.li.dao 层 接口的实现 配置文件 UserMapper.xml

之前一直写的都是接口UserMapper的实现类,但是自从使用mybatis之后,简单方便,都直接使用配置文件来对接口进行实现,所以这里的接口实现 配置文件与之前的接口的实现类作用是一样的。【作用:绑定接口+实现接口中的操作—sql语句】





         

    

    
    
        insert into ssmbuild.books (bookName,bookCounts,detail)
--         这种直接插入的傻瓜方式 是不对的 values (4,"我是菜狗",100,"菜狗真菜");
        values(#{bookName},#{bookCounts},#{detail});
    

    
    
          delete
          from ssmbuild.books
          where bookID=#{bookID};

    

    
    
      update ssmbuild.books
      set
          bookName=#{bookName},
          bookCounts=#{bookCounts},
          detail=#{detail}
      where bookID=#{bookID};

    

    
    

    
    

    
    

4、 编写 mybatis 的配置文件mybatis-config.xml
myabtis-config.xml配置文件的 主要作用 :用来设置日志、给实体类重命名、绑定接口的实现类配置文件






    
    
        
    

    

    
    
        
    

    
    
        
    

5、 编写 com.li.service 层的接口 BookService

service中操作跟dao层接口中的操作差不多,直接复制粘贴过来就可以了。

package com.li.service;

import com.li.pojo.Books;

import java.util.List;

//业务层 跟dao层的接口操作没有什么区别
public interface BookService {

    //操作编写 —— 增删改查

    //增加一本书
    int addBook(Books books);//增加一本书 参数(给她一本书)

    //删除一本书 —— 通过id来删除
    int deleteBookById(int id);

    //更新 修改 需要传入一整本书
    int updateBook(Books books);

    //查询 —— 会返回来一本书
    //查询 根据Id查询
    Books queryBookById(int id);

    //查询全部的书 —— 返回的是一个集合
    List queryAllBook();

    //新增
    Books queryBookByName(String bookName);

}

6、 编写 com.li.service 层的接口实现类 BookServiceImpl

业务层调用dao层 所以这里一定要 把dao层组合进来 ,这样spring就可以托管他了 因为spring不是自己创建对象; 把dao层放进来之后,加入他的 set方法

package com.li.service;

import com.li.dao.BookMapper;
import com.li.pojo.Books;

import java.util.List;

public class BookServiceImpl implements BookService{

//业务层调用dao层 所以这里一定要把dao层组合进来  这样spring就可以托管他了 因为spring不是自己创建对象 都是通过set方法注入
    private BookMapper bookMapper;
    //把dao层放进来之后,加入他的set方法

    public void setBookMapper(BookMapper bookMapper) {
        this.bookMapper = bookMapper;
    }

    @Override
    public int addBook(Books books) {
        return bookMapper.addBook(books);
    }

    @Override
    public int deleteBookById(int id) {
        return bookMapper.deleteBookById(id);
    }

    @Override
    public int updateBook(Books books) {
        return bookMapper.updateBook(books);
    }

    @Override
    public Books queryBookById(int id) {
        return bookMapper.queryBookById(id);
    }

    @Override
    public List queryAllBook() {
        return bookMapper.queryAllBook();
    }

    @Override
    public Books queryBookByName(String bookName) {
        return bookMapper.queryBookByName(bookName);
    }
}

7、 编写 数据库配置文件 database.properties

将连接数据的配置,写在该配置文件当中,方便后面的引用。

jdbc.driver=com.mysql.cj.jdbc.Driver
#如果使用的是Mysql8.0+需要配置一下时区&serverTimezone=Asia/Shanghai
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456

4、spring层

4.1 spring层整合mybatis

1、 编写整合的配置文件 spring-dao.xml

spring-dao.xml
【作用:引入数据库配置文件 连接数据库+绑定连接池+引入数据源+绑定mybatis-config.xml配置文件】




    
         
    

    
    
    
        
        
        
        

        
             
        
             
        
             
        
             
        
             
        
    

    
    
        
        
        
        


    
    
    
    
        
        
        
        
         
    

4.2 spring层整合service层

1、编写整合配置文件 spring-service.xml

【作用:注入数据源+将我们的业务全部注入进来+事务声明】




     
         
    
    
    
        
    
    
    
        
        
    
    
    
        
    
         
         
         
             
         
    
    
        
        
            
    

5、springmvc层

1、编写 web.xml




    
    
        springmvc
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            classpath:applicationContext.xml
        
        
        1
    
    
        springmvc
        /
    

    
    
        encondingFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
            encoding
            utf-8
        
    
    
        encondingFilter
        /
    

    
    
        15
    

2、 编写 spring-mvc.xml



    
    
    
    
    
    
    
    
        
        
    

3、 编写spring配置整体总和配置文件 applicationContext.xml

将之写的 spring-dao,xmlspring-service.xml 以及 spring-mvc.xml 文件全部整合到这一个整体的配置文件中,方便之后的引用。




      
    
    
    

至此,SSM项目的整体框架就搭建起来了,之后的所有业务操作全部都是基于上面框架进行的,框架中的内容基本不用再改变,只要进行controller和view层的编写就可以了。

三、项目业务操作

1、 com.li.controllerBookController 的编写

package com.li.controller;

import com.li.pojo.Books;
import com.li.service.BookService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;
import java.util.List;

@Controller
@RequestMapping("/book")//大的映射 父:book
public class BookController {

    //controller层调用service层
    //所以要把service注入进来

    @Autowired
    @Qualifier("BookServiceImpl")
    private BookService bookService;

    //查询全部的书籍 并且返回到书籍的展示页面
    @RequestMapping("/allBook")

    public String list(Model model){
        //去调用业务层的方法
        List books = bookService.queryAllBook();

       //返回给前端去展示
        model.addAttribute("list",books);

        //给到allBook页面
        return "allBook";
    }

    //跳转到增加书籍页面
    @RequestMapping("/toAddBook")
    public String toAddPaper (){

        return "addBook";
    }

    //添加书籍的请求
    @RequestMapping("/addBook")
    //前端传过来一个Book
    public String addBook(Books books){
        System.out.println("addBook=>"+books);
        //业务层调用service层
        bookService.addBook(books);

        //添加完以后 要回到首页 上面用的都是跳转  这里要使用重定向 因为添加完以后要呈现 全部书籍的页面  也就是说 定位到这个首页
         return "redirect:/book/allBook"; //也可以直接 return "allBook" 返回到allBook.jsp
    }
    //跳转到修改页面
    @RequestMapping("/toUpdateBook")

    public String toUpdatePaper(int id,Model model){
        System.out.println("updateBookId=>"+id);
        //业务层调用service层
        //通过id查出来一本书 把这个书传入方法中 传给前端渲染
        Books books = bookService.queryBookById(id);
        //传给前端渲染  后面页面中再取出来
        model.addAttribute("books",books);
        return "updateBook";

    }
    //修改书籍
    @RequestMapping("/updateBook")
    public String updateBook(Books books){
        System.out.println("updateBook=>"+books);
        int i = bookService.updateBook(books);
        if(i>0){
            System.out.println("修改成功");
        }
        return "redirect:/book/allBook";

    }
     //删除数据操作
    @RequestMapping("/toDeleteBook/{bookID}")
    public String toDeleteBook(@PathVariable("bookID") int id){
       bookService.deleteBookById(id);
        return "redirect:/book/allBook";

    }

    //新增了一个查询操作  查询书籍
    @RequestMapping("/queryBook")
    //查询一本书 这本书 需要从前端那边拿过来 前端目前设置的是 输入书籍的名字queryBookName
    //所以这里需要接收一个书籍的名字 跟前端一样的name标签中的名字一样
    public String queryBook(String queryBookName,Model model){
        //前端通过Name查询出来的书
        Books books = bookService.queryBookByName(queryBookName);

        System.out.println("books=>"+books);
        //到前端去展现出来
        List list=new ArrayList();
        //把查询出来的这本书 放进集合中 前端页面只显示一本书 而不是全部的书
        list.add(books);

        if(books==null){
             list=bookService.queryAllBook();
             model.addAttribute("error","未查到");
        }
        model.addAttribute("list",list);

        return "allBook";

    }
    }

2、编写首页 index.jsp 页面

<%--
  Created by IntelliJ IDEA.
  User: potential
  Date: 2022/4/22
  Time: 14:37
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

  
    首页
    
    
    
          
	      
	
    

    
    

  
  
  

进入书籍页面

3、书籍列表页面 allBook.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: potential
  Date: 2022/4/22
  Time: 15:41
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    查询全部书籍
    
    
    
          
	      
	
    <%--前面传过来一个list 这里需要将list遍历出来-->
    <%--BootStrop美化界面--%>
    



<%--引入bootstrop之后,就可以使用他的样式--%>
<%--toAddBook--%> 新增书籍 显示全部书籍
<%--新增一个搜索功能--%>
${error}
<%--书籍是从数据库里面查询出来的的,返回到前端页面的时候是一个集合list,所有需要从List中遍历出来 遍历:foreach 把他从里面拿出来 方式一:items=${list} 方式二:requestScope.get() --%>
书籍编号 书籍名称 书籍数量 书籍描述 操作
${book.bookID} ${book.bookName} ${book.bookCounts} ${book.detail} 修改  |  删除

4、添加书籍页面 addBook.jsp

<%--
  Created by IntelliJ IDEA.
  User: potential
  Date: 2022/4/22
  Time: 18:30
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    增加书籍
    
    
    
          
	      
	
    <%--BootStrop美化界面--%>
    



5、更新书籍 页面 updateBook.jsp

<%--
  Created by IntelliJ IDEA.
  User: potential
  Date: 2022/4/23
  Time: 12:04
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    修改书籍
    
    
    
          
	      
	
    <%--BootStrop美化界面--%>
    


<%--出现的问题 我们提交了修改的SQL请求,但是修改失败 初次考虑是事务问题,配置完毕,依旧失败 查询看一下SQL语句,能否执行成功,SQL执行失败,原来没有传入id --%> <%--前端传递隐藏域--%>

四、源码地址

链接:https://pan.baidu.com/s/1oAN7Hz10OelYcBcIBq\_x4g
提取码:9802

五、总结

1、排查错误的步骤

问题:bean不存在
   步骤:(1)查看这个bean是否成功  ok
        (2)junit单元测试,看我们的代码是否能查出来结果 ok
        (3)如果上面两个都正确,那么问题一定不在我们的底层,是spring出现了问题
        (4)springmvc整合的时候,没有调用到我们的service层的bean
            4.1 applicationContext.xml文件中没有注册bean
            4.2 web.xml中,我们也绑定过配置文件 contextConfigLocation处注入的bean 应该将总的管理文件给他注入进去applicationContext.xml

2、参考资料:

狂神说SSM框架:
https://blog.csdn.net/qq_33369905/article/details/106647318?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165069411716782184620346%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=165069411716782184620346&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2 all top_positive~default-2-106647318.142 v9 pc_search_result_control_group,157 v4 control&utm_term=ssm&spm=1018.2226.3001.4187

其他参考资料:

https://blog.csdn.net/weixin_45650003/article/details/121623824?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165069411716782184620346%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=165069411716782184620346&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2 all top_positive~default-3-121623824.142 v9 pc_search_result_control_group,157 v4 control&utm_term=ssm&spm=1018.2226.3001.4187

查看SSM框架原理可参考:
https://blog.csdn.net/bieleyang/article/details/77862042?utm_source=app&app_version=5.1.0

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除