← 返回首页
SpringMVC教程(十五)
发表时间:2022-05-10 19:51:42
SSM框架整合

SSM框架整合,也就是我们常说的Spring+SpringMVC+MyBatis的整合。

在Spring5框架中,默认不支持Mybatis3进行直接的整合,需要依赖官方提供的插件mybatis-spring-xxx.jar

实例:

使用SSM框架实现一个用户登录和注册的小程序。

实现步骤: 1)项目整体结构图如下:

2)新建maven模块,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.2.5.RELEASE</spring.version>
        <servlet-version>4.0.1</servlet-version>
        <junit.version>4.12</junit.version>
        <lombok.version>1.18.12</lombok.version>
        <jackson-versoin>2.13.2</jackson-versoin>
        <mybatis.version>3.5.9</mybatis.version>
        <mysql.version>8.0.21</mysql.version>
        <druid.version>1.2.9</druid.version>
        <mybatis-spring.version>2.0.7</mybatis-spring.version>
    </properties>

    <dependencies>

        <!--添加mybatis的依赖-->
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>

        <!--添加MySQL的依赖-->
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>

        <!--druid数据库连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
        </dependency>

        <!--spring与mybatis整合用到的依赖很重要-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>${mybatis-spring.version}</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--必须添加事务相关的依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${servlet-version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>provided</scope>
        </dependency>

        <!--添加jackson依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson-versoin}</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson-versoin}</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>${jackson-versoin}</version>
        </dependency>
    </dependencies>

3).在resource目录下创建db.properties和mybatis-config.xml db.properties

mysql.dataSource=com.alibaba.druid.pool.DruidDataSource
mysql.driver=com.mysql.cj.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false&allowPublicKeyRetrieval=true
mysql.username=root
mysql.password=root

mybatis-config.xml

<?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>
    <!-- 配置映射类的别名 -->
    <typeAliases>
        <package name="com.entity"/>
    </typeAliases>
</configuration>

4)在com.entity包下创建Users实体类。

package com.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Users implements Serializable, Cloneable {

    private int uid;
    private String username;
    private String password;
    private String email; //电子邮箱
    private String gender; //性别
    private int education; //学历
    private String birthday; //生日
    private String[] favorites; //爱好;
    private String introduce; //自我介绍
    private String province; //籍贯
    private String accept; //是否接受协议

}

5).在com.dao包下创建UsersMapper.java

package com.dao;

import com.entity.Users;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

public interface UsersMapper {

    @Insert("insert into users (username,password,gender,email,birthday,education,introduce,province) values (#{username},#{password},#{gender},#{email},#{birthday},#{education},#{introduce},#{province})")
    @Options(useGeneratedKeys=true,keyProperty = "uid", keyColumn = "uid")
    public int reg(Users user);  //用户注册

    @Select("select * from users where username=#{uname} and password=#{upass}")
    public Users login(@Param("uname") String username, @Param("upass") String password);
}

6).在resource下创建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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 注册HandlerMapper、HandlerAdapter两个映射类 -->
    <mvc:annotation-driven />
    <!-- 访问静态资源 -->
    <mvc:default-servlet-handler/>

    <context:property-placeholder location="classpath:db.properties" />
    <!-- 使用扫描机制扫描控制器类,控制器类都在controller包及其子包下 -->
    <context:component-scan base-package="com"/>

    <!-- 配置数据源,注意里面所有的属性的名字都是固定的写法。 -->
    <bean id="dataSource" class="${mysql.dataSource}">
        <property name="Username" value="${mysql.username}"/>
        <property name="Password" value="${mysql.password}"/>
        <property name="DriverClassName" value="${mysql.driver}"/>
        <property name="Url" value="${mysql.url}"/>
    </bean>

    <!--配置sessionFactorybean -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml" />
    </bean>

    <!--注入usersMapper Bean-->
    <bean id="usersMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="com.dao.UsersMapper"/>
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/html/"/>
        <!--后缀-->
        <property name="suffix" value=".html"/>
    </bean>

    <!-- 事务管理器,依赖于数据源 -->
    <bean id="txManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- 注册事务管理驱动 -->
    <tx:annotation-driven transaction-manager="txManager"/>

</beans>

7).在com.service包下创建UsersService和在impl包下创建UsersServiceImpl UsersService.java

package com.service;

import com.entity.Users;

public interface UsersService {
    public boolean reg(Users user) throws Exception;
    public Users login(String username,String password);
}

UsersServiceImpl.java

package com.service.impl;

import com.dao.UsersMapper;
import com.entity.Users;
import com.service.UsersService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

@Service
public class UsersServiceImpl implements UsersService {

    @Resource
    private UsersMapper usersMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean reg(Users user) throws Exception {
        try {
            usersMapper.reg(user);
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            //手动回滚。
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }
    @Override
    public Users login(String username, String password) {
        return usersMapper.login(username, password);
    }
}

8).创建名字为mybatis的数据库,导入以下SQL脚本。


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users`  (
  `uid` int NOT NULL AUTO_INCREMENT,
  `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  `password` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  `gender` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  `education` int NULL DEFAULT NULL,
  `birthday` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  `introduce` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  `province` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  PRIMARY KEY (`uid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES (1, 'zhangsan', '123456', '男', 'zhangsan@qq.com', 1, '2001-10-10', '帅哥', '陕西');
INSERT INTO `users` VALUES (2, '宝宝', '654321', '女', 'baobao@126.com', 2, '2001-10-10', '美女', '陕西');
INSERT INTO `users` VALUES (5, '宋小宝', '123456', '男', 'simoniu77@gmail.com', 5, '2007-12-12', '夜黑', '河南');

SET FOREIGN_KEY_CHECKS = 1;

9).在WEB-INF/html/下创建login.html和reg.html视图页面。

login.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<h1>用户登录</h1>
<hr>
<div>
    <form id="regForm" action="#" method="post">
        <table>
            <tr>
                <td class="title">用户名:</td>
                <td><input type="text" id="username" name="username"/></td>
            </tr>
            <tr>
                <td class="title">密码:</td>
                <td><input type="password" id="password" name="password"/></td>
            </tr>

            <tr>
                <td colspan="2" style="text-align: center">
                    <button type="button" onclick="doLogin()">登录</button>
                </td>
            </tr>
        </table>
    </form>
</div>

<script>


    function doLogin() {
        let username = $("#username").val();
        let password = $("#password").val();

        console.log('执行用户登录,username='+username+",password="+password);

        //发送ajax请求

        $.ajax({
            url: 'http://localhost:8080/ssmdemo/users/auth?username='+username+'&password='+password,
            type: 'get',
            async: true,
            success: function (resp) {
                console.log(resp);
                if(resp.code===200){
                    console.log("登录成功用户:"+JSON.stringify(resp.data));
                    alert('登录成功!');
                }else{
                    alert("登录失败!");
                }
            }
        });
    }
</script>

</body>
</html>

reg.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<h1>用户注册</h1>
<hr>
<div>
    <form id="regForm" action="#" method="post">
        <table>
            <tr>
                <td class="title">用户名:</td>
                <td><input type="text" name="username"/></td>
            </tr>
            <tr>
                <td class="title">密码:</td>
                <td><input type="password" name="password"/></td>
            </tr>
            <tr>
                <td class="title">确认密码:</td>
                <td><input type="password" name="confirmpass"/></td>
            </tr>
            <tr>
                <td class="title">电子邮箱:</td>
                <td><input type="text" name="email"/></td>
            </tr>

            <tr>
                <td class="title">性别:</td>
                <td><input type="radio" value="男" name="gender" checked/>男<input type="radio" value="女" name="gender"/>女
                </td>
            </tr>
            <tr>
                <td class="title">学历:</td>
                <td>
                    <select name="education">
                        <option value="-1" selected>-----请选择-----</option>
                        <option value="0">文盲</option>
                        <option value="1">小学</option>
                        <option value="2">初中</option>
                        <option value="3">高中</option>
                        <option value="4">大专</option>
                        <option value="5">本科</option>
                        <option value="6">硕士</option>
                        <option value="7">博士</option>
                        <option value="8">博士后</option>
                        <option value="9">圣斗士</option>
                    </select>
                </td>
            </tr>
            <tr>
                <td class="title">籍贯:</td>
                <td>
                    <input list="province" name="province" value=""/>
                    <datalist id="province">
                        <option value="河北">
                        <option value="河南">
                        <option value="山东">
                        <option value="山西">
                        <option value="陕西">
                    </datalist>
                </td>
            </tr>
            <tr>
                <td class="title">出生日期:</td>
                <td><input type="date" name="birthday" value=""/></td>
            </tr>
            <tr>
                <td class="title">爱好:</td>
                <td>
                    <!--复选框name名字必须一样-->
                    <input type="checkbox" name="favorites" value="read"/>读书
                    <input type="checkbox" name="favorites" value="music"/>音乐
                    <input type="checkbox" name="favorites" value="internet"/>上网
                    <input type="checkbox" name="favorites" value="nba"/>NBA
                </td>
            </tr>
            <tr>
                <td class="title">自我介绍:</td>
                <td><textarea rows="10" cols="25" name="introduce"></textarea></td>
            </tr>
            <tr>
                <td class="title">上传照片:</td>
                <td><input type="file" name="pic"/></td>
            </tr>
            <tr>
                <td class="title">是否接受条款:</td>
                <td><input type="checkbox" name="accept"/>我无条件接受霸王条款</td>
            </tr>
            <tr>
                <td colspan="2" align="center">
                    <button type="button" onclick="doReg()">注册</button>
                    <input type="reset" value="重置"/></td>
            </tr>
        </table>
    </form>
</div>

<script>

    //jquery的表单转json的方法
    $.fn.parseForm = function () {
        var serializeObj = {};
        var array = this.serializeArray();
        var str = this.serialize();
        $(array).each(function () {
            if (serializeObj[this.name]) {
                if ($.isArray(serializeObj[this.name])) {
                    serializeObj[this.name].push(this.value);
                } else {
                    serializeObj[this.name] = [serializeObj[this.name], this.value];
                }
            } else {
                serializeObj[this.name] = this.value;
            }
        });
        return serializeObj;
    };

    function doReg() {

        var param = $("#regForm").parseForm();
        console.log(JSON.stringify(param));
        //发送ajax请求
        $.ajax({
            url: 'http://localhost:8080/ssmdemo/users/save',
            data: JSON.stringify(param),
            type: 'post',
            contentType: 'application/json', //注意这里必须添加contentType: 'application/json'
            async: false,
            success: function (resp) {
                console.log(resp);
                if(resp.code===200){
                    alert("注册成功!");
                }else{
                    alert("注册失败!");
                }
            }
        });
    }
</script>

</body>
</html>

10).在com.controller下创建UsersController.java

package com.controller;
/*
* 专门用来处理用户业务逻辑的控制器
* */

import com.entity.Users;
import com.service.UsersService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("users")  //表示这里所有的动作都是处理用户业务逻辑请求的。
public class UsersController {

    @Resource
    private UsersService usersService;

    //跳转到用户登录页面
    @GetMapping("login")
    public String login(){
        return "login";
    }

    //跳转到用户注册页面
    @GetMapping("reg")
    public String reg(){
        return "reg";
    }

    //保存用户资料
    @PostMapping(value="save")
    @ResponseBody
    public Map<String,Object> add(@RequestBody Users user){
        Map<String,Object> result = new HashMap<String,Object>();
        System.out.println("执行用户注册或者添加新用户....");
        System.out.println("注册用户资料:"+user);
        try{
            if(usersService.reg(user)){
                result.put("code", 200);
                result.put("msg", "注册成功!");
                return result;
            }
            result.put("code", 400);
            result.put("msg", "注册失败!");
            return result;
        }catch(Exception ex){
            ex.printStackTrace();
            result.put("code",400);
            result.put("msg","注册出现异常!");
            return result;
        }

    }

    //用户登录
    @RequestMapping("auth")
    @ResponseBody
    public Map<String,Object> auth(String username,String password){
        Map<String,Object> result = new HashMap<String,Object>();
        Users loginUser = null;
        try{
            loginUser= usersService.login(username,password);
            if(loginUser!=null) {
                result.put("code", 200);
                result.put("msg", "登录成功!");
                result.put("data",loginUser);
                return result;
            }
            result.put("code", 400);
            result.put("msg", "登录失败!");
            return result;
        }catch(Exception ex){
            ex.printStackTrace();
            result.put("code",400);
            result.put("msg","登录出现异常!");
            return result;
        }
    }
}

部署项目测试运行。

项目启动后访问 http://localhost:8080/ssmdemo/users/login,测试登录效果如下:

访问 http://localhost:8080/ssmdemo/users/reg,测试注册效果如下: