SSM framework: SSM integration case

Integrated thinking

Step 1: build an integrated environment
Step 2: build a Spring development environment
Step 3: integrate Spring MVC with Spring
Step 4: integrate Mybatis with Spring
We first configure each framework to ensure that each framework can be executed separately, and then carry out the integration operation.

Integrated environment construction

Step 1: create database and table structure
create database db_ssm;
use db_ssm;
create table account(
    id int primary key auto_increment,
    name varchar(20),
    money double
);
Step 2: create Maven web project and import coordinates
<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.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <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-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>
  <!-- springmvc -->
  <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>
  <!-- servlet jsp -->
  <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>
  <!-- mybatis -->
  <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>
  <!-- Database driven -->
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>${mysql.version}</version>
  </dependency>
  <!-- Database connection pool -->
  <dependency>
    <groupId>c3p0</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.1.2</version>
    <type>jar</type>
    <scope>compile</scope>
  </dependency>
  <!-- junit unit testing  -->
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>compile</scope>
  </dependency>
  <!-- log4j -->
  <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>
</dependencies>
Step 3: create the package structure of the project
  • org.ldh.bean
  • org.ldh.dao
  • org.ldh.service
  • org.ldh.controller
  • org.ldh.test
Step 4: write entity classes
public class Account implements Serializable {
    private Integer id;
    private String name;
    private Double money;
    //set and get methods and toString methods
}
Step 5: write the persistent layer interface of the account
public interface AccountDao {
    //preservation
    void saveAccount(Account account);
    //delete
    void deleteAccount(Integer id);
    //modify
    void updateAccount(Account account);
    //Query one
    Account queryAccountById(Integer id);
    //Query all
    List<Account> queryAllAccount();
}
Step 6: write the business layer code of the account

Business layer interface of account

public interface AccountService {
    //preservation
    void saveAccount(Account account);
    //delete
    void deleteAccount(Integer id);
    //modify
    void updateAccount(Account account);
    //Query one
    Account queryAccountById(Integer id);
    //Query all
    List<Account> queryAllAccount();
    //test method
    void test();
}

Business layer implementation class of account

public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;

    @Override
    public void saveAccount(Account account) {
        accountDao.saveAccount(account);
    }

    @Override
    public void deleteAccount(Integer id) {
        accountDao.deleteAccount(id);
    }

    @Override
    public void updateAccount(Account account) {
        accountDao.updateAccount(account);
    }

    @Override
    public Account queryAccountById(Integer id) {
        Account account = accountDao.queryAccountById(id);
        return account;
    }

    @Override
    public List<Account> queryAllAccount() {
        List<Account> accounts = accountDao.queryAllAccount();
        return accounts;
    }
    
    @Override
    public void test() {
        System.out.println("Business layer.....");
    }
}

Build and test the development environment of Spring

Step 1: write ApplicationContext xml
<?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">
    <!-- Enable annotation scanning, only scanning dao and service Annotation of layer -->
    <context:component-scan base-package="org.ldh">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
</beans>
Step 2: import log4j configuration file

log4j.properties

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
log4j.rootCategory=info, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
Step 3: use annotation configuration on the service implementation class
@Service
public class AccountServiceImpl implements AccountService {
    ....
}
Step 4: write a test class
public class TestSpring {
    @Test
    public void test() {
        //1. Load the spring configuration file and create the container object
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2. Get the bean object according to the id
        AccountService accountService = ac.getBean(AccountService.class);
        System.out.println(accountService);
        //3. Implementation method
        accountService.test();
    }
}

Test results:

Build the development environment of spring MVC

Step 1: on the web XML writing front-end controller
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <!-- Configure a filter to solve Chinese garbled code -->
  <filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <!-- Specify character set -->
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <!-- Write front-end controller -->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- Initialize the initialization parameter loading of the front-end controller springmvc.xml initialization spring of ioc container -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!-- Load the when the server starts servlet -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>
Step 2: create spring MVC xml
<?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">
    <!-- Enable annotation scanning, only scanning controller Layer package -->
    <context:component-scan base-package="org.ldh.controller"/>
    
    <!-- Configure view parser -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    
    <!-- Filter static resources -->
    <mvc:resources mapping="/static/**" location="/static/"/>
    
    <!-- open springmvc Support for annotations(Configure processor mapper and processor adapter) -->
    <mvc:annotation-driven/>
</beans>
Step 3: test whether the framework of spring MVC is built successfully

Write index jsp

<a href="account/test">test</a>

Write controller code

@Controller
@RequestMapping("/account")
public class AccountController {

    @RequestMapping("/test")
    public String test() {
        System.out.println("Presentation layer.....");
        return "success";
    }
}

Write success jsp

<h3>Successfully built!</h3>

Console output:

Spring integrates spring MVC

Our goal is to successfully call the methods in the service object in the controller.
Idea: use dependency injection to inject the service object into the controller. When the project starts, load the spring configuration file, so that the service object will be created and stored in the container. Then we can inject the service object into the controller and call the service method for complete integration.

Step 1: configure the ContextLoaderListener listener

By default, the listener only loads ApplicationContext under the WEB ‐ INF directory XML configuration file, so manual configuration is required
On the web Configuration in XML

<!-- to configure spring integration springmvc Monitor for -->
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- set up spring Location of the configuration file -->
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:applicationContext.xml</param-value>
</context-param>
Step 2: inject the service object into the controller and call the method of the service object
@Controller
@RequestMapping("/account")
public class AccountController {

    @Autowired
    private AccountService accountService;

    @RequestMapping("/test")
    public String test(){
        accountService.test();
        System.out.println("Presentation layer.....");
        return "success";
   }
}

Test results:

Build Mybatis development environment

Step 1: write database properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/db_ssm?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
Step 2: write mybatis XML configuration file
<?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>
    <!-- Import external profile -->
    <properties resource="database.properties"/>
    <!-- Configure entity class alias -->
    <typeAliases>
        <package name="org.ldh.bean"/>
    </typeAliases>
    <!-- to configure mysql environment -->
    <environments default="mysql">
         <environment id="mysql">
             <transactionManager type="JDBC"/>
             <dataSource type="POOLED">
                 <property name="driver" value="${jdbc.driver}"/>
                 <property name="url" value="${jdbc.url}"/>
                 <property name="username" value="${jdbc.username}"/>
                 <property name="password" value="${jdbc.password}"/>
             </dataSource>
         </environment>
    </environments>
    <!-- Specifies the location of the annotation dao Fully qualified class name of the interface -->
    <mappers>
        <mapper class="org.ldh.dao.AccountDao"/>
    </mappers>
</configuration>
Step 3: use annotations in dao interface
public interface AccountDao {
    //preservation
    @Insert("insert into account(name,money) values(#{name},#{money})")
    void saveAccount(Account account);
    //delete
    @Delete("delete from account where id = #{id}")
    void deleteAccount(Integer id);
    //modify
    @Update("update account set name=#{name},money=#{money} where id=#{id}")
    void updateAccount(Account account);
    //Query one
    @Select("select * from account where id=#{id}")
    Account queryAccountById(Integer id);
    //Query all
    @Select("select * from account")
    List<Account> queryAllAccount();
}
Step 4: test whether mybatis is built successfully
public class TestMybatis {
    public static void main(String[] args) throws Exception {
        //1. Load configuration file
        InputStream in = Resources.class.getResourceAsStream("/mybatis.xml");
        //2. Create SqlSessionFactory factory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3. Create SqlSession object using factory
        SqlSession session = factory.openSession(true);
        //4. Use SqlSession to create the proxy object of dao interface
        AccountDao accountDao = session.getMapper(AccountDao.class);
        //5. Implementation method
        List<Account> accounts = accountDao.queryAllAccount();
        for(Account account : accounts) {
            System.out.println(account);
        }
        //6. Release resources
        session.close();
        in.close();
    }
}

Test results:

Spring integrates Mybatis

Objective: to put mybatis Configure the content in the XML configuration file to ApplicationContext In XML
Idea: if the generated proxy dao objects can also be stored in the ioc container, then we can inject the proxy dao of the persistence layer into the service, and then we can call the dao methods in the service for complete integration.

Step 1: configure the contents of mybatis in the spring configuration file

applicationContext.xml

<!-- spring integration mybatis -->
<!-- Step 1: import external configuration file -->
<context:property-placeholder location="classpath:database.properties"/>
<!-- Step 2: configure database connection pool -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driver}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
<!-- Step 3: Configure SqlSessionFactory factory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
</bean>
<!-- Step 4: Configure dao Fully qualified class name of the interface -->
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="org.ldh.dao"/>
</bean>
Step 2: use annotation configuration in dao interface
@Repository("accountDao")
public interface AccountDao {
    ....
}
Step 3: inject dao object into the service implementation class
@Service("accountService")
public class AccountServiceImpl implements AccountService {

    @Autowired
    @Qualifier("accountDao")
    private AccountDao accountDao;
    ....
}
Step 4: configure spring's declarative transaction control

applicationContext.xml

<!-- to configure spring Declarative transaction control of framework -->
<!-- Step 1: configure the transaction manager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
<!-- Step 2: configure transaction notification and transaction attributes -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="query*" read-only="true"/>
        <tx:method name="*" isolation="DEFAULT" read-only="false"/>
    </tx:attributes>
</tx:advice>
<!-- Step 3: Configure aop -->
<aop:config>
    <!-- Configure pointcut expressions -->
    <aop:pointcut id="pt1" expression="execution(* org.ldh.service.impl.*.*(..))"/>
    <!-- Configure the association between transaction notifications and pointcut methods -->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
</aop:config>
Step 5: test whether the integration is successful

index.jsp

<a href="account/testQueryAllAccount">Query all</a>

AccountController controller

@RequestMapping("/testQueryAllAccount")
public String testQueryAllAccount() {
    List<Account> accounts = accountService.queryAllAccount();
    for(Account account : accounts) {
        System.out.println(account);
    }
    return "success";
}

Test results:

After the integration of SSM, the controller layer can call the service layer, and the service layer can call the dao layer. This SSM integration step is very important and needs to be familiar with it! In the future, we will write SSM projects based on this case.
The directory structure of the whole case is as follows:

Spring integrates spring MVC framework

We want to call the service method in the controller, so when we start the server, we need to load the object of the service layer into the ioc container of spring. How should we implement it? Let's recall the role of the ServletContext object. It can load some configuration files when the server starts, so we can Configure a listener in XML to listen to the creation of ServletContext object and load the configuration file of spring. In this way, when we start the server, we will load the spring configuration file and create the service layer object. Then we can inject the service object into the controller and call its methods to complete the integration.

Spring integrates Mybatis framework:

We want to make mybatis The content in the XML configuration file is configured into the spring configuration file, so how do we configure the configuration content of mybatis in the spring configuration file? The spring framework has been provided for us. We only need to use the corresponding tags in the spring configuration file to configure the configuration content of mybatis. In this way, when the service object is loaded, the configuration content of mybatis is also loaded successfully. Then we can inject dao object into the service and call its methods to complete the integration.

Tags: Java Mybatis Spring Spring MVC SSM

Posted by eyegraphix on Tue, 10 May 2022 12:13:18 +0300