introduce

SSM

What is meant by SSM? Spring + Spring MVC + Mybatis is a popular synchronous blocking backend framework built on servlets. This framework is generally required in Spring back-end projects. With the release of Spring Boot, various frameworks can be directly integrated, including three frameworks in SSM. Therefore, manual CONSTRUCTION of SSM is more used for learning.

process

If you don’t want to see, directly visit the complete code: github.com/Littleor/SS…

If you want to do a good job, you must first sharpen it. Here we use IDEA to build, using Gradle 7.1 to build, JDK16 to run.

Create a Gradle project

It is recommended for beginners to create from IDEA or gradle command line.

Select Gradle and check Java and Web.

Then wait for the initialization to complete.

Adding mandatory dependencies

Add the following dependencies to dependencies, noting that to avoid problems later, they contain all the dependencies in this article.

    implementation 'org. Springframework: spring - webmvc: 5.3.9'
    implementation 'org. Springframework: spring - beans: 5.3.9'
    implementation 'org. Springframework: spring - the context: 5.3.9'
    implementation 'org. Springframework: spring - the context - support: 5.3.9'
    implementation 'org. Springframework: spring - web: 5.3.9'
    implementation 'org. Springframework: spring - tx: 5.3.9'
    implementation 'org. Springframework: spring - JDBC: 5.3.9'
    implementation 'org. Springframework: spring - test: 5.3.9'
    implementation 'org. Mybatis: mybatis: 3.5.7'
    implementation 'mysql: mysql connector - Java: 8.0.25'
    implementation 'org. Mybatis: mybatis - spring: 2.0.6'
    implementation 'org. Mybatis: mybatis - spring: 2.0.6'
    implementation 'com. Alibaba: druid - spring - the boot - starter: 1.2.6'
    implementation 'org. Slf4j: slf4j - log4j12:1.7.32'
    implementation 'the log4j: log4j: 1.2.17'
    implementation 'com. Fasterxml. Jackson. Core: Jackson - databind: 2.12.4'
    implementation 'com. Fasterxml. Jackson. Core: Jackson - annotations: 2.12.4'
Copy the code

Then save the installation dependencies.

Added Mybatis Reverse Task

Mybatis reverse generates the corresponding entity class and Mapper from the library table structure in the database.

Jdbc_config.properties = jdbc_config.properties = jdbc_config.properties = jdbc_config.properties = jdbc_config.properties = jdbc_config.properties = jdbc_config.properties = jdbc_config.properties

jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://ip:3306/database? useUnicode=true&characterEncoding=UTF-8
jdbc.username=username
jdbc.password=password
package.model=org.mybatis.entity
package.mapper=org.mybatis.mapper
package.xml=mybatis/mapping
Copy the code

Replace it with your database address, account number, and password.

Create spring-mybatis. XML under Resources to configure mybatis:


      
<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-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
    <! -- Automatic scan -->
    <context:component-scan base-package="org.mybatis.mapper"/>
    <! -- Import configuration file -->
    <bean id="propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:jdbc_config.properties"/>
    </bean>

    <bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <! -- Initialize connection size -->
        <! -- <property name="initialSize" value="${initialSize}"></property>-->
        <! -- Maximum number of connection pools -->
        <! -- <property name="maxActive" value="${maxActive}"></property>-->
        <! -- Connection pool maximum free time -->
        <! -- <property name="maxIdle" value="${maxIdle}"></property> -->    <! -- Connection pool minimum idle -->
        <! -- <property name="minIdle" value="${minIdle}"></property>-->
        <! Get the maximum waiting time for connections -->
        <! -- <property name="maxWait" value="${maxWait}"></property>-->
    </bean>

    <! -- Spring and MyBatis integrate perfectly, no need for MyBatis configuration mapping file -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <! -- Automatically scan mapping.xml file -->
        <property name="mapperLocations" value="classpath:mybatis/mapping/*.xml"/>
    </bean>

    <! Spring will automatically find the class under the package name of the DAO interface.
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="org.mybatis.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>

    <! -- transaction Manager, use JtaTransactionManager for Global TX -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

</beans>
Copy the code

Create Generatorconfig.xml under Resources to configure the generator:


      
<! - the configuration file, a https://www.cnblogs.com/ygjlch/p/6471924.html-- >
<! DOCTYPEgeneratorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <! -- Context: environment ID for generating a set of objects: Mandatory, context ID for prompting defaultModelType when generating an error; Conditional: similar to hierarchical; 2. Flat: All content (primary key, BLOB) is generated in one object; 3, Hierarchical: Primary key generates an XXKey object (Key class), Blob etc generates an object separately, other simple attributes in an object (Record class) targetRuntime: 1, MyBatis3: the default value to generate content based on MyBatis3. X or higher, including XXXBySample; 2, MyBatis3Simple: similar to MyBatis3, but without generating XXXBySample; IntrospectedColumnImpl: Class fully qualified name used to extend MBG -->
    <context id="default" targetRuntime="MyBatis3Simple" defaultModelType="flat">
        <! -- Generated POJO, implements Serializable -->
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
        <commentGenerator>
            <! -- Comment generator (false on default true off) -->
            <property name="suppressAllComments" value="true"/>
            <! -- Comment generator time display (false on default true off) -->
            <property name="suppressDate" value="true"/>
            <! Java file encoding format -->
            <property name="javaFileEncoding" value="utf-8"/>
            <! -- Formatting Java code -->
            <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
            <! -- Format XML code -->
            <property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>
        </commentGenerator>

        <! -- JDBC connection information -->
        <jdbcConnection driverClass="${driverClass}"
                        connectionURL="${connectionURL}"
                        userId="${userId}"
                        password="${password}">
            <property name="nullCatalogMeansCurrent" value="true"/>
        </jdbcConnection>
        <! Define Java type parser properties -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <! -- package name of entity class -->
        <javaModelGenerator targetPackage="${modelPackage}" targetProject="${src_main_java}">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <! Generate mapping file config XML package name -->
        <sqlMapGenerator targetPackage="${sqlMapperPackage}" targetProject="${src_main_resources}">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <! -- type= ANNOTATEDMAPPER means not to generate an XML file and I'm using XMLMAPPER -->
        <! Mapper -->
        <javaClientGenerator targetPackage="${mapperPackage}" targetProject="${src_main_java}" type="XMLMAPPER">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <! Table to be generated -->
        <! The percent sign represents all tables in the database.
        <table tableName="%">
            <generatedKey column="id" sqlStatement="Mysql" identity="true"/>
        </table>
    </context>
</generatorConfiguration>

Copy the code

This configuration is done, now configure the task in build.gradle and add the following code at the end:

configurations {
    mybatisGenerator
}
dependencies {
    // mybatis-generator mybatis reverse
    mybatisGenerator 'org. Mybatis. The generator: mybatis generator - core: 1.4.0'
    mybatisGenerator 'mysql: mysql connector - Java: 8.0.25'
    mybatisGenerator 'tk. Mybatis: mapper: 4.1.5'
}

def getDbProperties = {
    def properties = new Properties()
    file("src/main/resources/jdbc_config.properties").withInputStream { inputStream ->
        properties.load(inputStream)
    }
    properties
} as Object

task mybatisGenerator {
    def properties = getDbProperties()
    ant.properties['targetProject'] = projectDir.path
    ant.properties['driverClass'] = properties.getProperty("jdbc.driverClassName")
    ant.properties['connectionURL'] = properties.getProperty("jdbc.url")
    ant.properties['userId'] = properties.getProperty("jdbc.username")
    ant.properties['password'] = properties.getProperty("jdbc.password")
    ant.properties['src_main_java'] = sourceSets.main.java.srcDirs[0].path
    ant.properties['src_main_resources'] = sourceSets.main.resources.srcDirs[0].path
    ant.properties['modelPackage'] = properties.getProperty("package.model")
    ant.properties['mapperPackage'] = properties.getProperty("package.mapper")
    ant.properties['sqlMapperPackage'] = properties.getProperty("package.xml")
    ant.taskdef(
            name: 'mbgenerator'.classname: 'org.mybatis.generator.ant.GeneratorAntTask'.classpath: configurations.mybatisGenerator.asPath
    )
    ant.mbgenerator(overwrite: true.configfile: 'src/main/resources/generatorConfig.xml'.verbose: true) {
        propertyset {
            propertyref(name: 'targetProject')
            propertyref(name: 'userId')
            propertyref(name: 'driverClass')
            propertyref(name: 'connectionURL')
            propertyref(name: 'password')
            propertyref(name: 'src_main_java')
            propertyref(name: 'src_main_resources')
            propertyref(name: 'modelPackage')
            propertyref(name: 'mapperPackage')
            propertyref(name: 'sqlMapperPackage')}}}Copy the code

Create folders Mybatis/ Entity and Mybatis/Mapper under Resources and run mybatisGenerator.

I’m going to do it backwards.

The Spring configuration

To run our project in Tomcat, we now need to configure Spring, create applicationContext.xml under Resource, and configure the following:


      
<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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <! Spring automatically scans for Java files in the base package location. If it finds a class annotated with @Component, @Controller, @Service, @repository, etc., it registers that class as Bean.
    <context:component-scan base-package="org.controller"/>

    <! -- Enable SpringMVC annotation pattern -->
    <mvc:annotation-driven/>
    <! -- Static resource default servlet configuration -->
    <mvc:default-servlet-handler/>

    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>

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


</beans>

Copy the code

Configure the Web. XML of web-INF in the Web directory as follows:


      
<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">
    <! -- Encoding filter -->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <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>

    <! -- Web container start/stop listener -->
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

    <! -- Web container integrated with spring context listener -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <! -- Spring and Mybatis configuration files -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mybatis.xml</param-value>
    </context-param>

    <! Springmvc front-end controller: dispatcherServlet -->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <! Struts struts struts struts struts struts struts struts struts struts struts
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
Copy the code

At this point all spring-related configuration is complete.

Controller writing

To test this, add the package org.controller to the Java directory and create the UserController file

/ * * *@author Littleor <[email protected]>
 * @createTime 2021/8/20 17:32
 */
package org.controller;

import org.mybatis.entity.User;
import org.mybatis.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

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

@RestController
public class UserController {
    @Autowired
    private UserMapper userMapper;

    @RequestMapping(value = "/insert", produces = {"application/json; charset=UTF-8"})
    @ResponseBody
    public String insertUser(a) {
        User user = new User();
        user.setName("Xiao Ming");
        user.setPassword("44555");
        user.setCreateTime(new Date());
        userMapper.insert(user);
        return user.toString();
    }

    @RequestMapping(value = "/findAll", produces = {"application/json; charset=UTF-8"})
    public List<User> findAll(a) {
        returnuserMapper.selectAll(); }}Copy the code

Then you’re happy to start testing.

Tomcat configuration

First go to download and install Tomcat. The version I used here corresponds to Tomacat 9.x. By default, you have installed it, so you can configure it directly in IDEA:

Click Edit Configuration and create a Tomcat service:

Then configure the Tomcat related content: port and Tomcat path.

Then configure the deployed WAR package:

Configure the corresponding build, and then select the context to complete the configuration.

Now that all the configuration is complete, the pit is ready to begin.

Start Tomcat

Just select the configuration and click the Run button on the right. Isn’t that easy?

Wait for it to be built, then deploy to Tomcat, then accesshttp://localhost:8080/ssm/insertYou can insert the user.

At this point, a simple SSM framework setup is complete. Congratulations on completing all the configuration, but don’t be too excited about running it too soon when you may encounter the following problems.

Pit!!!!!!

Tomcat log problem

At runtime you may get an error like this:

log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader). log4j:WARN Please Initialize the log4j system properly. Log4j: WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.Copy the code

It is only a WARN, but it looks very uncomfortable. After installing the corresponding dependency (see dependency configuration at the beginning), add the log4j.properties file under Resources and configure:

log4j.rootLogger=WARN, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern=%5p [%t] (%F:%L) - %m%n
Copy the code

You can drop the WARN.

Mybatis Mapper repeats the problem

If you run without WARN, you may encounter ERROR:

Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [spring-mybatis.xml]: Invocation of init method failed; nested exception is org.springframework.core
Copy the code

Mybatis /mapping = mybatis/mapping = mybatis/mapping = mybatis/mapping = mybatis/mapping = mybatis/mapping = mybatis/mapping = mybatis/mapping

The metaphysics problem

And of course you’re more likely to encounter metaphysics:

java.lang.NoClassDefFoundError: javax/servlet/ServletRequestListener
Copy the code

This is usually a metaphysical/versioning problem. If there is no problem with the Tomcat version, restart it again.

MVC return object cannot be resolved as JSON problem

This is an optimization problem, usually we have back end return object, the framework will help us to parse it into JSON return, but Spring MVC needs to configure itself… (The above configuration has been configured for you!)

Install dependencies first:

    implementation 'com. Fasterxml. Jackson. Core: Jackson - databind: 2.12.4'
    implementation 'com. Fasterxml. Jackson. Core: Jackson - annotations: 2.12.4'
Copy the code

Then add the configuration to applicationContext.xml:

    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>
Copy the code

Afterword.

At this point, the SSM framework based on Gradle is completed. If you have any questions please refer to the full code on Github: original address