Construction of SSM (SPRING+SPRINGMVC+MYBATIS) Framework

Posted by leequalls on Fri, 19 Jul 2019 13:49:43 +0200

I. Introduction of SSM Framework Architecture and Process

SSM framework, usually refers to the integration of spring mvc+spring+mybatis three frameworks, spring mvc itself is part of spring, so there is no integration between the two. The main thing here is to integrate spring and mybatis framework, in fact, SqlSessionFactory object is handed over to spring. G is managed, and transactions are managed by spring.

 

1. SSM Architecture

SSM framework is mainly divided into bean/entity layer, mapper/dao layer, service layer and controller layer.

(1) The bean layer (also called entity/pojo/model layer) is used to store our entity classes, which is basically consistent with the attribute values in the database. Create concrete entity class objects in beans to facilitate other layers to directly manipulate entity class objects

(2) The dao layer (mapper layer) is encapsulated here for some tasks of contacting the database, specifically for the addition, deletion and modification of a table or entity.

(3) Service layer is mainly responsible for the logic application design of business module, which can be subdivided into service interface and service Impl implementation class.

(4) controller layer

Controller, imported into service layer, is responsible for the control of specific business module process, in which the interface of service layer is invoked to control business process.

 

2. SSM process

Call process: front-end JSP/html - > Controller - > Service - > Dao - > Database

The controller layer uses ajax+json to interact with the front-end html file to obtain the front-end request and return data to the front-end. The front-end page user requests to transfer the corresponding method to the controller layer through ajax, and then feedback the data to the html file. The processed data is displayed on the page and fed back to the user.

When the controller layer executes the corresponding method, it actually calls the corresponding interface of service layer, so that the service layer obtains the method in the implementation class to complete the corresponding business. The service layer generally uses transaction to carry out method operation to ensure the consistency of operation.

The service layer implementation class contains business implementation methods and some operations about database processing, but not directly dealing with the database. If the method of service layer needs to operate database, it needs to call the interface of dao layer.

The mybatis framework in the dao layer often uses the mapper dynamic proxy, so the dao layer interface will correspond to the corresponding sql statements in the mapper mapping file, thus realizing the operation of the database.

There is also the bean layer, which usually stores our entity classes, basically consistent with the attribute values in the database. Create concrete entity class objects in beans to facilitate other layers to operate entity class objects directly. Finally, in the dao layer, the operations of these entity class objects will be mapped directly to the corresponding sql statements, and the corresponding data in the database will be manipulated.

Conversely, when starting a project, the mapper.xml file will be parsed. There is a namespace in the XML pointing to dao. Using dynamic proxy and reflection technology, an implementation class of the Dao layer will be generated. Dao layer is used to operate database, return data, service calls Dao layer to obtain data, does some processing according to specific business, controller layer calls service layer, generally used to receive data from the front desk, and then transfers the data obtained from service layer to the front desk.

 

II. Construction of SSM Framework

1. Create a maven project in which new packages, such as bean s, controller s, service s, dao s, etc., are built.

2. Complete configuration files

(1) Adding dependencies, adding jar packages needed by the project in the project pom.xml file (mainly the jar packages involved in the three frameworks of spring MVC + Spring + mybatis)

<?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">
    <parent>
        <artifactId>learn</artifactId>
        <groupId>test</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>_11_ssm_crud</artifactId>
    <packaging>war</packaging>

    <name>_11_ssm_crud</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.0.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.0.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.4.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>

        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.10.0</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.caches</groupId>
            <artifactId>mybatis-ehcache</artifactId>
            <version>1.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.1</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.4</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.4</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.4</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-parameter-names</artifactId>
            <version>2.9.4</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jdk8</artifactId>
            <version>2.9.4</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.9.4</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.46</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>_11_ssm_crud</finalName>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

(2) Configuration of spring-mvc

Add spring-mvc.xml file under a. resouce folder to complete the configuration file of spring-mvc. In spring-mvc.xml, it completes the configuration of registered component scanner, view parser, internal view parser, static resources, and resolves the problem of returning json data scrambling.

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


    <!--Resolve Return json Data scrambling problem-->
    <bean id="stringHttpMessageConverter"
          class="org.springframework.http.converter.StringHttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/plain;charset=UTF-8</value>
                <value>application/json;charset=UTF-8</value>
            </list>
        </property>
    </bean>
    <mvc:annotation-driven>
        <mvc:message-converters>
            <ref bean="stringHttpMessageConverter" />
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!--Static resources-->
    <mvc:resources mapping="/images/**" location="/images/" />
    <mvc:resources mapping="/js/**" location="/js/" />
    <mvc:resources mapping="/css/**" location="/css/" />
    <mvc:resources mapping="/html/**" location="/html/" />

    <!-- Register component scanner, component scanner only scans controller Pack, don't scan service Wait for other packages, or the transaction configuration will fail-->
    <context:component-scan base-package="test.controller"/>

    <!-- view resolver -->
    <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>

    <!--Internal view parser-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/html/"/>
        <property name="suffix" value=".html"/>
    </bean>

</beans>

b. Complete WEB-INF/web.xml configuration

Complete the configuration of specified spring configuration file path, registered spring listener, registered character set filter and registered spring mvc central controller.

<?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_3_1.xsd"
         version="3.1">
    <!--Appoint spring Location of configuration files-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-*.xml</param-value>
    </context-param>

    <!--Registered listener-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!--To configure spring MVC Configuration Items-->
    <!--Character Coding Filter-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

        <!--Specified character encoding-->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>

        <!--Forces the specified character encoding, that is, if request If a character encoding is specified, the current character encoding is also mandatory.-->
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- register spring MVC The central controller -->
    <servlet>
        <servlet-name>springMVC</servlet-name>
        <!-- spring MVC Core controller in -->
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

(3) Configuration of mybatis

Add the database configuration file db.properties

#drive
jdbc.driver=com.mysql.jdbc.Driver  
#Database Connection Address
jdbc.url=jdbc:mysql://127.0.0.1:3306/ssm?useSSL=false
#User name and database password, which need to be changed here, each database password is different
jdbc.user=root
jdbc.password=mysql

 

b. Add the database log configuration file log4j.properties

log4j.rootLogger=debug,console
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern= [%-5p][%d{yyyy-MM-dd HH:mm:ss}]%m%n

 

c. Add the database cache configuration file ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">

    <diskStore path="java.io.tmpdir"/>

    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </defaultCache>
</ehcache>

 

d. Add mybatis.xml configuration file

The mapper mapping file is registered to scan with spring's Mapr Scanner Configurer scanner, SqlSession Factory is managed by spring, and data source is managed by spring, so no configuration is needed.

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

    <typeAliases>
        <package name="test.bean"/>
    </typeAliases>

</configuration>

Add spring-mybatis.xml configuration file

Load the data source, submit the sqlsessionfactory to spring management, and use MapperScanner Configurer to generate the Mapper interface into proxy objects. It is important to note that there is no need to scan the classes under the controller package when registering component scanners because they have been scanned in the springmvc configuration file.

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

    <!-- Loading configuration files -->
    <context:property-placeholder location="classpath:db.properties"/>

    <!-- Registered Component Scanner -->
    <context:component-scan base-package="test">
        <!--No Scanning controller annotation-->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"
    </context:component-scan>

    <!-- Database connection pool -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.user}" />
        <property name="password" value="${jdbc.password}" />
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="maxActive" value="10" />
        <property name="minIdle" value="5" />
    </bean>

    <!-- Give Way spring Administration sqlsessionfactory Use mybatis and spring In the Integration Package -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- Database connection pool -->
        <property name="dataSource" ref="dataSource" />
        <!-- Load mybatis Global Profile -->
        <property name="configLocation" value="classpath:mybatis.xml" />
    </bean>

    <!-- Automatic scanning will Mapper Interface Generation Proxy Object -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--Mapper The path where the file is located-->
        <property name="basePackage" value="monmkey1024.dao" />
    </bean>


</beans>

(4) Configuration of spring

Adding spring-tx.xml file for transaction management and using AOP annotation for transaction management

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


    <!-- Transaction Manager -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- data source -->
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!--Open Annotation Transaction Driver-->
    <tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

 

3. Complete the interface and implementation class of each layer

(1) Create the corresponding database table t_user, including id (primary key), name, phone, address, birthday fields

(2) bean Layer, Create User Class - User Class Object

package test1.bean;

import org.springframework.format.annotation.DateTimeFormat;

import java.time.LocalDate;

public class User {
    private int id;
    private String name;
    private  String phone;
    private String address;
    @DateTimeFormat(pattern = "yyyy-mm-dd")
    private LocalDate birthday;

    public User() {
    }

    public User(String name, String phone, String address, LocalDate birthday) {
        this.name = name;
        this.phone = phone;
        this.address = address;
        this.birthday = birthday;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public LocalDate getBirthday() {
        return birthday;
    }

    public void setBirthday(LocalDate birthday) {
        this.birthday = birthday;
    }
}

 

(3) dao layer, create UserDao interface file and UserDao corresponding mapper file UserDao.xml

UserDao interface file

package test.dao;

import test.bean.User;

import java.util.List;

public interface UserDao {
    void addUser(User user);

    void updateUser(User user);

    List<User> selectUsers();

    User selectUserById(int id);

    void deleteUser(int id);
}

UserDao.xml (sql statements specifically for database operations are edited here)

<?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="test.dao.UserDao">

    <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

    <insert id="addUser">
        INSERT INTO t_user
        (name,phone,address,birthday)
        VALUES
        (#{name},#{phone},#{address},#{birthday});

        <selectKey resultType="int" keyProperty="id" order="AFTER">
            SELECT @@identity
        </selectKey>
    </insert>

    <delete id="deleteUser">
        DELETE FROM t_user where id=#{id}
    </delete>

    <update id="updateUser">
        UPDATE t_user set name=#{name},phone=#{phone},address=#{address},birthday=#{birthday} where id=#{id}
    </update>

    <select id="selectUsers" resultType="user">
        SELECT id,name,phone,address,birthday FROM t_user
    </select>

    <select id="selectUserById" resultType="user">
        SELECT id,name,phone,address,birthday FROM t_user where id=#{id}
    </select>

</mapper>

(4) service layer: Create UserService interface and implementation class

UserService interface

package test.service;

import test.bean.User;

import java.util.List;

public interface UserService {
    void addUser(User user);

    void updateUser(User user);

    List<User> selectUsers();

    User selectUserById(int id);

    void deleteUser(int id);
}

UserServiceImpl implementation class ()

package test.service.impl;

import test.bean.User;
import test.dao.UserDao;
import test.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service  //For annotating Service implementation classes, Spring automatically creates objects for UserService Impl, and through annotations, the container finds an instance of UserService type, userService, to inject it, or @Component.

@Transactional  //Configuring transactions with annotations
public class UserServiceImpl implements UserService {


    @Autowired  //Auto-injection annotations, which default to type-by-type auto-assembly, are injected by the container looking for instances of UserDao type, initializing their objects, and then directly using methods in the object such as userDao.addUser(user), instead of creating objects with new.
    private UserDao userDao;

    @Override
    public void addUser(User user) {
        userDao.addUser(user);


    }

    @Override
    public void updateUser(User user) {
        userDao.updateUser(user);

    }

    @Override
    public List<User> selectUsers() {
        return userDao.selectUsers();
    }

    @Override
    public User selectUserById(int id) {
        return userDao.selectUserById(id);
    }

    @Override
    public void deleteUser(int id) {
        userDao.deleteUser(id);

    }
}

(5) Controller layer: Create controller classes, using restful style:

package test.controller;

import com.alibaba.fastjson.JSON;
import test.bean.User;
import test.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController  //Common Annotations for spring mvc in restful Style
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/users")  //This annotation is used to replace RequestMapping, which is characterized by @GetMapping only handles requests in get mode, and // annotations are followed by URL addresses.
    public String selectUsers(){

        List<User> users = userService.selectUsers();


        return JSON.toJSONString(users);
    }

    @GetMapping("/users/{id}")//The annotation is followed by a URL address that contains the required resources, such as the id here.
    public String selectUserById(@PathVariable int id) {

        User user = userService.selectUserById(id);

        return JSON.toJSONString(user);
    }

    @PostMapping("/users")
    public String addUser(@RequestBody User user) {


        try {
            userService.addUser(user);

            return JSON.toJSONString("success");
        } catch (Exception e) {
            e.printStackTrace();
            return JSON.toJSONString("fail");
        }

    }

    @PutMapping("/users/{id}")
    public String updateUser(@PathVariable int id, @RequestBody User user) {


        try {
            user.setId(id);
            userService.updateUser(user);

            return JSON.toJSONString("success");
        } catch (Exception e) {
            e.printStackTrace();
            return JSON.toJSONString("fail");
        }
    }

    @DeleteMapping("/users/{id}")
    public String deleteUser(@PathVariable int id) {

        try {
            userService.deleteUser(id);

            return JSON.toJSONString("success");
        } catch (Exception e) {
            e.printStackTrace();
            return JSON.toJSONString("fail");
        }
    }


}

 

4. Finally, create the required HTML front-end file under the webapp/html folder as needed.

Above is to build SSM framework combination to complete simple add, delete, modify and check functions, you can according to this idea to practice on your own.

 

The demo file will be attached later.

Reference material:

https://www.cnblogs.com/wmyskxz/p/8916365.html

Corresponding SSM Framework Introduction Tutorial

Topics: Programming Spring xml Mybatis Database