前言

SSM(Spring+SpringMVC+MyBatis)框架集由Spring、MyBatis两个开源框架整合而成;

以下我将分别搭建出Spring、SpringMVC、Mybatis的环境;

以spring为平台,把3层架构里SpringMVC的controller处理器对象、service层的实现类对象、Mybatis的创建的mapper对象放到容器中;

各个对象放到spring的容器之后,进行依赖注入,实现3层之间的调用;

1.SSM框架集合

  • SpringMVC负责表示层跟用户交互
  • Spring负责业务层逻辑(声明式事务)
  • Mybatis负责持久层对数据库操作

2.SSM整合基本思路:

  • 使用Spring( 容器 )来整合Mybatis和SpringMVC

3.整合步骤是这样:

  • 先各自搭建SSM的环境
  • 使用Spring整合Mybatis
  • 使用Spring整合Springmvc

 

一、开发环境

先准备一下开发环境;

1.导入pom依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  <modelVersion>4.0.0</modelVersion>  
  <groupId>com.zhanggen</groupId>  
  <artifactId>ssm</artifactId>  
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
    <dependencies>

    <!--mybatis相关-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.15</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.1</version>
    </dependency>


    <!--spring相关-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.1.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.7</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.1.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.1.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    </dependency>


    <!--spring跟mybatis整合-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.5</version>
    </dependency>

    <!--json转换-->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.8</version>
    </dependency>

    <!--辅助-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.8</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
</dependencies>
</project>
pom.xml

2.数据库创建User表

-- 创建学生表
CREATE TABLE student(
  number VARCHAR(10) UNIQUE,   -- 学号
  NAME VARCHAR(10),            -- 姓名
  birthday DATE,               -- 生日
  address VARCHAR(200)         -- 地址
);
INSERT INTO student VALUES ('hm001','张弢','1995-05-05','北京市昌平区');
INSERT INTO student VALUES ('hm002','少林圣神','1996-06-06','北京市海淀区');
INSERT INTO student VALUES ('hm003','易云','1997-07-07','北京市朝阳区');
INSERT INTO student VALUES ('hm004','易天行','1998-08-08','北京市丰台区');
INSERT INTO student VALUES ('hm005','易继风','1999-09-09','北京市顺义区');
INSERT INTO student VALUES ('hm006','飞龙将军','2000-01-01','北京市西城区');
INSERT INTO student VALUES ('hm007','逍遥王','2001-02-02','北京市延庆区');
INSERT INTO student VALUES ('hm008','张君宝','2002-03-03','北京市东城区');
INSERT INTO student VALUES ('hm009','张启樵','2003-04-04','北京市东城区');
student.sql

 

二、dao层搭建

使用Mybatis实现dao层,Mybatis的使用流程如下

  • 读取配置mybatis文件为数据流
  • 创建SqlSessionFactory工厂
  • 通过SqlSessionFactory工厂类获取sqlSession对象
  • 通过sqlSession对象的getMapper()方法获取studentMapper对象
  • 执行studentMapper对象的接口方法
  • 提交事务
  • 释放资源

1.Mybatis的外部配置文件(properties)

Mybatis是一个持久层框架,Mybatis的底层还是jdbc;

为了配置信息的拆分以及便于项目打包后,可以对数据库信息的灵活修改;

我们通常会把jdbc配置信息单独放到1个properties配置文件,再由Mybatis的主配置文件进行引入;

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.56.18:3306/dbForJava?characterEncoding=utf8
jdbc.username=zhanggen
jdbc.password=123.com
jdbc.properties

2.Mybatis配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--引入外部的properties文件-->
    <properties resource="jdbc.properties">
    </properties>
    <!--起别名-->
    <typeAliases>
        <package name="com.zhanggen.domian"></package>
    </typeAliases>
    <!--mybatis数据环境配置-->
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--指定为那个包下的接口产生代理对象-->
    <mappers>
        <package name="com.zhanggen.mapper"></package>
    </mappers>

</configuration>
mybatis-config.xml

3.实体类

package com.zhanggen.domian;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private String number;
    private String name;
    private Date birthday;
    private String address;
}
Student.java

4.StudentMapper接口

package com.zhanggen.mapper;

import com.zhanggen.domian.Student;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface StudentMapper {
    //查询所有
    @Select("select * from student")
    List<Student> findAll();
}
StudentMapper.interface

5.加入日志配置文件

### 设置###
log4j.rootLogger = debug,stdout

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
log4j.properties

6.测试Mybatis

package com.zhanggen.test;

import com.zhanggen.domian.Student;
import com.zhanggen.mapper.StudentMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class StudentMapperTest {
    @Test
    public void testFindAll() throws IOException {
        //1.读取配置mybatis文件为数据流
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        //2.创建SqlSessionFactory工厂
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //3.创建sqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //4.获取studentMapper对象执行方法
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        //5.提交事务
        List<Student> studenList = studentMapper.findAll();
        for (Student student : studenList) {
            System.out.println(student);
        }
        //释放资源
        sqlSession.commit();
        sqlSession.close();


    }
}
StudentMapperTest.java

 

三、service层搭建

实现service层不需要依赖其他第三方包,但需要借助spring把service实现对象放到spring的容器中

1.spring配置文件

配置spring容器启动时扫描service层的注解

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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/aop
                http://www.springframework.org/schema/aop/spring-aop.xsd
                http://www.springframework.org/schema/tx
                http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--spring容器扫描service层的注解-->
    <context:component-scan base-package="com.zhanggen.service"></context:component-scan>

</beans>
applicationContext.xml

2.定义service接口

package com.zhanggen.service;

import com.zhanggen.domian.Student;

import java.util.List;

public interface StudentService {
    //查询所有
    List<Student> findAll();
}
StudentService.interface

3.创建接口实现类

package com.zhanggen.service.impl;

import com.zhanggen.domian.Student;
import com.zhanggen.mapper.StudentMapper;
import com.zhanggen.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service //把当前实现类实例化的对象,放入spring的IOC容器
public class StudentServiceImpl implements StudentService {
//    @Autowired //调用spring的IOC容器中的StudentMapper对象
    //todo 等待StudentMapper对象放入pring的IOC容器中
    private StudentMapper studentMapper;

    public List<Student> findAll() {
        //todo 等待StudentMapper对象放入pring的IOC容器中
//        List<Student> userList = studentMapper.findAll();
        System.out.println("service中findAll()方法被调用了");
        return null;
    }
}
StudentServiceImpl.java

4.测试service层实现类

package com.zhanggen.test;

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

import java.io.IOException;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class StudentServiceTest {
    @Autowired
    private StudentService studentService;

    @Test
    public void testFindAll() throws IOException {
        studentService.findAll();
    }
}
StudentServiceTest.java

 

四、controller层搭建

使用springMVC实现控制(controller)层;

Tomcat通过web.xml配置文件调用springMVC(控制层);

1.web.xml

Tomcat读取web项目的web.xml配置文件以调用dispatcherServlet;

<?xml version="1.0" encoding="UTF-8"?>
<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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <!--springMVC扫描controller层的注解-->
    <context:component-scan base-package="com.zhanggen.controller"></context:component-scan>

    <!--配置注解驱动-->
    <mvc:annotation-driven/>

    <!--释放静态资源-->
</beans>
web.xml

2.springMVC配置文件

dispatcher读取springMVC配置文件,实现注解驱动、扫描controller层的注解;

<?xml version="1.0" encoding="UTF-8"?>
<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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <!--springMVC扫描controller层的注解-->
    <context:component-scan base-package="com.zhanggen.controller"></context:component-scan>

    <!--配置注解驱动-->
    <mvc:annotation-driven/>

    <!--释放静态资源-->
</beans>
spring-mvc.xml

3.配置处理器

dispatcherServlet通过@Mapping("/student")注解把http请求路由到处理器;

通过@RestController注解把处理器实现类放到spring的容器中;

package com.zhanggen.controller;

import com.zhanggen.domian.Student;
import com.zhanggen.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

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

@RestController//@Controller+@ResponseBody
public class UserController {
    //todo 目前springMVC和spring环境还未做整合,不能完成依赖注入
//    @Autowired //从spring的容器中调用studentService对象
    private StudentService studentService;

    @GetMapping("/student")
    public List<Student> findAll() {
//        List<Student> studentList = studentService.findAll();
        ArrayList<Student> studentList = new ArrayList<Student>();
        studentList.add(new Student("1", "逍遥王", new Date(), "西域"));
        studentList.add(new Student("2", "易云", new Date(), "名剑山庄"));
        studentList.add(new Student("3", "圣神", new Date(), "少林寺"));
        return studentList;
    }
}
UserController.java

 

五、Spring整合Mybatis

将Mybatis的所有配置信息转移到Spring的配置文件中,为创建工厂做准备;

将Mybatis的SqlSessionFactory(工厂)托管到Spring的容器中;

当SqlSessionFactory(工厂)托管到Spring的容器中之后;

org.mybatis.spring.SqlSessionFactoryBean可以实现将SqlSessionFactory(工厂)创建出来的SqlSession对象和所有dao层的mapper全部自动托管到spring容器中;

1.spring配置文件修改

修改spring的配置文件,把mybatis的配置转移到spring的配置文件中;

不能直接把Mybatis的配置信息复制到spring的配置中;

在spring的配置文件中有对应的标签可以实现Mybatis的配置;

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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/aop
                http://www.springframework.org/schema/aop/spring-aop.xsd
                http://www.springframework.org/schema/tx
                http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--spring容器扫描service层的注解-->
    <context:component-scan base-package="com.zhanggen.service"></context:component-scan>

    <!--spring整合Mybatis: 配置Mybatis使用外部properties文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--spring整合Mybatis: 配置Mybatis的数据源为德鲁伊Druid,不在使用POOLED-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <!--spring整合Mybatis: 配置Mybatis事务管理器为DataSourceTransactionManager-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--spring整合Mybatis: 配置Mybatis需要通过扫描哪1个mapper包下mapper接口进行mapper对象的创建-->
    <bean id="configurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.zhanggen.mapper"/>
    </bean>
    <!--spring整合Mybatis:配置Mybatis的SqlSessionFactory创建的Sqlsession和mapper对象自动托管到spring的容器中-->
    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--配置数据类型别名:当数据类型名称过长时,可以通过typeAliases设置类型的别名-->
        <property name="typeAliasesPackage" value="com.zhanggen.domian"/>

    </bean>
</beans>
applicationContext.xml

2.service层注入mapper对象

如果service层的实现类对象想要调用dao层Mybatis创建出来的mapper对象,需要先把自己托管到spring容器中;

在service层的实现类对象中注入mapper对象以实现service调用dao层的目的;

package com.zhanggen.service.impl;

import com.zhanggen.domian.Student;
import com.zhanggen.mapper.StudentMapper;
import com.zhanggen.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service //把当前Service层实现类实例化的对象,放入spring的IOC容器
public class StudentServiceImpl implements StudentService {
    @Autowired //调用spring的IOC容器中的StudentMapper对象
    private StudentMapper studentMapper;

    public List<Student> findAll() {
        List<Student> userList = studentMapper.findAll();
        System.out.println(userList);
        return userList;
    }
}
StudentServiceImpl

3.测试service层

加载spring的修改完毕的applicationContext.xml配置文件,通过service层调用dao层Mybatis;

package com.zhanggen.test;

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

import java.io.IOException;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class StudentServiceTest {
    @Autowired
    private StudentService studentService;

    @Test
    public void testFindAll() throws IOException {
        studentService.findAll();
    }
}
StudentServiceImpl.java

 

六、Spring整合SpringMVC

Spring是根容器,SpringMVC是其子容器,所以Spring和SpringMVC本身就已经整合完毕,现在的问题是当Tomcat启动时,Spring容器自己无法启动

启动Spring容器的工作可交给ContextLoaderListener监听器;

 

1.ContextLoaderListener监听器

在web.xml配置文件中配置1个ContextLoaderListener监听器,

ContextLoaderListener的作用就是当Tomcat启动时,通过监听器,自动装配ApplicationContext的配置信息,启动spring容器;

   <!--监听器(Listener):可以监听tomcat,当tomcat启动的时候,会帮助我们读取spring的配置文件,启动spring容器-->
    <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>

2.controller中注入service对象

package com.zhanggen.controller;

import com.zhanggen.domian.Student;
import com.zhanggen.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

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

@RestController//@Controller+@ResponseBody
public class UserController {
    @Autowired //从spring的容器中调用studentService对象
    private StudentService studentService;

    @GetMapping("/student")
    public List<Student> findAll() {
        List<Student> studentList = studentService.findAll();
//        ArrayList<Student> studentList = new ArrayList<Student>();
//        studentList.add(new Student("1", "逍遥王", new Date(), "西域"));
//        studentList.add(new Student("2", "易云", new Date(), "名剑山庄"));
//        studentList.add(new Student("3", "圣神", new Date(), "少林寺"));
        return studentList;
    }
}
UserController.java

3.设置Json转换格式

package com.zhanggen.domian;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private String number;
    private String name;
    //通过 @JsonFormat注解指定json转换规则
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date birthday;
    private String address;
}
Student.java

4.测试

重启Tomcat,通过URL访问Controller层;

 

七、增删改查案例

以上已经整合了SSM框架,以下该使用该框架进行开发;

1.SpringMVC释放静态资源

让前端用户可以访问到后端的静态资源

 <!--释放静态资源-->
    <mvc:resources mapping="/index.html" location="/"/>
    <mvc:resources mapping="/css/*" location="/css/"/>
    <mvc:resources mapping="/js/*" location="/js/"/>
    <mvc:resources mapping="/fonts/*" location="/fonts/"/>
    <mvc:resources mapping="/img/*" location="/img/"/>
    <mvc:resources mapping="/js/*" location="/js/"/>
spring-mvc.xml

2.前后端交互对象引入(View Object)

规范后端返回给前端的数据格式

package com.zhanggen.vo;

import lombok.Data;

import java.io.Serializable;

//表示层对象:View Object,通用返回结果,服务端响应的数据最终都会封装成此对象
@Data
public class ResultInfo implements Serializable {
    private Integer code; //编码:1成功,0和其它数字为失败
    private String msg; //错误信息
    private Object data; //数据

    //成功结果
    public static ResultInfo success(Object object) {
        ResultInfo resultInfo = new ResultInfo();
        resultInfo.data = object;
        resultInfo.code = 1;
        return resultInfo;
    }

    //失败结果
    public static ResultInfo error(String msg) {
        ResultInfo resultInfo = new ResultInfo();
        resultInfo.msg = msg;
        resultInfo.code = 0;
        return resultInfo;
    }
}
ResultInfo.java

3.Controller控制层

package com.zhanggen.controller;

import com.zhanggen.domian.Student;
import com.zhanggen.service.StudentService;
import com.zhanggen.vo.ResultInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

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

@RestController//@Controller+@ResponseBody
public class UserController {
    @Autowired //从spring的容器中调用studentService对象
    private StudentService studentService;

    @GetMapping("/student")
    public ResultInfo findAll() {
        List<Student> studentList = studentService.findAll();
        return ResultInfo.success(studentList);
    }
    //保存
    @PostMapping("/student")
    public ResultInfo save(@RequestBody Student student ) {
        studentService.save(student);
        return ResultInfo.success(null);
    }
    //根据主键查询
    @GetMapping("/student/{number}")
    public ResultInfo findById(@PathVariable String number) {
        Student student=studentService.findById(number);
        System.out.println(number);
        return ResultInfo.success(student);
    }
    //根据主键修改
    @PutMapping("/student")
    public ResultInfo update(@RequestBody Student student) {
        //调用service修改
        studentService.update(student);
        //返回结果
        return ResultInfo.success(null);
    }
    //根据主键删除
    @DeleteMapping("/student/{number}")
    public ResultInfo delete(@PathVariable String number) {
        //调用service修改
        studentService.delete(number);
        //返回结果
        return ResultInfo.success(null);
    }


}
UserController.java

4.service服务层

4.1.接口

package com.zhanggen.service;

import com.zhanggen.domian.Student;

import java.util.List;

public interface StudentService {
    //查询所有
    List<Student> findAll();

    //新增
    void save(Student student);

    //根据number主键查询
    Student findById(String number);

    //根据number主键修改
    void update(Student student);

    //根据number主键删除
    void delete(String number);
}
StudentService.interface

4.2.实现类

package com.zhanggen.service.impl;

import com.zhanggen.domian.Student;
import com.zhanggen.mapper.StudentMapper;
import com.zhanggen.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service //把当前Service层实现类实例化的对象,放入spring的IOC容器
@Transactional
public class StudentServiceImpl implements StudentService {
    @Autowired //调用spring的IOC容器中的StudentMapper对象
    private StudentMapper studentMapper;

    //查询所有
    public List<Student> findAll() {
        List<Student> userList = studentMapper.findAll();
        return userList;
    }

    //保存
    public void save(Student student) {
        studentMapper.save(student);
        //测试声明式事务和springMVC的统一异常处理
        // int i=1/0;
    }

    //根据主键查询
    public Student findById(String number) {
        return studentMapper.findById(number);
    }

    //根据主键修改
    public void update(Student student) {
        studentMapper.update(student);
    }
    //根据主键删除
    public void delete(String number) {
        studentMapper.delete(number);

    }
}
StudentServiceImpl.java

5.dao/mapper层

使用Mybatis实现dao层不需要定义实现类,因为Mybatis会根据你定义的接口,自动创建该结构的实现类对象(mapper对象);

package com.zhanggen.mapper;

import com.zhanggen.domian.Student;
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 StudentMapper {
    //查询所有
    @Select("select * from student")
    List<Student> findAll();

    //保存
    @Insert("insert into student values(#{number},#{name},#{birthday},#{address})")
    void save(Student student);

    //编辑时-根据主键查询
    @Select("select * from student where number=#{number}")
    Student findById(String number);

    //编辑时-修改
    @Update("update student set name = #{name},birthday = #{birthday},address = #{address} where number = #{number}")
    void update(Student student);

    //根据注解删除
    @Delete("delete from student where number = #{number}")
    void delete(String number);
}
StudentMapper.interface

 

 

八、添加声明式事务

使用事务管理器,保证项目中1组SQL操作出现异常时,可以进行事务回滚;

1.Spring配置事务注解驱动

   <!--spring整合声明式事务: 配置事务注解驱动-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
applicationContext.xml

2.service层增加事务

给service层实现类上增加@Transactional注解

@Service //把当前Service层实现类实例化的对象,放入spring的IOC容器
@Transactional
public class StudentServiceImpl implements StudentService {

 

九、SpringMvc统一异常处理

SpringMvc的统一异常处理功能:可以保证后台出错情况下和正常情况下, 响应给前端的数据格式是一致的;

1.spring配置注解扫描

  <!--spring容器扫描handler的注解,完成统一异常处理-->
    <context:component-scan base-package="com.zhanggen.handler"></context:component-scan>
applicationContext.xml

2.定义异常处理类

package com.zhanggen.handler;

import com.zhanggen.vo.ResultInfo;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice //该注解可以声明当前类是一个用于统一处理3层异常的类
@ResponseBody
public class CommonExceptionHandler {
    @ExceptionHandler(Exception.class)  //标注该方法可以处理哪些类型的异常
    public ResultInfo handleAllException(Exception e) {
        //记录错误日志
        e.printStackTrace();
        //给前端提示
        return ResultInfo.error("后端异常");
    }
}
CommonExceptionHandler.java

 

十、注解扫描配置

Spring和SpringMVC的容器具有父子关系,Spring容器为父容器,SpringMVC为子容器

子容器可以引用父容器中的Bean,而父容器不可以引用子容器中的Bean;

为了保证应该放到spring容器中bean放到spring的容器中,应该放到SpringMVC容器中bean放到SpringMVC的容器中

Spring官方建议spring的配置文件(applicationContext.xml)配置如下:

    <!--spring容器启动时扫描com.zhanggen包下所有注解,并把注解的对象放到spring的容器中-->
    <context:component-scan base-package="com.zhanggen">
        <!--排除掉类上标有RestController注解的类(所有的controller)因为  -->
        <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.RestController"/>
    </context:component-scan>

通过排除对Controller层的扫描,避免Controller层注解产生的bean放到Spring的容器中,造成事务失效;

 

 

posted on 2022-05-23 15:59  Martin8866  阅读(60)  评论(0编辑  收藏  举报