【环境搭建】SSM 整合使用
阅读原文时间:2023年07月09日阅读:4

SSM 整合使用

文章源码

整合说明

SSM 整合可以使用多种方式,但是选择 XML + 注解 的方式最为合适。

整合思路

  • 搭建整合环境
  • Spring 环境搭建并测试
  • Spring 整合 SpringMVC 并测试
  • Spring 整合 MyBatis 并测试

创建 Maven 工程

使用到工程的聚合和拆分的概念。

使用 IDEA 新建一个 Maven 工程,选择 maven-archetype-webapp

  • 在 项目 的 pom.xml 文件中引入坐标依赖

    <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.1.20.RELEASE</spring.version>
    <mybatis.version>3.5.6</mybatis.version>
    <mysql.version>5.1.48</mysql.version>
    <junit.version>4.12</junit.version>
    <jsckson.version>2.10.5</jsckson.version>
    </properties>
    
    <dependencies>
    
    <!-- Spring start-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</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-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-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.14</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>
    <!-- Spring end-->
    
    <!-- MyBatis 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.3</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
    </dependency>
    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.5.2</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.12</version>
    </dependency>
    <!-- MyBatis end-->
    
    <!-- Test end-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- Test end-->
    
    <!-- Common end-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${jsckson.version}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>${jsckson.version}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>${jsckson.version}</version>
    </dependency>
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.4</version>
    </dependency>
    <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-core</artifactId>
      <version>1.18.1</version>
    </dependency>
    <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-client</artifactId>
      <version>1.18.1</version>
    </dependency>
    <!-- Common end-->
    
    </dependencies>

选中项目,点击右键,选择 Add FrameWorks Support,添加上 SpringMVC 支持。会自动创建 src/main/webapp/WEB-INF/applicationContext.xmlsrc/main/webapp/WEB-INF/dispatcher-servlet.xml 文件,前者是 Spring 配置文件,后者是 SpringMVC 配置文件。

创建数据库和表结构

src/main/resources/ssm.sql

drop database if exists ssm;

create database ssm;
use ssm;

# ---

drop table if exists `user`;

create table `user`(
                       `id` int(11) primary key auto_increment,
                       `username` varchar(30) not null comment '用户名',
                       `password` varchar(30) not null comment '密码'
) engine=InnoDB default charset=utf8;

insert into user(username, password) VALUES
('admin', 'admin11002244'), ('parzulpan', '12345678');

# ----

编写实体类

src/main/java/cn/parzulpan/domain/User.java

package cn.parzulpan.domain;

import java.io.Serializable;

/**
 * @Author : parzulpan
 * @Time : 2020-12
 * @Desc : 用户实体类
 */

public class User implements Serializable {
    private Integer id;
    private String username;
    private String password;

    // getter setter toString
}

编写 dao 接口和实现类

src/main/java/cn/parzulpan/dao/UserDAO.java

/**
 * @Author : parzulpan
 * @Time : 2020-12
 * @Desc : 用户持久层接口
 */

public interface UserDAO {
    /**
     * 查询所有用户信息
     * @return
     */
    public List<User> findAll();

    /**
     * 根据 Id 查询用户信息
     * @param id
     * @return
     */
    public User findById(Integer id);

    /**
     * 根据 用户名 查询用户信息
     * @param username
     * @return
     */
    public User findByName(String username);

    /**
     * 保存用户
     * @param user
     */
    public void save(User user);
}

src/main/java/cn/parzulpan/dao/impl/UserDAOImpl.java

// 后面整合 MyBatis 后直接使用注解开发,这个文件将弃用删除

@Repository("userDAO")
public class UserDAOImpl implements UserDAO {
    @Override
    public List<User> findAll() {
        System.out.println("用户持久层:查询所有用户信息");
        return null;
    }

    @Override
    public User findById(Integer id) {
        System.out.println("用户持久层:根据 Id 查询用户信息");
        return null;
    }

    @Override
    public User findByName(String username) {
        System.out.println("用户持久层:根据 用户名 查询用户信息");
        return null;
    }

    @Override
    public void save(User user) {
        System.out.println("用户持久层:保存用户");

    }
}

编写 service 接口和实现类

src/main/java/cn/parzulpan/service/UserService.java

/**
 * @Author : parzulpan
 * @Time : 2020-12
 * @Desc : 用户业务层接口
 */

public interface UserService {

    /**
     * 查询所有用户信息
     * @return
     */
    public List<User> findAllUser();

    /**
     * 根据 Id 查询用户信息
     * @param id
     * @return
     */
    public User findUserById(Integer id);

    /**
     * 根据 用户名 查询用户信息
     * @param username
     * @return
     */
    public User findUserByName(String username);

    /**
     * 保存用户
     * @param user
     */
    public void saveUser(User user);
}

src/main/java/cn/parzulpan/service/impl/UserServiceImpl.java

/**
 * @Author : parzulpan
 * @Time : 2020-12
 * @Desc : 用户业务层接口的实现类
 */

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

    @Autowired
    private UserDAO userDAO;

    @Override
    public List<User> findAllUser() {
        System.out.println("用户业务层:查询所有用户信息");
        return userDAO.findAll();
    }

    @Override
    public User findUserById(Integer id) {
        System.out.println("用户业务层:根据 Id 查询用户信息");
        return userDAO.findById(id);
    }

    @Override
    public User findUserByName(String username) {
        System.out.println("用户业务层:根据 用户名 查询用户信息");
        return userDAO.findByName(username);
    }

    @Override
    public void saveUser(User user) {
        System.out.println("用户业务层:保存用户");
        userDAO.save(user);
    }
}

编写 Spring 配置文件

src/main/webapp/WEB-INF/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">

    <!-- Spring 配置 Start -->
    <!-- 开启注解扫描,只扫描 service 和 dao 层,忽略 web 层 -->
    <context:component-scan base-package="cn.parzulpan">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!-- Spring 配置 End -->

</beans>

测试 Spring 环境

src/test/java/cn/parzulpan/service/impl/UserServiceImplTest.java

/**
 * @Author : parzulpan
 * @Time : 2020-12
 * @Desc : 对 用户业务层接口的实现类 进行单元测试
 */

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/applicationContext.xml"})
public class UserServiceImplTest {

    @Autowired
    private UserService us;

    @Test
    public void findAllUser() {
        List<User> users = us.findAllUser();
    }

    @Test
    public void findUserById() {
        User user = us.findUserById(1);
    }

    @Test
    public void findUserByName() {
        User user = us.findUserByName("admin");
    }

    @Test
    public void saveUser() {
        us.saveUser(new User(null, "test", "test1234"));
    }
}
  • 在 web.xml 中配置 DispatcherServlet 前端控制器

  • 在 web.xml 中配置 DispatcherServlet 过滤器 解决中文乱码

  • 在 web.xml 中配置 ContextLoaderListener 监听器 为了在controller 中能成功的调用 service 对象中的方法

    <!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>
    &lt;!-- 配置Spring的监听器 Start --&gt;
    &lt;listener&gt;
        &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
    &lt;/listener&gt;
    &lt;!-- 通过监听器,读取 Spring 的配置文件 --&gt;
    &lt;context-param&gt;
        &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
        &lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;/param-value&gt;
    &lt;/context-param&gt;
    &lt;!-- 配置Spring的监听器 End --&gt;
    
    &lt;!-- 配置 app 分派器(前端控制器)Start --&gt;
    &lt;servlet&gt;
        &lt;servlet-name&gt;dispatcher&lt;/servlet-name&gt;
        &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
        &lt;!-- 配置初始化参数,读取 SpringMVC 的配置文件 --&gt;
        &lt;init-param&gt;
            &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
            &lt;param-value&gt;/WEB-INF/dispatcher-servlet.xml&lt;/param-value&gt;
        &lt;/init-param&gt;
        &lt;!-- 配置 Servlet 对象的创建时间点为应用加载时创建,取值只能为非零整数,表示启动顺序 --&gt;
        &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
    &lt;/servlet&gt;
    &lt;!-- 配置映射,同 Servlet 一样 --&gt;
    &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;dispatcher&lt;/servlet-name&gt;
        &lt;url-pattern&gt;/&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;
    &lt;!-- 配置 app 分派器(前端控制器)End --&gt;
    
    &lt;!-- 配置解决中文乱码的过滤器 Start --&gt;
    &lt;filter&gt;
        &lt;filter-name&gt;characterEncodingFilter&lt;/filter-name&gt;
        &lt;filter-class&gt;org.springframework.web.filter.CharacterEncodingFilter&lt;/filter-class&gt;
        &lt;!-- 设置过滤器中的属性值 --&gt;
        &lt;init-param&gt;
            &lt;param-name&gt;encoding&lt;/param-name&gt;
            &lt;param-value&gt;UTF-8&lt;/param-value&gt;
        &lt;/init-param&gt;
        &lt;init-param&gt;
            &lt;param-name&gt;forceRequestEncoding&lt;/param-name&gt;
            &lt;param-value&gt;true&lt;/param-value&gt;
        &lt;/init-param&gt;
        &lt;init-param&gt;
            &lt;param-name&gt;forceResponseEncoding&lt;/param-name&gt;
            &lt;param-value&gt;true&lt;/param-value&gt;
        &lt;/init-param&gt;
    &lt;/filter&gt;
    &lt;!-- 过滤所有请求 --&gt;
    &lt;filter-mapping&gt;
        &lt;filter-name&gt;characterEncodingFilter&lt;/filter-name&gt;
        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
    &lt;/filter-mapping&gt;
    &lt;!-- 配置解决中文乱码的过滤器 End --&gt;
    </web-app>

  • 在 dispatcher-servlet.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">
    &lt;!-- SpringMVC 配置 Start --&gt;
    
    &lt;!-- 开启注解扫描,只扫描 web 层 --&gt;
    &lt;context:component-scan base-package="cn.parzulpan"&gt;
        &lt;context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/&gt;
    &lt;/context:component-scan&gt;
    
    &lt;!-- 配置 视图解析器 --&gt;
    &lt;bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"&gt;
        &lt;property name="prefix" value="/WEB-INF/views/"/&gt;
        &lt;property name="suffix" value=".jsp"/&gt;
    &lt;/bean&gt;
    
    &lt;!-- 配置 文件解析器,要求 id 名称必须是 multipartResolver --&gt;
    &lt;bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"&gt;
        &lt;property name="maxUploadSize" value="10485760"/&gt;
    &lt;/bean&gt;
    
    &lt;!-- 配置 处理器拦截器 --&gt;
    
    &lt;!-- 设置静态资源不过滤 --&gt;
    &lt;mvc:resources mapping="/js/**" location="/js/"/&gt;
    &lt;mvc:resources mapping="/css/**" location="/css/"/&gt;
    &lt;mvc:resources mapping="/images/**" location="/images/"/&gt;
    
    &lt;!-- 开启对 SpringMVC 注解的支持 --&gt;
    &lt;mvc:annotation-driven/&gt;
    
    &lt;!-- SpringMVC 配置 End --&gt;
    </beans>
  • 删除 SqlConfigMap.xml,在 applicationContext.xml 中 配置 MyBatis

  • 在 applicationContext.xml 中 配置 Spring 声明式事务管理

    <?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">
    &lt;!-- Spring 配置 Start --&gt;
    &lt;!-- 开启注解扫描,只扫描 service 和 dao 层,忽略 web 层 --&gt;
    &lt;context:component-scan base-package="cn.parzulpan"&gt;
        &lt;context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/&gt;
    &lt;/context:component-scan&gt;
    
    &lt;!-- 配置 Spring 声明式事务管理 --&gt;
    &lt;!-- 1. 配置事务管理器 --&gt;
    &lt;bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;
        &lt;property name="dataSource" ref="dataSource"/&gt;
    &lt;/bean&gt;
    &lt;!-- 2. 配置事务的通知 --&gt;
    &lt;tx:advice id="txAdvice" transaction-manager="transactionManager"&gt;
        &lt;tx:attributes&gt;
            &lt;tx:method name="*" read-only="false" propagation="REQUIRED"/&gt;
            &lt;tx:method name="find*" read-only="true" propagation="SUPPORTS"/&gt;
        &lt;/tx:attributes&gt;
    &lt;/tx:advice&gt;
    &lt;!-- 3. 配置 AOP 增强 --&gt;
    &lt;aop:config&gt;
        &lt;aop:pointcut id="allServiceImplPT" expression="execution(* cn.parzulpan.service.impl.*.*(..))"/&gt;
        &lt;aop:advisor advice-ref="txAdvice" pointcut-ref="allServiceImplPT"/&gt;
    &lt;/aop:config&gt;
    
    &lt;!-- Spring 配置 End --&gt;
    
    &lt;!-- MyBatis 配置 Start --&gt;
    &lt;!-- 配置 C3P0 连接池对象 --&gt;
    &lt;bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"&gt;
        &lt;property name="driverClass" value="com.mysql.jdbc.Driver"/&gt;
        &lt;property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ssm?useSSL=false"/&gt;
        &lt;property name="user" value="root"/&gt;
        &lt;property name="password" value="root"/&gt;
    &lt;/bean&gt;
    &lt;!-- 配置SqlSession的工厂 --&gt;
    &lt;bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"&gt;
        &lt;property name="dataSource" ref="dataSource" /&gt;
    &lt;/bean&gt;
    &lt;!-- 配置映射信息 --&gt;
    &lt;bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"&gt;
        &lt;property name="basePackage" value="cn.parzulpan.dao"/&gt;
    &lt;/bean&gt;
    &lt;!-- MyBatis 配置 Start --&gt;
    </beans>
  • 以注解的方式编写 DAO,注意 @Param 的使用,当 SQL 中需要多个参数的时候,MayBatis 会将参数列表中的参数封装成一个 Map 进行传递,这个过程是通过 @Param 来实现的,@Param 注解括号中的值会作为 key,value 就是参数实际的值。解析参数的时候会按照 @Param 中定义的 key 获取对应的值

    /**
    * @Author : parzulpan
    * @Time : 2020-12
    * @Desc : 用户持久层接口
    */
    
    @Repository
    public interface UserDAO {
        /**
        * 查询所有用户信息
        * @return
        */
        @Select("select * from user")
        public List<User> findAll();
    /**
    * 根据 Id 查询用户信息
    * @param id
    * @return
    */
    @Select("select * from user where id = #{id}")
    public User findById(@Param("id") Integer id);
    
    /**
    * 根据 用户名 查询用户信息
    * @param username
    * @return
    */
    @Select("select * from user where username = #{username}")
    public User findByName(@Param("username") String username);
    
    /**
    * 根据用户名和密码查询用户信息
    * @param username
    * @param password
    * @return
    */
    @Select("select * from user where username = #{username} and password = #{password}")
    public User findByNameAndPwd(@Param("username") String username, @Param("password") String password);
    
    /**
    * 保存用户
    * @param user
    * @return
    */
    @Insert("insert into user(username, password) values (#{username}, #{password})")
    @SelectKey(keyColumn = "id", keyProperty = "id", resultType = Integer.class, before = false,
            statement = {"select last_insert_id()"})
    public int save(User user);
    }

src/main/java/cn/parzulpan/web/UserController.java

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    /**
     * 登录
     * @param user
     * @return
     */
    @RequestMapping("/login")
    public String login(User user){
        System.out.println("表现层:登录用户");
        System.out.println(user);

        User userByNameAndPwd = userService.findUserByNameAndPwd(user.getUsername(), user.getPassword());
        if (userByNameAndPwd != null) {
            System.out.println("登录成功");
            return "redirect:findAll";
        }

        return "error";
    }

    /**
     * 注册
     * @param user
     * @return
     */
    @RequestMapping("/registration")
    public String registration(User user){
        System.out.println("表现层:注册用户");
        System.out.println(user);

        int i = userService.saveUser(user);
        if (i > 0) {
            System.out.println("注册成功");
            return "redirect:findAll";
        }

        return "error";
    }

    /**
     * 查询所有账户
     * @param model
     * @return
     */
    @RequestMapping("/findAll")
    public String findAll(Model model) {
        System.out.println("表现层:查询所有账户");

        List<User> users = userService.findAllUser();
        model.addAttribute("users", users);

        return "success";
    }

    /**
     * 返回首页
     * @return
     */
    @RequestMapping("/returnIndex")
    public String returnIndex() {
        System.out.println("表现层:返回首页");

        return "redirect:/index.jsp";
    }
}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章