Spring Framework Learning Notes - SSM Integration and Maven Custom Template Creation

Spring+Spring MVC+MyBatis+Maven

The core of SSM integration is Spring+MyBatis integration. Looking back on MyBatis operation database process, we use a SQL Session Factory object to get the SQL Session, and then CRUD operation.

Now, with spring, we load and manage the SQL Session Factory through spring.

If you want to use it directly, please go. SSM-Maven-Archetype

step

1. Create maven projects

2. Adding dependencies

<?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.wan</groupId>
    <artifactId>SSM-Template</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

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

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

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

        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.9.release</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.3.9.release</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.9.release</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.3.9.release</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.3.9.release</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>4.3.9.release</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.3.9.release</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.9.release</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.3.9.release</version>
        </dependency>
        <!--AOP-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.9.release</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>RELEASE</version>
        </dependency>
        <!-- springmvc Dependent json Library (if used@responsebody Annotation return json Data) -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>
        <!-- jstl 1.2.5 version libarary -->
        <dependency>
            <groupId>org.apache.taglibs</groupId>
            <artifactId>taglibs-standard-spec</artifactId>
            <version>1.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.taglibs</groupId>
            <artifactId>taglibs-standard-impl</artifactId>
            <version>1.2.5</version>
        </dependency>
        <!-- oracle driver -->
        <dependency>
            <groupId>com.github.noraui</groupId>
            <artifactId>ojdbc8</artifactId>
            <version>12.2.0.1</version>
        </dependency>
        <!-- mybatis orm frame -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!--Alibaba Connection Pool-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!-- spring integration mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.2</version>
        </dependency>
        <!--File upload-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!-- Log Library -->
        <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>
        <!-- apache libraries -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.5</version>
        </dependency>
        <!--MyBatis Paging plugins-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <!--Automatically download the latest version -->
            <version>5.1.6</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>SSM-Template</finalName>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.2.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

3. Integrating Spring MVC

The first three steps are mainly to integrate Spring + Spring MVC framework, you can refer to this article. Spring MVC Framework There's not much to add here.

4. Integrating Spring and MyBatis

In spring, MyBatis is perfectly integrated, so you can configure MyBatis configuration files without needing MyBatis configuration files, or MyBatis configuration files if you need them, and then you can import them.

The main processes are as follows:

  1. Create a db.properties to store the database url, account and password
  2. Create the bean object of DataSource (using connection pool, using db.properties above)
  3. Create the bean object of MyBatis's SqlSessionFactory (using the bean object of DataSourcebean above)
  4. Configure automatic loading mapper interface

Here's my spring configuration, using Alibaba's open source connection pool library and MyBatis's paging plug-in

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

    <!--
        1. scanning Service assembly, Mapper assembly
            @Service, @Repository
        2. Configuring data sources
        3. aggregate mybatis Some related configurations
        4. Database Transaction Manager
        5. AOP affair,That is to say AOP Method to cut database transactions to specified Service assembly
    -->

    <context:annotation-config />

    <!-- scanning dao Class ( service),You can have multiple packages separated by commas to complete Bean Functions for creating and automating dependency injection-->
    <!--<context:component-scan base-package="dao" />-->

    <!-- Reference to database resources in property files-->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations" value="classpath:db.properties"/>
    </bean>

    <!-- Declare a alibaba druid data source -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close">
        <!-- Basic attributes url,user,password -->
        <property name="url" value="${url}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
        <!-- <property name="driverClassName" value="${jdbc.driver}"></property> -->
        <!-- Configuration initialization size, minimum, maximum -->
        <property name="initialSize" value="1" />
        <property name="minIdle" value="1" />
        <property name="maxActive" value="20" />
        <!-- Configuration to get the connection waiting timeout time -->
        <property name="maxWait" value="60000" />
        <!-- How often is the configuration interval detected to detect idle connections that need to be closed in milliseconds? -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
        <!-- Configure the minimum lifetime of a connection in the pool in milliseconds -->
        <property name="minEvictableIdleTimeMillis" value="300000" />
        <property name="validationQuery" value="SELECT 'x' FROM DUAL" />
        <property name="testWhileIdle" value="true" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />
        <!-- open PSCache,And specify on each connection PSCache Size -->
        <property name="poolPreparedStatements" value="true" />
        <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
        <!-- Configuration Monitoring Statistical Interception filters -->
        <property name="filters" value="stat,log4j" />
    </bean>

    <!-- statement mybatis SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- If necessary, separate ones can be introduced. myBatis configuration file -->
        <!--<property name="configLocation" value="classpath:mybatis-config.xml"/>-->

        <!--You can configure it here SQL Mapping files, but they cannot be the same id Of parameterMap, resultMap or sql etc.-->
        <property name="mapperLocations" value="classpath*:mapper/*.xml" />

        <property name="typeAliasesPackage" value="model" />
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageInterceptor">
                    <property name="properties">
                        <!--Configure the parameters in the following way, one line at a time -->
                        <value>
                            <!-- Support for adoption Mapper Interface parameters to pass paging parameters
   helperDialect=oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby
                            -->
                            helperDialect=oracle
                            supportMethodsArguments=true
                            rowBoundsWithCount=true
                            offsetAsPageNum=true
                            pageSizeZero=false
                            reasonable=true
                        </value>
                    </property>
                </bean>
            </array>
        </property>

    </bean>

    <!-- Scan Mapper Files -->
    <!-- This method can also be scanned. Mapper Interface -->
    <!--<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="mapper" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>-->
    <!-- scan for mappers and let them be autowired -->
    <mybatis:scan base-package="dao" />

    <!--================Transaction-related control===================-->
    <bean name="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- AOP affair
     Service:
      newAccount(){
         DAO:
         1. from
         2. to
         3. log
       }

      <tx:method name="insert*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />

          propagation: Transaction Communication Behavior
          read-only: If it is a read-only transaction, it can only do inquiries, not to do. insert,update,delete operation
          rollback-for: When such an exception occurs, the transaction rolls back

      // Transactions must be opened
      UserService.insertUser(){

        // otherService.findX()
        otherService.insertXxx(); // c) Requires_New: New transaction
      }
     -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="insert*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
            <tx:method name="add*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
            <tx:method name="new*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
            <tx:method name="save*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
            <tx:method name="delete*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
            <tx:method name="update*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="select*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="query*" propagation="SUPPORTS" read-only="true"/>
        </tx:attributes>
    </tx:advice>

    <!--aop To configure-->
    <aop:config>

    </aop:config>

</beans>

5. Generating maven skeleton

Open the command line window in IDEA and enter the following commands (you have to configure maven's environment variables)

mvn archetype:create-from-project

build success means success.

PS: Solution to Keep Blank Folder

Several of the projects created above are blank folders, but after installing skeleton, when using skeleton to create maven project, we found that the blank folder was ignored and found two solutions on the internet.

  1. Place files in blank folders
  2. Modify configuration

Let's talk about the second method, which was found in Stack Overflow.

After executing mvn archetype:create-from-project, modify target/generated-sources/archetype/src/main/resources/META-INF/maven archetype-metadata.xml

<fileSet encoding="UTF-8">
  <directory>src/main/application/controller</directory>
</fileSet>

Here are my additions:

<fileSet filtered="true" encoding="UTF-8">
  <directory>src/main/java</directory>
  <includes>
    <include>**/*.java</include>
  </includes>
</fileSet>
<fileSet encoding="UTF-8">
  <directory>src/main/java/controller</directory>
</fileSet>
<fileSet encoding="UTF-8">
  <directory>src/main/java/dao</directory>
</fileSet>
<fileSet encoding="UTF-8">
  <directory>src/main/java/model</directory>
</fileSet>
<fileSet encoding="UTF-8">
  <directory>src/main/resources/mapper</directory>
</fileSet>
<fileSet encoding="UTF-8">
  <directory>src/main/webapp/css</directory>
</fileSet>
<fileSet encoding="UTF-8">
  <directory>src/main/webapp/img</directory>
</fileSet>
<fileSet encoding="UTF-8">
  <directory>src/main/webapp/js</directory>
</fileSet>
<fileSet encoding="UTF-8">
  <directory>src/main/webapp/view</directory>
</fileSet>

In addition, there are several files that need to be modified.
Spring and spring MVC configuration files under target generated-sources archetype src main resources archetype-resources src main resources

web.xml in target generated-sources archetype src main resources archetype-resources src main webapp

The xml version inside somehow changed to 1.0-SNAPSHOT, and we all changed to a fixed 1.0.

6. Install and add maven skeleton

Command line path to targetgenerated-sourcesarchetype

cd target\generated-sources\archetype

Enter Installation Command

mvn clean install

A build success indicates success

Open pom.xml in the target generated - sources archetype directory and remember the first three coordinate information below

Re-create a new maven project, then select to add an archetype and enter the coordinates

Then you can see that the list is made up of our custom skeleton.

7. Use maven skeleton

As before, select our custom skeleton and create a new maven project

Use precautions

Modify configuration

Make configuration changes according to your requirements

First is the configuration of the data source db.properties

spring-config.xml
72 rows mapper path (relative to resources directory)

105 rows of packages in the dao class,

<mybatis:scan base-package="dao" />

It automatically scans the package where Mapper is located and generates a bean (Dao object) with an id of xx, which can then be obtained from the spring container and used for CRUD operations.

Equivalent to the following code

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="dao" />
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>

Mybatis uses

In Mybatis, we can match the interface class with the mapper.xml file according to the convention, thus simplifying the CRUD operation.

In the project, I have the corresponding interface class and mapper.xml file

The namespace in UserMapper is dao.UserDao, where the namespace must correspond to the interface class UserDao

UserMapper.xml

<?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">
<!--
namespace: Namespaces, used to identify each Mapper XML Statements in a file, prevent them from being different Mapper XML The same statement exists in the file ID
-->
<mapper namespace="dao.UserDao">
    <!--
        resultType: Also known as automatic mapping, only the column names of tables and POJO When the attributes of the class are identical, it will be convenient to use the whole class name.
    -->
    <select id="select" resultType="model.Users">
        select * from USERS
    </select>
</mapper>

UserDao.java

package dao;

import java.util.List;

import model.Users;

/**
 * @author StarsOne
 * @date Create in  2019/10/11 0011 20:22
 * @description
 */
public interface UserDao {
    List<Users> select();
}

This is the way to use it.

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/spring-config.xml");
//spring automatically loads, the first letter lowercase, if EmployeeDao, then employeeDao
UserDao userMapper = (UserDao) context.getBean("userDao");
List<Users> users = userMapper.selectAll();
for (Users user : users) {
    System.out.println(user.toString());
}

Paging use

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/spring-config.xml");
AccountDao acountDao = (AccountDao) context.getBean("accountDao");
//Query the first page, each page has two data
PageHelper.startPage(1, 2);
List<Account> accounts = acountDao.selectAll();
for (Account account : accounts) {
    System.out.println(account.toString());
}

Tags: Java Spring Mybatis Maven xml

Posted on Fri, 11 Oct 2019 22:44:20 -0700 by NArc0t1c