Spring, spring MVC and Mybatis framework integration configuration template (ready to use)

Keywords: Java Spring SSM mvc

✍, Spring, spring MVC and Mybatis framework integration

  • Every time you build an SSM framework integration environment, you always need to configure dependencies in advance. Every time you add a configuration, you need to look through the official website documents or notes, which is a waste of time and sometimes cited errors.
  • This paper integrates the common dependencies in development, from dependency to the establishment of configuration files, including the separation of data sources, the introduction of log files, the construction of MVC architecture, etc. all dependencies are integrated before coding to truly achieve ready to use.
  • Here will be tested with simple small cases. There are detailed graphic tutorials for each step. From the initial environment construction, successful construction, test dao layer, service layer, controller layer, test addition, deletion, modification and query, interceptor, etc., to establish an integration framework template for use!
  • Idea version 2021.1
  • Refer to the video tutorial: Three shift teacher framework integration

1. SSM integration

1.1 step analysis

Let's first analyze how to integrate spring, spring MVC and mybatis.

1.1.1 steps

① Mybatis on Spring integration

Both Dao layers are injected into the Spring container through the Service layer

② Introducing and configuring spring MVC

Inject the Controller layer into the spring MVC container

③ Let the web project automatically read the Spring configuration file when it starts to create a Spring container

You can use ContextLoaderListener to create a Spring container.

1.1.2 common doubts

  • Why use two containers?

    Because if the Controller is not placed in the MVC container, it will have no effect and cannot process the request. If the Service is not placed in the Spring container, declarative transactions cannot be used.

  • The Controller in the Spring MVC container needs to depend on the Service. Can you get the dependent Service object from the Spring container?

    Spring container is the parent container and MVC container is the child container. A child container can use objects in its parent container in addition to objects in its own container.

  • When did two containers have this parent-child relationship?

    In the ContextLoaderListener, the container will be stored in the servletContext field after it is created. In this way, when the dispatcher servlet is started, after creating the Spring MVC container, the Spring container object will be obtained from the servletContext domain and set as its parent container, so that the child container can obtain the bean s in the parent container.

1.2 preparation

  1. Create a normal maven project
  2. File - > project structure - > modules, add web Application

  1. Move the web to the main directory, change its name to webapp, and add the code labeled war package in pom.xml

  1. File - > project structure - > modules, check whether the path is red

  1. If it doesn't explode red, it's OK

1.2.1 import dependency

Introduce all dependencies

 <!--Spring-context Spring Container dependency-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <!--AOP Correlation dependency-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>
        <!-- spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <!-- mybatis Integrate into Spring Consolidation package for -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.4</version>
        </dependency>
        <!--mybatis rely on-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.4</version>
        </dependency>
        <!--log4j Dependency, printing mybatis journal-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!--Paging query, pagehelper-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>4.0.0</version>
        </dependency>

        <!--mysql drive-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!-- druid data source -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>

        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!-- spring integration junit Dependence of -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
		 <!-- Lombok plug-in unit-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
            <scope>provided</scope>
        </dependency>


        <!-- servlet rely on -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!--jsp rely on -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>
        <!--springmvc Dependence of-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>

        <!-- jackson,Help with json transformation-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.0</version>
        </dependency>

        <!--commons File upload. If the file upload function is required, this dependency needs to be added-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>

1.2.2 database initialization

Database initialization statement

CREATE DATABASE /*!32312 IF NOT EXISTS*/`mybatis_db` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `mybatis_db`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `address` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
insert  into `user`(`id`,`username`,`age`,`address`) values 
(1,'UZI',19,'Shanghai'),
(2,'PDD',25,'Shanghai');

1.3 relevant configuration

① Integrating Spring and Mybatis

  1. Create the Spring core configuration file in the resources directory: applicationContext.xml, as follows

<?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:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--Component scan, exclusion controller-->
    <context:component-scan base-package="com.sangeng">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter>
    </context:component-scan>

    <!--read properties file-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <!--Create connection pool injection container-->
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClassName" value="${jdbc.driver}"></property>
    </bean>
    <!--spring integration mybatis Creation and acquisition of post control SqlSessionFactory Object of-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sessionFactory">
        <!--Configure connection pool-->
        <property name="dataSource" ref="dataSource"></property>
        <!--to configure mybatis Path to configuration file-->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
    </bean>

    <!--mapper Scan configuration, scanned mapper Objects are injected Spring In container-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" id="mapperScannerConfigurer">
        <property name="basePackage" value="com.sangeng.dao"></property>
    </bean>

    <!--open aop Annotation support-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    <!--Declarative transaction related configuration-->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

</beans>
  • The mapper scan configuration here is to scan the package com.sangeng.dao, so we create a new Dao package

  1. Create the jdbc.properties file in the resources directory, as follows:

jdbc.url=jdbc:mysql://localhost:3306/mybatis_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
jdbc.driver=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=123456
  1. Create mybatis-config.xml in the resources directory, as follows:

<?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>
    <settings>
        <!--Specify use log4j Print Mybatis journal-->
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <!--Configure alias package-->
    <typeAliases>
        <package name="com.sangeng.domain"></package>
    </typeAliases>
    <plugins>
        <!-- Note: the plug-in of paging assistant is configured in general mapper before -->
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <!-- Designated dialect -->
            <property name="dialect" value="mysql"/>
        </plugin>
    </plugins>
</configuration>
  • The alias is configured for the com.sangeng.domain package in the configuration, so we build a domain package under com.sangeng

  1. Create log4j.properties in the resources directory, as follows:

#Output the log information with the level of DEBUG to stdout, which is defined in the following code
log4j.rootLogger=debug, stdout

#Settings related to console output
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=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

#Settings related to file output
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=./log/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

② Spring MVC introduction

  1. Create spring-mvc.xml in the resources directory, as follows:

<?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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--
         SpringMVC Scan only controller Just pack
     -->
    <context:component-scan base-package="com.sangeng.controller"/>
    <!-- Solve the problem of static resource access, if not mvc:annotation-driven Will result in inaccessibility handler-->
    <mvc:default-servlet-handler/>
    <!--Resolve response garbled code-->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="utf-8"/>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>


    <!--The front and back ends of the configuration view parser are not separated from the project-->
<!--    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
        &lt;!&ndash;Prefix requiring splicing&ndash;&gt;
        <property name="prefix" value="/WEB-INF/page/"></property>
        &lt;!&ndash;Suffix to splice&ndash;&gt;
        <property name="suffix" value=".jsp"></property>
    </bean>-->

    <!--Configuring Interceptors -->
<!--    <mvc:interceptors>

        <mvc:interceptor>
            &lt;!&ndash;
            &ndash;&gt;
            <mvc:mapping path="/**"/>
            &lt;!&ndash;Configure paths to exclude interception&ndash;&gt;
            <mvc:exclude-mapping path="/"/>
            &lt;!&ndash;Configure interceptor object injection container&ndash;&gt;
            <bean class=""></bean>
        </mvc:interceptor>
    </mvc:interceptors>-->

    <!--
          File upload parser
          be careful: id Must be multipartResolver
          If you need to upload files, you can release the corresponding configuration
      -->
    <!--<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">-->
        <!--&lt;!&ndash; Set default character encoding &ndash;&gt;-->
        <!--<property name="defaultEncoding" value="utf-8"/>-->
        <!--&lt;!&ndash; The maximum total size of a file requested to be uploaded at one time, in bytes&ndash;&gt;-->
        <!--<property name="maxUploadSize" value="#{1024*1024*100}"/>-->
        <!--&lt;!&ndash; The maximum size of each uploaded file, in bytes&ndash;&gt;-->
        <!--<property name="maxUploadSizePerFile" value="#{1024*1024*50}"/>-->
    <!--</bean>-->
</beans>
  • The spring MVC scan controller package is configured above, so we need to create a new package controller under sangeng

  1. Finally, modify the web.xml file
<?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>
        <!--
            by DispatcherServlet Providing initialization parameters
            set up springmvc Path to configuration file
                name Is fixed, must be contextConfigLocation
                value refer to SpringMVC Location of the configuration file
         -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <!--
            Specifies that the project is initialized at startup DispatcherServlet
         -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <!--
             /           Represents the current servlet Mapping Division jsp All requests except (including static resources)
             *.do        express.do The end of the request path can be deleted SpringMVC handle(Old projects will appear)
             /*          Represents the current servlet Map all requests (including static resources),jsp),Its configuration should not be used DispatcherServlet
         -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <!--Garbled code processing filter SpringMVC provide-->
    <!-- handle post Request garbled code -->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <!-- name Fixed, value Values are set as needed -->
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <!-- All requests are set utf-8 Coding of -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

③ Integrating Spring into web projects

Let the Spring container be created when the web project starts. You can use the listener ContextLoaderListener provided by Spring, so we need to configure this listener in web.xml and configure the path of the Spring configuration file.

    <!--to configure spring Configuration file path for-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!--Configure the listener, which can be created when the application is deployed spring container-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

In this way, our SSM integration configuration level has been completed. Next, we write tests

1.4. Write Controller,Service, Dao

Let's write the interface to query the user according to the id for testing

First, there is the Controller. The request is processed by the Handler in the Controller. In the Handler, it is processed through the Service. The Service will rely on dao to query the database. dao is written in Mybatis

Therefore, we first write the Controller, then the Service interface, implement the methods in the Service interface, and inject dao into the Service implementation class, then write dao, and then write the corresponding xml Mapping file

1.4.1. Write entity class domain

  • com.sangeng.domain.User.java code is as follows
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    // The attributes here correspond to those of our database one by one
    private Integer id;
    private String username;
    private Integer age;
    private String address;
}

1.4.2. Write Service

  • com.sangeng.service.UserService interface, the code is as follows
public interface UserService {
    User findById(Integer id);
}
  • com.sangeng.service.impl.UserServiceImpl implementation class code is as follows
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    public User findById(Integer id) {
        return userDao.findById(id);
    }
}
  • @The Service annotation is used on the Service layer class to instantiate beans, and set this class as spring managed beans
  • @The Autowired annotation is used on the field for type dependent injection in order to obtain this object from the Spring container

1.4.3 writing dao

  • com.sangeng.dao.UserDao interface, the code is as follows
public interface UserDao {
    /**
     * Query user by id
     * @param id
     * @return
     */
    User findById(Integer id);
}
  • Generate the corresponding mapper mapping file for the interface. Resources - > right click - > new directory generate the corresponding mapper directory

  • The existence of the plug-in can help us generate the mapper.xml mapping file with one click. alt + enter and select the plug-in

  • Select the location where mapper.xml is generated

  • Then continue alt + enter on the method

  • In this way, we only need to write sql statements in the generated mapper.xml

  • Therefore, the code of resources/com/sangeng/dao/UserDao.xml is as follows:
<?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.sangeng.dao.UserDao">


    <select id="findById" resultType="com.sangeng.domain.User">
        select * from user where id = #{id}
    </select>
</mapper>

1.4.4. Write Controller

Requirement: query the user by id

  • The Controller cannot query the database and needs to rely on the service, so you need to create the service interface and implementation class first

  • The service implementation class needs to rely on the dao layer to query the database

  • dao is the operation of querying the database with mybatis

  • Therefore, the code of com.sangeng.controller.UserController is as follows:
// @Controller + @ResponseBody = @RestController
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/user/{id}")
    public User findById(@PathVariable Integer id){
        User user = userService.findById(id);
        return user;
    }
}
  • The @ Controller annotation is used on the web layer class to instantiate beans and set this class as a bean managed by spring MVC

  • Annotate @ ResponseBody to convert the return value into Json format and put it in the response body.

    • @Controller + @ResponseBody = @RestController
  • The @ RequestMapping annotation is added to set the request path

  • The @ Autowired annotation is used on the field to inject according to type dependency in order to obtain this object from the Spring container

  • The @ PathVariable annotation is the parameter to obtain the request path

  • Finally, we configure the tomcat plug-in in pom.xml

    <!--structure-->
    <build>
        <!--Setting plug-ins-->
        <plugins>
            <plugin>
                <!--Specific plug-in configuration-->
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.1</version>
                <!--configure port-->
                <configuration>
                    <port>80</port>
                    <!--Virtual path-->
                    <path>/</path>
                    <!--solve get Request Chinese garbled code-->
                    <uriEncoding>utf-8</uriEncoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

Access test:

Of course, instead of configuring the tomcat plug-in, we can integrate tomcat into the IDEA and start it

2. Case

2.1 uniform response format

We should ensure that the data format returned by all interfaces in a project is unified. In this way, it is more convenient for both front-end and mobile development to conduct unified processing after obtaining our data. We are here to unify all data formats into json format.

Therefore, we define the following result encapsulation class ResponseResult. Since the format is uniform and public, we can create a common package under com.sangeng and create the result encapsulation class ResponseResult under the package

  • @The JsonInclude(JsonInclude.Include.NON_NULL) annotation indicates that if the value of a property is not NULL, it will be converted to Json format
// With this annotation, if the value of a property is not NULL, it will be converted to Json format
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseResult<T> {
    /**
     * Status code
     */
    private Integer code;
    /**
     * Prompt information. If there is an error, the front end can get this field to prompt
     */
    private String msg;
    /**
     * The query result data (the query types of different interfaces are different, so we can set it as generic)
     */
    private T data;

    // Parametric construction of three parameters (query operation needs to return query data)
    public ResponseResult(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    // Parametric construction of two parameters (status code and prompt information)
    public ResponseResult(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    // Parametric construction of two parameters (status code and data)
    public ResponseResult(Integer code, T data) {
        this.code = code;
        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;
    }

    public T getData() {
        return data;
    }

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


}

Therefore, we encapsulate the query data returned by the previous controller query id of 1, and the modification code is as follows:

  • The return type is the ResponseResult type of the result set we encapsulated
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/user/{id}")
    public ResponseResult findById(@PathVariable("id") Integer id){
        User user = userService.findById(id);
        if(user==null){
            //Description: there is no corresponding user
            return new ResponseResult(500,"There is no such user");
        }
        return new ResponseResult(200,"Operation succeeded",user);
    }
}

Access test:

  • tomcat plug-in startup presentation:

  • IDEA integrated tomcat presentation:

2.2. Query all users

  • Call the method in the Service at the Controller layer
@RestController
public class UserController {
    @Autowired
    private UserService userService;

    // Query all users
    @GetMapping("/user")
    public ResponseResult findAll(){
        List<User> list = userService.findAll();
        return new ResponseResult(200,"Operation succeeded",list);
    }

}
  • The Service interface is as follows
public interface UserService {
    // Query user by id
    User findById(Integer id);
    // Query all users
    List<User> findAll();
}
  • Method of calling dao in Service implementation class
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
	//Omit other irrelevant codes

    public List<User> findAll() {
        return userDao.findAll();
    }
}
  • dao layer interfaces are as follows:
public interface UserDao {

    // Query all users
    List<User> findAll();
}
  • The dao layer uses the plug-in to generate the mapper.xml file as follows
<?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.sangeng.dao.UserDao">
    <select id="findAll" resultType="com.sangeng.domain.User">
        select * from user
    </select>
</mapper>

tomcat plug-in startup presentation:

IDEA integrated tomcat presentation:

2.3 paging query user

In addition to the user data found, the result of paging query also includes the current number of pages, the number of entries per page and the total number of records.

Therefore, we create a new page encapsulation class PageResult under the common package. The code is as follows:

public class PageResult<T> {
	// Current number of pages
    private Integer currentPage;
	// Number of entries per page
    private Integer pageSize;
	// Total records
    private Integer total;
    // Paging data
    private List<T> data;

    public PageResult(Integer currentPage, Integer pageSize, Integer total, List<T> data) {
        this.currentPage = currentPage;
        this.pageSize = pageSize;
        this.total = total;
        this.data = data;
    }

    public Integer getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(Integer currentPage) {
        this.currentPage = currentPage;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public Integer getTotal() {
        return total;
    }

    public void setTotal(Integer total) {
        this.total = total;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }
}
  • Write the Controller class and call the methods of the Service layer
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/user/{pageSize}/{pageNum}")
    public ResponseResult findByPage(@PathVariable("pageSize") Integer pageSize,@PathVariable("pageNum") Integer pageNum){
        
        PageResult pageResult =  userService.findByPage(pageSize,pageNum);
        return new ResponseResult(200,"Operation succeeded",pageResult);
    }

}
  • Write a Service implementation class and call the methods of Dao layer
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;


    public PageResult findByPage(Integer pageSize, Integer pageNum) {
        PageHelper.startPage(pageNum,pageSize);
        List<User> list = userDao.findAll();
        PageInfo pageInfo = new PageInfo(list);
        PageResult pageResult = new PageResult(pageInfo.getPageNum(),pageInfo.getPageSize(), (int) pageInfo.getTotal(),list);
        return pageResult;
    }
}

2.4. Insert user

① Write the Controller layer and call the service layer method

  • We pass data in Json format into the request body, and the @ RequestBody annotation can obtain the data in the request body
// Insert Post request
@PostMapping("/user")
public ResponseResult insertUser(@RequestBody User user){
    userService.insertUser(user);

    return new ResponseResult(200,"Operation succeeded");
}

Second, write the Service layer and call the dao method in the service implementation class.

  • Add method definition in Service interface
void insertUser(User user);
  • Implement the method in the implementation class:
public void insertUser(User user) {
    userDao.insertUser(user);
}

③ Write the Dao layer and use the plug-in to generate the mapper.xml mapping file

  • Define methods in interfaces
void insertUser(User user);
  • In the mapper mapping file
<insert id="insertUser">
    <!--id Is self increasing,We incoming null that will do-->
    insert into user values(null,#{username},#{age},#{address})
</insert>

④ Test: we pass Json data into the request body

{"username":"Sangeng thatched cottage","age":15,"address":"Excuse me?"}

We encapsulate the Json data of the incoming request body into a User object and demonstrate it in PostMan software, because the browser is only convenient to demonstrate GET requests

2.5. Delete user

① Write the Controller layer and call the service layer method

//Delete user by id
//delete request
@DeleteMapping("/user/{id}")
public ResponseResult deleteUser(@PathVariable("id") Integer id){
    userService.deleteUser(id);
    return new ResponseResult(200,"Operation succeeded");
}

Second, write the Service layer and call the dao method in the service implementation class.

  • Add method definition in Service interface
void deleteUser(Integer id);
  • Implement the method in the implementation class:
public void deleteUser(Integer id) {
    userDao.deleteUser(id);
}

③ Write the Dao layer and use the plug-in to generate the mapper.xml mapping file

  • Define methods in interfaces
void deleteUser(Integer id);
  • In the mapper mapping file
<delete id="deleteUser">
    delete from user where id = #{id}
</delete>

Perform a demonstration in PostMan and delete the user with id 3

2.6. Update users

① Write the Controller layer and call the service layer method

// Update user
// put request for update operation
@PutMapping("/user")
public ResponseResult updateUser(@RequestBody User user){
    userService.updateUser(user);
    return new ResponseResult(200,"Operation succeeded");
}

Second, write the Service layer and call the dao method in the service implementation class.

  • Add method definition in Service interface
void updateUser(User user);
  • Implement the method in the implementation class:
public void updateUser(User user) {
    userDao.updateUser(user);
}

③ Write the Dao layer and use the plug-in to generate the mapper.xml mapping file

  • Define methods in interfaces
    void updateUser(User user);
  • In the mapper mapping file
<update id="updateUser">
    update user set username = #{username},age = #{age},address = #{address} where id = #{id}
</update>

3. Unified exception handling

We can use @ ControllerAdvice to handle exceptions uniformly. This allows you to return a JSON response when an exception occurs.

We create a package exception under com.sangeng to store our unified exception handling class SGControllerAdvice

The code is as follows:

  • @The ControllerAdvice annotation sets the current class as the exception handler class
  • @The ExceptionHandler annotation setting specifies how exceptions are handled
  • @The ResponseBody annotation is to put the returned Json data into the response body
@ControllerAdvice
public class SGControllerAdvice {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseResult handleException(Exception e){
        return new ResponseResult(500,e.getMessage());
    }
}

We manually create errors in the method of finding users in the Controller layer

@GetMapping("/user")
public ResponseResult findAll(){
    System.out.println(1/0);//Manual manufacturing error
    List<User> list = userService.findAll();
    return new ResponseResult(200,"Operation succeeded!",list);
}

4. Interceptor

Create a package interceotor under com.sangeng, and create a new interceptor SGHandlerInterceptor class in the package

Create interceptor class

public class SGHandlerInterceptor implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}
  • Configure interceptors in Spring-MVC.xml
    <!--Configuring Interceptors -->
        <mvc:interceptors>

            <mvc:interceptor>
                <!--
                -->
                <mvc:mapping path="/**"/>
                <!--Configure paths to exclude interception-->
                <!--<mvc:exclude-mapping path="/"/>-->
                <!--Configure interceptor object injection container-->
                <bean class="com.sangeng.interceptor.SGHandlerInterceptor"></bean>
            </mvc:interceptor>
        </mvc:interceptors>

test

preHandle, postHandle and afterCompletion are also output on the IDEA console

5. Declarative transaction

① Write the Controller layer and call the service layer method

// Test declarative transactions
@RequestMapping("/user/test")
public ResponseResult test(){
    userService.test();
    return new ResponseResult(200,"Operation succeeded");
}

② Write Service layer

  • Add method definition in Service interface
// Test declarative transactions
void test();
  • Implement the method in the implementation class
    • The corresponding configuration has been made. Just annotate the service method
// Test declarative transactions
@Override
@Transactional
public void test() {
    userDao.insertUser(new User(null,"test1",11,"cc"));
    System.out.println(1/0);		//Manual manufacturing error
    userDao.insertUser(new User(null,"test2",12,"cc2"));
}

③ Testing

Inserting the user failed because there was an error and the transaction will be rolled back.

6.AOP

Note that when you use AOP for enhancement, you should enhance the Service. The Controller cannot be enhanced because the aspect class will be put into the parent container, and our Controller is in the child container. The parent container cannot access the child container, and the child container can access the parent container

The code of com.sangeng.aspect.SGAspect is as follows:

@Aspect
@Component
public class SGAspect {

    //Define tangent point
    @Pointcut("execution(* com.sangeng.service..*.*(..))")
    public void pt(){

    }

    //Enhance
    @Before("pt()")
    public void before(){
        System.out.println("before");
    }
}

The startup test found that the AOP enhancement was successful

  • If you need to enhance the Controller, use the interceptor
  • If you need to enhance the Service, use AOP to implement it yourself

Posted by pmiller624 on Mon, 20 Sep 2021 18:46:09 -0700