SSM整合开发配置

发布时间 2023-06-13 09:19:08作者: YxinHaaa

SSM整合开发配置

配置类作用

web(controller springmvc) 业务逻辑层 数据访问层(mybatis)

web->业务逻辑层->数据访问层->数据源(连接池)->数据库(book表)

spring框架负责把三层架构中的所有对象的创建 以及属性的赋值

SSM整合流程

  1. 创建工程

  2. SSM整合(配置文件版)

  3. 功能模块

    • 表与实体类
    • dao(接口+自动代理)
    • service(接口+实现类)
      • 业务层接口测试(整合JUnit)
    • controller
      • 表现层接口测试(PostMan)

创建工程,添加依赖和插件

 <dependencies>

        <!--springmvc的依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>


        <!--spring事务管理器要使用的依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>

       

        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>


        <!--spring整合myabtis依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.0</version>
        </dependency>

        <!--数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>


        <!--druid连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>

       


        

        <!--小辣椒-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>


        <!--json的转换包  @RequestBody  @ResponseBody-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.0</version>
        </dependency>
    </dependencies>

Spring整合Mybatis

-- 创建ssm_db数据库
CREATE DATABASE IF NOT EXISTS ssm_db CHARACTER SET utf8;

-- 使用ssm_db数据库
USE ssm_db;

-- 创建tbl_book表
CREATE TABLE tbl_book(
    id INT PRIMARY KEY AUTO_INCREMENT, -- 图书编号
    `type` VARCHAR(100), -- 图书类型
    `name` VARCHAR(100), -- 图书名称
    description VARCHAR(100) -- 图书描述
);
-- 添加初始化数据
INSERT INTO tbl_book VALUES(NULL,'计算机理论','Spring实战 第5版','Spring入门经典教材,深入理解Spring原理技术内幕');
INSERT INTO tbl_book VALUES(NULL,'计算机理论','Spring 5核心原理与30个类手写实战','十年沉淀之作,手写Spring精华思想');
INSERT INTO tbl_book VALUES(NULL,'计算机理论','Spring 5设计模式','深入Spring源码剖析,Spring源码蕴含的10大设计模式');
INSERT INTO tbl_book VALUES(NULL,'市场营销','直播就该这么做:主播高效沟通实战指南','李子柒、李佳琦、薇娅成长为网红的秘密都在书中');
INSERT INTO tbl_book VALUES(NULL,'市场营销','直播销讲实战一本通','和秋叶一起学系列网络营销书籍');
INSERT INTO tbl_book VALUES(NULL,'市场营销','直播带货:淘宝、天猫直播从新手到高手','一本教你如何玩转直播的书,10堂课轻松实现带货月入3W+');

jdbc.properties属性文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///ssm_db
jdbc.username=root
jdbc.password=root

web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <!--
  application  往里面放值  修改值 删除值
  session 往里面放值  修改值 删除值  钝化 活化
  request 往里面放值  修改值 删除值

  tomcat容器一启动  就会创建 该项目关联的application对象  一旦application对象 被创建  则ContextLoaderListener就开始工作
  它会自动读取配置在WEB-INF中的applicationContext.xml 如果你的配置文件不在WEB-INF中 我们就需要告知 你的applicationContext.xml
  -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>


  <servlet>
    <servlet-name>xx</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>xx</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

       <context:property-placeholder location="classpath:jdbc.properties"/>
       <!--
       创建德鲁伊对象

       -->
    <bean id="dss" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="${jdbc.name}"/>
        <property name="password" value="${jdbc.pwd}"/>
        <property name="driverClassName" value="${jdbc.driverclass}"/>
        <property name="url" value="${jdbc.url}"/>
    </bean>


    <!--
    创建sqlsessionfacroty的对象
    -->
    <bean id="sss" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dss"/>
        <!--
        给com.tyhxzy.entity下面的所有类起别名 别名就是类名首字母小写
        -->
        <property name="typeAliasesPackage" value="com.tyhxzy.entity"/>

        <!--
        将映射文件加载进来
        -->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>


    <!--
     创建数据访问层对象
     <property name="basePackage" value="数据访问层接口所在的包名"/>
      <property name="sqlSessionFactoryBeanName" value="sqlsessionfacrpty的对象名"/>
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.tyhxzy.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="sss"/>
    </bean>

    <!--
    扫描注解 创建业务逻辑性对象 以及实现将数据访问层对象注入给业务逻辑层的属性
    -->
    <context:component-scan base-package="com.tyhxzy.service.impl"/>
</beans>

springmvc.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--
    .noHandlerFound No mapping for GET /pp/book/find
    -->
    <context:component-scan base-package="com.tyhxzy.controller"/>
    <!--
    创建处理器映射器 处理器适配器
    -->
    <mvc:annotation-driven />

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

mybatis-config.xml

2 功能模块开发

创建数据源对象 在applicationContext.xml

   <context:property-placeholder location="classpath:jdbc.properties"/>
   <!--
   创建德鲁伊对象

   -->
<bean id="dss" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="username" value="${jdbc.name}"/>
    <property name="password" value="${jdbc.pwd}"/>
    <property name="driverClassName" value="${jdbc.driverclass}"/>
    <property name="url" value="${jdbc.url}"/>
</bean>

数据层开发(BookDao)

Book实体类

package com.tyhxzy.entity;

import lombok.Data;

@Data
public class Book {
    private Integer id;
    private String type;
    private String name;
    private String desc;
    
}

BookMapper接口

package com.tyhxzy.dao;

import com.tyhxzy.entity.Book;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

public interface BookMapper {

  package com.tyhxzy.mapper;

import com.tyhxzy.entity.Book;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface BookMapper {


    List<Book> findall(String name);

    @Insert("insert into book values(null,#{type},#{name},#{desc})")
    int saveBook(Book book);




}

}

<?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.tyhxzy.mapper.BookMapper">

    <select id="findall" resultType="book">
        select  * from book
        <where>
            <if test="name!='all'">
                name like concat('%',#{name},'%')
            </if>
        </where>
    </select>
</mapper>

业务层开发(BookService/BookServiceImpl)

BookService接口

package com.tyhxzy.service;

import com.tyhxzy.entity.Book;

import java.util.List;

public interface BookService {
    List<Book> selectAll(String name);

    int saveBook(Book book);
}

BookServiceImpl实现类

@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookMapper bookMapper;
    @Override
    public List<Book> selectAll(String name) {
        return bookMapper.findall(name);
    }

    @Override
    public int saveBook(Book book) {
        return bookMapper.saveBook(book);
    }
}

表现层开发(BookController)

package com.tyhxzy.controller;

import com.tyhxzy.entity.Book;
import com.tyhxzy.service.BookService;
import com.tyhxzy.util.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
//@ResponseBody+@Controller
@RestController
@RequestMapping("/book")
// 取消跨域限制
@CrossOrigin
public class BookController {

    @Autowired
    private BookService bookService;

    @RequestMapping("/find")
    public R find(@RequestParam(value = "aa",required = false,defaultValue = "all") String name){


        List<Book> books = bookService.selectAll(name);
        if(books==null){

             R r = new R(false,"查询失败",null);
              return r;
        }else{
            R r = new R(true,"查询成功",books);
            return r;
        }

    }


    @RequestMapping("/save")
    public R save(@RequestBody Book book){

      int res=  bookService.saveBook(book);
      if(res>0) {
          R r = new R(true, "保存成功", null);
          return r;
      }else{
          R r = new R(false, "保存失败", null);
          return r;
      }

    }
}

postman测试表现层接口

image-20230612170021296

表现层数据封装

表现层响应数据的问题

问题:我们表现层增删改方法返回true或者false表示是否成功,getById()方法返回一个json对象,getAll()方法返回一个json对象数组,这里就出现了三种格式的响应结果,极其不利于前端解析。

image-20230612170112545

解决:我们需要统一响应结果的格式

定义Result类封装响应结果

package com.tyhxzy.entity;

import lombok.Data;

@Data
public class Result {

    private Integer code; //状态码, 代表本次请求成功还是失败  1000010

    private Object data; //数据,请求成功携带的数据

    private String msg ; //消息说明。


    public Result() {
    }


    public Result(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Result(Integer code, Object data, String msg) {
        this.code = code;
        this.data = data;
        this.msg = msg;
    }
}

注意事项:

Result类中的字段并不是固定的,可以根据需要自行增减

Code类封装响应码

package com.tyhxzy.domain;

//状态码
public interface Code {
    Integer SAVE_OK = 20011;
    Integer DELETE_OK = 20021;
    Integer UPDATE_OK = 20031;
    Integer GET_OK = 20041;

    Integer SAVE_ERR = 20010;
    Integer DELETE_ERR = 20020;
    Integer UPDATE_ERR = 20030;
    Integer GET_ERR = 20040;
}

注意事项:

Code类的常量设计也不是固定的,可以根据需要自行增减,例如将查询再进行细分为GET_OK,GET_ALL_OK,GET_PAGE_OK

表现层数据封装返回Result对象

package com.tyhxzy.controller;

import com.tyhxzy.entity.Book;
import com.tyhxzy.entity.Code;
import com.tyhxzy.entity.Result;
import com.tyhxzy.service.BookService;
import org.apache.ibatis.annotations.Delete;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.List;

//@Controller //把该类变成一个controller
@RestController //@RestController作用: 1. 会把该类变成contrller, 2. 所有方法的返回值都是json
@RequestMapping("/books")
public class BookController {

    @Autowired
    private BookService bookService;


    /**
     * 添加图书
     * restful风格对于增加使用post的请求方式
     * @param book
     * @return
     */
    @PostMapping
    public Result save(@RequestBody  Book book){
        boolean result = bookService.save(book);
        if(result){
            return new Result(Code.SAVE_OK,"添加成功");
        }else{
            return new Result(Code.SAVE_ERR,"添加失败");
        }
    }

    /**
     * 删除图书
     * restful风格对于删除使用delete的请求方式
     * @param id
     * @return
     *
     * restFul传参
     *     对于get与delete的请求不能使用json传参,只能使用路径传参
     *     post与put可以使用json传参。
     */
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable  Integer id){
        boolean result = bookService.delete(id);
        if(result){
            return new Result(Code.DELETE_OK,"删除成功");
        }else{
            return new Result(Code.DELETE_ERR,"删除失败");
        }
    }


    /**
     * 修改图书
     * restful风格对于增加使用put的请求方式
     * @param book
     * @return
     */
    @PutMapping
    public Result update(@RequestBody  Book book){
        boolean result = bookService.update(book);
        if(result){
            return new Result(Code.UPDATE_OK,"更新成功");
        }else{
            return new Result(Code.UPDATE_ERR,"更新失败");
        }
    }


    /**
     * 查询单个图书
     * restful风格对于查询使用get的请求方式
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public Result findById(@PathVariable("id") Integer id){
        Book book = bookService.getById(id);
        if(book!=null){
            return new Result(Code.GET_OK,book,"查询成功");
        }else{
            return new Result(Code.GET_ERR,book,"查询失败");
        }
    }


    /**
     * 查询所有图书
     * restful风格对于查询使用get的请求方式
     * @return
     */
    @GetMapping
    public Result findById(){
        List<Book> bookList = bookService.getAll();
        if(bookList!=null&&bookList.size()>0){
            return new Result(Code.GET_OK,bookList,"查询成功");
        }else{
            return new Result(Code.GET_ERR,bookList,"查询失败");
        }
    }



}

  • 统一表现层的返回值结果是作用是什么?

    • 前后端分离开发的情况下,前端人员不清楚后端人员controller的返回值是什么会给前端人员造成困扰,所以我们就统一返回值结果。让前后端开发人员根据有默契
  • Result对象的每一个字段代表什么意思?

    • code : 状态码,表示请求成功还是失败
    • data 请求成功返回的数据
    • msg 状态码的消息说明