当前位置: 首页 > news >正文

SSM整合(超详细)

SSM整合

步骤

  1. 创建工程

  2. SSM整合

    • Spring
      • SpringConfig
    • MyBatis
      • MybatisConfig
      • JdbcConfig
      • jdbc.properties
    • SpringMVC
      • ServletConfig
      • SpringMvcConfig

    3.功能模块

    • 表和实体类

    • Dao(接口+自动代理)

    • service(接口+测试类)

      • 业务层接口(整合Junit)
    • Controller

      • 表现层接口测试(PostMan)

一:导入相关依赖

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>

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

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

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.16</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.0</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.1</version>
            <configuration>
                <port>80</port>
                <path>/</path>
            </configuration>
        </plugin>
    </plugins>
</build>

二:创建相应包和类

在这里插入图片描述

三:编写相应配置类

3.1:Spring配置类

@Configuration
@Import({JdbcConfig.class,MybatisConfig.class})
@ComponentScan("com.ysj.service")
@PropertySource("classpath:jdbc.properties")
public class SpringConfig {
}

3.2:MyBatis配置类

3.2.1:Mybatis

public class MybatisConfig {



    @Bean
   public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){

       SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
       sqlSessionFactoryBean.setTypeAliasesPackage("com.ysj.Domain");
        sqlSessionFactoryBean.setDataSource(dataSource);
       return sqlSessionFactoryBean;
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();

        mapperScannerConfigurer.setBasePackage("com.ysj.Dao");
        return mapperScannerConfigurer;
    }

}

3.2.2:Jdbc配置类

public class JdbcConfig {
//    jdbc.driver=com.mysql.jdbc.Driver
//    jdbc.url=jdbc:mysql://localhost:3308/mybatis
//    jdbc.username=root
//    jdbc.password=yangshijie
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource(){

        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);

        return dataSource;
    }

}

3.2.3:Jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root

4:SpringMVC配置类

  • 控制表现层(这个配置类如果导入SpringConfig中,SpringMVC控制的bean也会被Spring控制)

    @Configuration
    @ComponentScan("com.ysj.Controller")
    @EnableWebMvc
    public class SpringMvcConfig {
    }
    
  • web配置类

    //web配置类
    public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
        protected Class<?>[] getRootConfigClasses() {
            return new Class[]{SpringConfig.class};
        }
    
        protected Class<?>[] getServletConfigClasses() {
            return new Class[]{SpringMvcConfig.class};
        }
    
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    }
    

5:Junit测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class) //上下文配置类
public class BookServiceTest {

    @Autowired
    private BookService bookService;

    @Test
    public void testGetById(){
        Book book = bookService.getById(1);
        System.out.println(book);
    }

    @Test
    public void testGetAll(){
        List<Book> all = bookService.getAll();
        System.out.println(all);
    }

}

6:事务管理器

6.1:注册驱动

  • ​ 在Spring配置类中注册事务管理驱动

    @EnableTransactionManagement
    

6.2:配置平台事务管理容器

  • 可在Jdbc配置类中直接配置
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
    DataSourceTransactionManager ds = new DataSourceTransactionManager();
    ds.setDataSource(dataSource); //别用方法调用,否则就变成了java语言管理,而不是Speing容器管理了
    return ds;
}

6.3:加事务

  • 直接在service接口类上加@Transactional

  • 后续有更多需求再加(事务传播行为等)

    @Transactional
    

7:前后端传输协议

7.1:后端返回值

public class Result {
    //描述统一格式中的数据
    private Object data;
    //描述统一格式中的编码,用于区分操作,可以简化配置0或1表示成功失败
    private Integer code;
    //描述统一格式中的消息,可选属性
    private String msg;

    public Result() {
    }

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

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

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}
  • 编写Code编码类(状态码)

    public class Code {
        public static final Integer SAVE_OK = 20011;
        public static final Integer DELETE_OK = 20021;
        public static final Integer UPDATE_OK = 20031;
        public static final Integer GET_OK = 20041;
    
        public static final Integer SAVE_ERR = 20010;
        public static final Integer DELETE_ERR = 20020;
        public static final Integer UPDATE_ERR = 20030;
        public static final Integer GET_ERR = 20040;
    
        public static final Integer SYSTEM_ERR = 50001;
        public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
        public static final Integer SYSTEM_UNKNOW_ERR = 59999;
    
        public static final Integer BUSINESS_ERR = 60002;
    
    
    
    }
    

8:自定义异常处理器

  • 新建一个excepition包
  • 包下创建所需各个异常类

8.1:总的异常处理器

//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
    //@ExceptionHandler用于设置当前处理器类对应的异常类型
    @ExceptionHandler(SystemException.class)
    public Result TestExcepition(TestExcepition ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(ex.getCode(),null,ex.getMessage());
    }
    
    //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
    @ExceptionHandler(Exception.class)
    public Result doOtherException(Exception ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
    }
}

8.2:自定义分类的异常处理器类

  • 记得继承相应的异常父类,
    • 原因:程序运行时遇到相应异常后可以不处理向上抛
    • 不继承坏处:以后每个方法都要加上这个类
//继承RuntimeException类
public class TestExcepition extends RuntimeException {

    private Integer code; //区别自定义异常类的编码

    public TestExcepition(Integer code) {
        this.code = code;
    }

    public TestExcepition(String message, Integer code) {
        super(message);
        this.code = code;
    }

    public TestExcepition(String message, Throwable cause, Integer code) {
        super(message, cause);
        this.code = code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public Integer getCode() {
        return code;
    }
}

9:拦截器

9.1:拦截器概念

  • 拦截器是是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行(执行的时候类似栈思想)
  • 作用
    • 在指定的方法执行前后调用我们预先设定的代码
    • 阻止原始方法的执行(权限)

在这里插入图片描述

9.2:拦截器和过滤器的区别

9.2.1 精简版

  • 过滤器是Servlet技术,其可以对几乎所有的请求进行增强
  • 拦截器是SpringMVC技术,仅仅对SpringMVC技术进行增强

9.2.2 详细版

以下信息来源于html中文网

在这里插入图片描述

9.3:拦截器入门

  • 拦截器在表现层生效,所以建议在controller包下新建Interceptor包

    在这里插入图片描述

  • 在该包下新建所需拦截器类(类继承HandlerInterceptor接口)

//继承HandlerInterceptor接口
//注意当前类必须受Spring容器控制
@Component
public class TestProjectInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //中间可以加上所需业务逻辑
        return false;//这个返回值决定了后续的原生方法等是否会执行
    }
//原始方法调用后执行的内容
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }
//原始方法调用完成后执行的内容
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
  • 将其加入SpringMvc控制中

  • 方法:

    • 新建一个类,继承WebMvcConfigurationSupport

      @Configuration
      public class SpringMvcSupport extends WebMvcConfigurationSupport {
      
          @Autowired
          private TestProjectInterceptor testProjectInterceptor;
      //    *    匹配单个字符,如 /user/* 匹配的是 /user/aa,/user/bb 等,又如  /user/*/ab 匹配到 /user/p/ab;
      //            **   匹配任意多字符(包括多级路径),如:/user/** 匹配到 /user/aa、/user/p/bb 等;
          //配置相应的静态资源放行
          @Override
          protected void addResourceHandlers(ResourceHandlerRegistry registry) {
              registry.addResourceHandler("pages/**").addResourceLocations("pages/");
          }
      
          @Override
          protected void addInterceptors(InterceptorRegistry registry) {
              registry.addInterceptor(testProjectInterceptor).addPathPatterns("books/","books/*");
          }
      }
      
    • 直接在SpringMvc配置类中进行

      • 让SpringMvc配置类继承WebMvcConfigurer接口
    @Configuration
    @ComponentScan({"com.ysj.controller"})
    @EnableWebMvc
    //实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
    public class SpringMvcConfig implements WebMvcConfigurer {
        @Autowired
        private ProjectInterceptor projectInterceptor;
        @Autowired
        private ProjectInterceptor2 projectInterceptor2;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //配置多拦截器
            registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
            registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");
        }
    }
    

9.4🎃拦截器参数

  • request:请求对象

  • response:响应对象

  • handler:一个被调用的处理器对象,其本质上是一个方法对象(HandlerMethod),对反射技术中的

    ​ Method进行的再包装。

  • ModelAndView:若处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行调整

  • Exception:获取程序运行过程中的异常对象(可通过SpringMvc自定义的异常处理器完美代替)

9.5🛋拦截器链

  • 创建所需的多个拦截器类

    在这里插入图片描述

  • 配置多拦截器

        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //配置多拦截器
            registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
            registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");
        }
    }
    
  • 多拦截器执行顺序

    • 按添加顺序运行
    • 若其中一个拦截器触发拦截条件,返回值为false,则直接跳到afterCompletion方法处,然后(出栈思想)
      在这里插入图片描述

的异常处理器完美代替)

9.5🛋拦截器链

  • 创建所需的多个拦截器类

    在这里插入图片描述

  • 配置多拦截器

        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //配置多拦截器
            registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
            registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");
        }
    }
    
  • 多拦截器执行顺序

    • 按添加顺序运行
    • 若其中一个拦截器触发拦截条件,返回值为false,则直接跳到afterCompletion方法处,然后(出栈思想)
      在这里插入图片描述

** 好了。SSM整合包含的知识点和步骤到这里已经总结完了,如有不足请指正,欢迎各位来一起交流讨论。
最后,创作不易,给个三连支持下呗。**

相关文章:

  • 【程序语言】-- 编程语言分类和应用
  • Springboot三层架构--DAO层、Service层、Colltroler层--这波我在外太空
  • Selenium快速入门
  • manim|集合的运算
  • 【代理设计模式 Objective-C语言】
  • 【C++】类和对象 (上篇)
  • 【Shell编程】Bash变量-用户自定义变量
  • MySQL经典练习题+解题思路(三)
  • 基于STM32的TM1638的按键控制以及数码管和LED灯的动态扫描
  • 【Linux】Tomcat优化
  • 10.4复习
  • LVGL v8学习笔记 | 09 - 进度条控件的使用方法(bar)
  • 力扣239 - 滑动窗口的最大值【单调队列的原理】
  • 基于JavaWeb的学生成绩管理系统设计与实现
  • CVPR 2022 | HorNet:递归门控卷积的高效高阶空间相互作用
  • [译] 怎样写一个基础的编译器
  • 07.Android之多媒体问题
  • CSS 提示工具(Tooltip)
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • ES6系统学习----从Apollo Client看解构赋值
  • gops —— Go 程序诊断分析工具
  • javascript 总结(常用工具类的封装)
  • Java程序员幽默爆笑锦集
  • Node + FFmpeg 实现Canvas动画导出视频
  • PHP变量
  • TypeScript实现数据结构(一)栈,队列,链表
  • 阿里研究院入选中国企业智库系统影响力榜
  • 编写符合Python风格的对象
  • 从输入URL到页面加载发生了什么
  • 解析带emoji和链接的聊天系统消息
  • 近期前端发展计划
  • 为什么要用IPython/Jupyter?
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • $.each()与$(selector).each()
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (java)关于Thread的挂起和恢复
  • (第61天)多租户架构(CDB/PDB)
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (转)jQuery 基础
  • (转)大道至简,职场上做人做事做管理
  • .FileZilla的使用和主动模式被动模式介绍
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .NET 8.0 发布到 IIS
  • .NET Core中Emit的使用
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • @ConfigurationProperties注解对数据的自动封装
  • @synthesize和@dynamic分别有什么作用?
  • @我的前任是个极品 微博分析
  • [ vulhub漏洞复现篇 ] JBOSS AS 5.x/6.x反序列化远程代码执行漏洞CVE-2017-12149
  • [ 云计算 | AWS ] 对比分析:Amazon SNS 与 SQS 消息服务的异同与选择