0%

JavaWeb之SSM

JavaWeb学习中关于整合SSM的相关知识 💯💤

SSM整合

采用Spring整合MyBatis以及SpringMVC的方式,使用XML+注解的配置方式。

1. 准备工作

1. 创建数据库表

create database ssm;
use ssm;
create table account(
    id int primary key auto_increment,
    name varchar(20),
    money double
);

2. 创建maven工程并导入依赖

<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>
        <!-- servlet -->
        <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>
        <!-- el表达式 -->
        <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 -->

        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>
        <!-- Spring整合mybatis-->
        <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>

3. 编写实体类

public class Account implements Serializable {
    private Integer id;
    private String name;
    private Double money;
    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Double getMoney() {
        return money;
    }
    public void setMoney(Double money) {
        this.money = money;
    }
}

4. 持久层接口

因为使用了mybatis框架,dao中不需要提供实现类,会由mybatis生成代理对象去实现。

public interface AccountDao {
    /**
     * 查询所有账户
     *
     * @return
     */
    public List<Account> findAll();
    /**
     * 保存账户信息
     *
     * @param account
     */
    public void saveAccount(Account account);
}

5. 业务层接口及实现类

AccountService

public interface AccountService {
    /**
     * 查询所有账户
     *
     * @return
     */
    public List<Account> findAll();
    /**
     * 保存账户信息
     *
     * @param account
     */
    public void saveAccount(Account account);
}

AccountServiceImpl

public class AccountServiceImpl implements AccountService {
    @Override
    public List<Account> findAll() {
        System.out.println("业务层:查询所有账户...");
        return null;
    }
    @Override
    public void saveAccount(Account account) {
        System.out.println("业务层:保存账户信息...");
    }
}

2. Spring配置

1.创建配置文件

在resources目录下创建Spring的配置文件applicationContext.xml

由于表现层采用了SpringMVC的框架去实现,所以不需要在Spring中配置web层注解,需要忽略这一部分。

<?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">
    <!-- 开启注解扫描,要扫描的是service和dao层的注解,要忽略web层注解,因为web层让SpringMVC框架去管理 -->
    <context:component-scan base-package="cn.sucrelt">
        <!-- 配置要忽略的注解 -->
        <context:exclude-filter type="annotation"
                                expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
</beans>

2. 业务层实现类加入Spring容器中

AccountServiceImpl通过注解加入到Spring容器中

@Service("accountService")
public class AccountServiceImpl implements AccountService {
...
}

3. 测试

public class TestSpring {
    @Test
    public void run1() {
        //加载配置文件
        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        //获取对象
        AccountService accountService = (AccountService) ac.getBean("accountService");
        //调用方法
        accountService.findAll();
    }
}

测试结果:控制台显示执行了业务层的方法。

3. 整合SpringMVC

1. 目的

  1. 首先搭建SpringMVC框架,包括配置web.xmlspringmvc.xml文件,编写AccountController控制器类(也是web表现层)、以及响应的前端请求界面index.jsp和最后跳转界面list.jsp
  2. 整合的目的是使用controller控制器类作为web层,即能够在controller中调用service方法

2.分析

服务器启动之后,会加载配置文件web.xml,其中加载前端控制器从而加载springmvc的配置文件,但是spring的配置文件没能加载,所以需要在web.xml中使用配置监听器,用于加载spring的配置文件applicationContext.xml

3. 配置监听器

在项目启动的时候,就去加载applicationContext.xml的配置文件,在web.xml中配置ContextLoaderListener监听器(该监听器只能加载WEB-INF目录下的applicationContext.xml的配置文件),所以需要设置加载类路径下的文件。

当加载了spring的配置文件后,就会启动spring注解的扫描,在之后控制器中使用注解自动注入service对象便会生效。

<!-- 配置监听器,用于加载spring的配置文件applicationContext.xml -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>

4. 在控制器中调用service方法

在控制器中调用service方法,实现Spring和SpringMVC的整合,service方法进行自动注入。

@Controller
@RequestMapping("/account")
public class AccountController {
    @Autowired
    private AccountService accountService;

    @RequestMapping("/findAll")
    public String findAll() {
        System.out.println("表现层:查询所有账户信息...");
        accountService.findAll();
        return "list";
    }
}

5. 测试

通过index.jsp请求

    <body>
        <a href="account/findAll">测试Spring+SpringMVC</a>
    </body>

测试结果:请求到达web层,即SpringMVC框架中的前端控制器,执行表现层方法,其中调用了accountService.findAll(),便进入Spring框架中的业务层,执行业务层方法。控制台输出为:

表现层:查询所有账户信息...
业务层:查询所有账户...

4. 配置MyBatis

个中细节参考MyBatis的文档。

1. 编写MyBatis配置文件

<?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>
    <!-- 配置环境 -->
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/ssm?characterEncoding=UTF-8&amp;serverTimezone=GMT"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 引入映射的配置文件,使用的是注解,引入对应dao类 -->
    <mappers>
        <!--该包下的所有dao接口都可用-->
        <package name="cn.sucrelt.dao"/>
    </mappers>
</configuration>

2. 注解配置dao类

public interface AccountDao {

    @Select("select * from account")
    public List<Account> findAll();

    @Insert("insert into account (name, money) values (#{name}, #{money})")
    public void saveAccount(Account account);
}

5. 整合MyBatis

1. 分析

service使用Spring框架实现,service的类存入到Spring的IOC容器中,由于MyBatis使用代理对象实现dao功能,整合的目的就是要让代理对象也加入到Spring容器中,从而被service对象调用

2. 配置applicationContext.xml

把SqlMapConfig.xml配置文件中的内容配置到applicationContext.xml配置文件中,除了环境和映射的配置外,还要配置SqlSession的工厂,从而将代理对象加入到Spring容器中。

原有的SqlMapConfig.xml可以删除。

 <!-- 整合Mybatis -->
    <!-- 配置连接池对象 -->
    <bean id="dataSource"
          class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/ssm?characterEncoding=UTF-8&amp;serverTimezone=GMT"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>
    <!-- 配置SqlSession的工厂 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 配置扫描dao的包 -->
    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.sucrelt.dao"/>
    </bean>

3. 修改service和dao

  1. dao类上加上@Repository注解

    @Repository
    public interface AccountDao {
    
        @Select("select * from account")
        public List<Account> findAll();
    
        @Insert("insert into account (name, money) values (#{name}, #{money})")
        public void saveAccount(Account account);
    }
    
  2. service实现类中自动注入dao类并调用其中方法

    @Service("accountService")
    public class AccountServiceImpl implements AccountService {
        @Autowired
        private AccountDao accountDao;
        @Override
        public List<Account> findAll() {
            System.out.println("业务层:查询所有账户...");
            return accountDao.findAll();
        }
        @Override
        public void saveAccount(Account account) {
            System.out.println("业务层:保存账户信息...");
            accountDao.saveAccount(account);
        }
    }
    

4.测试

修改控制器和前端代码进行测试

控制器:

@Controller
@RequestMapping("/account")
public class AccountController {
    @Autowired
    private AccountService accountService;
    
    @RequestMapping("/findAll")
    public String findAll(Model model) {
        System.out.println("表现层:查询所有账户信息...");
        List<Account> list = accountService.findAll();
        for (Account account : list) {
            System.out.println(account);
        }
        model.addAttribute("list", list);
        return "list";
    }
}

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <a href="account/findAll">测试Spring+SpringMVC</a>
    </body>
</html>

list.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <h3>显示查询的所有用户</h3>>
        ${list}
    </body>
</html>

5. 添加事务管理

整合MyBatis的事务管理同样也配置在applicationContext.xml中。

  <!--配置事务通知-->
    <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>

    <!--配置AOP增强-->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.sucrelt.service.impl.*ServiceImpl.*(..))"/>
    </aop:config>

6. 整合流程分析

  1. 前端界面发送请求到控制器;
  2. 控制器使用SpringMVC框架,整合到Spring框架中后,可以调用Spring中的service类并自动注入。
  3. 执行service实现类中的方法,其中调用了dao类的方法并自动注入。
  4. dao类采用MyBatis的配置,配置项放在Spring的配置文件中,实现整合。
-------------------本文结束 感谢您的阅读-------------------

本文标题:JavaWeb之SSM

文章作者:Sucre

发布时间:2020年12月05日 - 18:14:17

最后更新:2020年12月05日 - 18:16:11

原始链接:https://tangtangsama.github.io/article/dca918a2.html/

非商业性使用-转载请保留原文链接及作者。

感谢您的支持和鼓励!