study hard and make progress every day

Text has been included to my lot DayDayUP:github.com/RobodLee/DayDayUP warehouse, welcome Star, more articles, please go to: directory navigation

In the field of Java backend development, the three frameworks of Spring+SpringMVC+MyBatis are especially frequently used. Many friends have learned these three frameworks but do not know how to integrate them. This article will take you step by step to realize the integration of the three frameworks. I am also a beginner, and the purpose of writing this article is on the one hand to save you from the detour, and on the other hand to deepen my understanding of these three frameworks. The idea of integration is to integrate SpringMVC and MyBatis framework with the Spring framework as the core. First we need to create a project and have the database ready for testing.

One. Preparation

How to create Maven project I believe you can, I will not repeat, do not know the friends please baidu. MySQL > create SSMTest; MySQL > create SSMTest; MySQL > create SSMTest;

create database ssmtest;
use ssmtest;
create table user(
id int primary key auto_increment,
name varchar(20),
age int
);
Copy the code

Then you need to prepare the required JAR packages and configuration files. I have pasted the contents of my entire POM file here for your reference.

<?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.playman</groupId>
  <artifactId>SSMTest</artifactId>
  <version>1.0 the SNAPSHOT</version>
  <packaging>war</packaging>

  <name>SSM 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.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <spring.version>5.0.2. RELEASE</spring.version>
    <slf4j.version>1.6.6</slf4j.version>
    <log4j.version>1.2.12</log4j.version>
    <mysql.version>5.1.6</mysql.version>
    <mybatis.version>3.4.5</mybatis.version>
  </properties>

  <dependencies>
    <! -- spring -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.6.8</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <! -- log start -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>${slf4j.version}</version>
    </dependency>
    <! -- log end -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>${mybatis.version}</version>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.0</version>
    </dependency>
    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
      <type>jar</type>
      <scope>compile</scope>
    </dependency>
  </dependencies>

  <build>
    <finalName>SSMTest</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>
        <! -- JDK plugin -->
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <configuration>
            <source>1.8</source>
            <target>1.8</target>
            <encoding>utf-8</encoding>
          </configuration>
        </plugin>
        <! -- tomcat plug-in - >
        <plugin>
          <groupId>org.apache.tomcat.maven</groupId>
          <! -- A plugin for Tomcat7, which varies between tomcat versions -->
          <artifactId>tomcat7-maven-plugin</artifactId>
          <version>2.1</version>
          <configuration>
            <! -- Using Maven Tomcat7 :run to access project port number -->
            <port>8080</port>
            <! In this example, localhost:9090. If aa is configured, the access path is localhost:9090/ AA.
            <path>/ssmtest</path>
            <! -- Solve the problem of Chinese garble -->
            <uriEncoding>UTF-8</uriEncoding>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>
Copy the code

You can now create some of the required directories and files:

OK! With the preparation finished, we can proceed to the next step.

two Setting up the Spring Framework

I used annotations to build the Spring framework this time. Because there is not much content involved this time, it is relatively simple to use annotations. Start by creating an applicationContext. XML file in the Resources directory as the Spring 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:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <! Turn on the scan of annotations -->
    <context:component-scan base-package="com.robod">
        <! Configure which annotations are not scanned -->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

</beans>
Copy the code

The methods in the UserService interface are then implemented and annotated in UserServiceImp.java.

@Service("userService")
public class UserServiceImpl implements UserService {

    @Override
    public List<User> findAll(a) {
        System.out.println("Now the findAll() method in UserService is called.");
        return null;
    }

    @Override
    public void save(List<User> users) {}}Copy the code

Now that we’re ready, we can test the Spring framework setup for problems. We used Junit for unit testing under the Test package,

public class TEST {

    @Test
    public void testSpring(a){
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = ac.getBean("userService",UserService.class); userService.findAll(); }}Copy the code

Let’s run it and see if we get anything

The result shows that there is no problem with the Spring framework construction. Now we can build the SpringMVC framework.

3. Build the SpringMVC framework

To configure the SpringMVC framework, we need to prepare the SpringMVC configuration file. In the Resources directory, we need to create a new SpringMVC. XML file with the following contents:

<?xml version="1.0" encoding="UTF-8"? >
<beans  xmlns="http://www.springframework.org/schema/beans"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <! -- 1. Enable annotation scanning and only scan Controller annotations -->
    <context:component-scan base-package="com.robod.controller">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <! -- enable support for SpringMVC annotations -->
    <mvc:annotation-driven/>
</beans>
Copy the code

Having the configuration file ready is not enough. The Tomcat server does not automatically load the springMVC.xml file at startup, so the next step is to get tomcat to load the configuration file at startup. Open the web-INF folder in the WebApp directory, which contains a web. XML file, and configure a front-end controller in it as follows:

  <! -- Configure front-end controller -->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <! Load SpringMVC. XML configuration file -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:SpringMVC.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup> <! Create the Servlet when starting the server -->
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
Copy the code

Now it’s time to configure the path by opening the userController.java file we created in the Controller directory

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/findAll")
    public void findAll(a) {
        System.out.println("FindAll () method in UserController executes"); }}Copy the code

Now visit http://localhost:8080/ssmtest/user/findAll path can perform the.findall () method, after the start tomcat in the browser and press enter after input the path, look at the console print:

OK, the method executes normally, indicating that our SpringMVC framework has been built successfully. Now we can integrate Spring and SpringMVC framework.

Four. Integration of Spring and SpringMVC frameworks

Finally, the integration of the two frameworks can begin. Without further ado, let’s begin! If we can successfully call the method in the controller into the service, then we have no problem with the integration of the framework. Before we used Spring alone, we manually loaded the Spring container, which is obviously not appropriate here. So we need to automatically load the Spring container as soon as Tomcat starts. What do we do? We need to configure the listener in web.xml to load at startup by adding the following:

  <! -- Spring with SpringMVC-->
  <! The applicationContext. XML file in the WEB-INF directory is loaded by default.
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <! -- Set the path to the configuration file -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
Copy the code

Now modify the UserController, add UserService to it, and call the method in UserService:

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    UserService userService;

    @RequestMapping("/findAll")
    public void findAll(a) {
        System.out.println("FindAll () method in UserController executes"); userService.findAll(); }}Copy the code

Now start the tomcat server, visit http://localhost:8080/ssmtest/user/findAll and see the results.

Obviously, the Spring framework and The SpringMVC framework have been successfully integrated, and we can now prepare the MyBatis framework.

Five. The Spring framework integrates the MyBatis framework

Originally, I planned to build MyBatis framework first and test whether there is any problem before integration. However, using MyBatis framework alone requires configuration file preparation, which is not needed during integration. Therefore, I skipped testing MyBatis framework alone and directly integrated it while building it. If you have used the MyBatis framework, you should know that we configure the dataSource and import the mapping configuration file, and then create the SqlSession to initialize the DAO instance. All of these can be configured into the Spring container, so that the Spring framework can integrate MyBatis framework. Add the following to the applicationContext.xml file:

    <! MyBatis framework -->
    <! -- Configure connection pool -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="JDBC: mysql: / / 127.0.0.1:3306 / ssmtest"/>
        <property name="user" value="root"/>
        <property name="password" value="123456"/>
    </bean>
    <! SqlSessionFactory = SqlSessionFactory
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <! Configure the package where the AccountDao interface resides.
    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.robod.dao"/>
</bean>
Copy the code

Now that we can load it into the Spring container, we annotate the UserDao, call the corresponding method in UseDao in the UserServiceImpl, and print the result in the UserController: UserDao:

@Repository("userDao")
public interface UserDao {

    @Select("select * from user")
    public List<User> findAll(a);

    @Update("insert into user(name , age) values (#{name},#{age})")
    public void save(User user);

}

Copy the code

UserController:

    @RequestMapping("/findAll")
    public void findAll(a) {
        System.out.println("FindAll () method in UserController executes");
        List<User> users = userService.findAll();
        for(User user : users) { System.out.println(user.toString()); }}Copy the code

At this time, there is no data in our database. Let’s add a few random data first, and then start the Tomcat server.

No problem, so far our three framework integration is complete!

Six. Spring declarative transaction management

One of the most powerful features in Spring is declarative transaction management, which we can’t forget. There are three steps to configuring Spring declarative transaction management. I have added a comment to the code and you can see for yourself. Add the following to applicationContext.xml:

    <! Spring Framework declarative transaction Management -->
    <! (1) Configure transaction manager -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <! -- (2) configure transaction notification -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*" isolation="DEFAULT"/>
        </tx:attributes>
    </tx:advice>
    <! Configure AOP enhancement -->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.playman.service.impl.*ServiceImpl.*(..) )"/>
    </aop:config>
Copy the code

OK, now we can test it. I wrote a save method in the previous section, which is not useful, but is ready to test declarative transaction management. Add a save method to UserController:

    @RequestMapping("/save")
    public void saveAccounts(a) {
        User user1 = new User();
        user1.setId(1);
        user1.setName("li");
        user1.setAge(20);
        User user2 = new User();
        user2.setId(2);
        user2.setName("j");
        user2.setAge(25);
        List<User> accounts = new ArrayList<>();
        accounts.add(user1);
        accounts.add(user2);
        userService.save(accounts);
    }
Copy the code

Then complete the UserServiceImpl save method:

@Override
public void save(List<User> users) {
    User user1 = users.get(0);
    User user2 = users.get(1);
    userDao.save(user1);
    userDao.save(user2);
}
Copy the code

We start tomcat, visit http://localhost:8080/ssmtest/user/save

Open the database and you can see that our save method is fine. Now in order to see if our declarative transaction management is working properly, we add an artificial exception and modify the UserServiceImpl save method:

    @Override
    public void save(List<User> users) {
        User user1 = users.get(0);
        User user2 = users.get(1);
        userDao.save(user1);
        int i = 1/0;    // If the transaction is not rolled back, then it should be ok to add a piece of data
        userDao.save(user2);
    }
Copy the code

To see the comparison, let’s delete the declarative transaction management configuration and delete the data we just added to the database. Run:

SQL > select * from db where transaction management has not been configured; SQL > select * from DB where transaction management has not been configured

As you can see, no data is added to the database, indicating that the rollback is true and our declarative transaction management configuration is successful. At this point, all operations are complete!