SSM整合之登录注册

     阅读:64

一、概述

        本文以一个登录注册的小功能作为示例,对SSM框架做一个整合

二、SSM整合

        SSM框架是指Spring、SpringMVC和Mybatis,SpringMVC是包含在Spring中的,因此SSM框架整合核心是将Mybatis整合到Spring中。

2.1 DAO

        1. 创建如下的数据库表格:

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) NOT NULL,
  `user_password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `create_time` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

        2. 创建对应表格的User类:

/**
 * 对应数据库user表格的User对象
 */
@Data
@AllArgsConstructor //生成一个包含所有参数的构造器
@NoArgsConstructor //生成一个没有参数的构造器
public class User {
    private int id;
    private String userName;
    private String userPassword;
    private Date createTime;
}

        3. 创建Mybatis配置文件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>

    <!--配置日志-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <typeAliases>
        <package name="com.wyf.dao"/>
    </typeAliases>

    <mappers>
        <package name="com.wyf.dao" />
    </mappers>

</configuration>

        mybatis-config.xml是Mybatis的主配置文件,一般若是单独使用Mybatis的话,应该在该配置文件中使用环境配置对数据库连接进行配置,但是,我们整合SSM框架,可以将数据库连接的相关配置交给Spring来做,甚至都可以不要mybatis-config.xml文件。

        4. 编写UserMapper接口

public interface UserMapper {
    /**
     * 新增用户
     *
     * @param sysUser
     * @return 返回影响行数
     */
    int insert(User sysUser);
    /**
     * 通过ID查询用户
     * @param id
     * @return
     */
    User selectById(int id);

    /**
     * 查询符合登录条件的用户数
     * @return
     */
    long selectUser(User sysUser);
}

        示例程序只有登录操作以及注册操作,因此此处为了简单,只提供了插入和查询功能。如果有其他需求,可以添加。

        5. 编写UserMapper接口对应的UserMapper.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.wyf.dao.UserMapper">
    <resultMap id="userMap" type="com.wyf.dao.User">
        <id property="id" column="id"/>
        <result property="userName" column="user_name"/>
        <result property="userPassword" column="user_password"/>
        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
    </resultMap>

    <!-- select查询 -->
    <select id="selectById" resultMap="userMap">
        select * from  `user` where id = #{id}
    </select>

    <!-- insert数据插入 -->
    <insert id="insert">
        insert into `user`(
            user_name, user_password, create_time)
        values(#{userName}, #{userPassword}, #{createTime, jdbcType=TIMESTAMP})
    </insert>

    <select id="selectUser" resultType="long">
        SELECT COUNT(*) from `user` WHERE user_name=#{userName} AND user_password=#{userPassword};
    </select>

</mapper>

        6. 编写spring-dao.xml文件,将Mybatis框架整合到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"
       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">

    <!-- spring整合Mybatis,使用c3p0数据库连接池 -->

    <!-- 配置整合mybatis -->
    <!-- 1. 关联数据库文件 -->
    <context:property-placeholder location="classpath:database.properties"/>
    <!-- C3P0数据库连接池 -->
    <!-- 配置数据源(C3P0) -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <!-- 属性注入 -->
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>

        <!-- C3P0其他属性设置 -->
        <!--连接池中保留的最小连接数。 -->
        <property name="minPoolSize" value="10" />
        <!--连接池中保留的最大连接数。Default: 15 -->
        <property name="maxPoolSize" value="30" />
        <!-- 关闭链接后不自动commit -->
        <property name="autoCommitOnClose" value="false"/>
        <!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
        <property name="maxIdleTime" value="1800" />
        <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
        <property name="acquireIncrement" value="3" />
        <property name="maxStatements" value="1000" />
        <property name="initialPoolSize" value="10" />
        <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
        <property name="idleConnectionTestPeriod" value="60" />
        <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
        <property name="acquireRetryAttempts" value="30" />
        <property name="breakAfterAcquireFailure" value="true" />
        <property name="testConnectionOnCheckout" value="false" />
    </bean>

    <!-- 3. 配置sqlSessionFactory对象 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 配置Mybatis的配置文件:mybatis-config.xml -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>

    <!-- SqlSessionTemplate:就是我们使用的sqlSession -->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!-- 只能使用构造器注入SqlSessionFactory,因为它没有set方法 -->
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>

    <!-- 注入UserMapperImpl数据操作类 -->
    <bean id="userMapper" class="com.wyf.dao.UserMapperImpl">
        <property name="sqlSession" ref="sqlSession"/>
    </bean>

</beans>

        我们在使用Mybatis框架的时候,必然要使用SqlSessionFactory以及SqlSession。Mybatis框架整合到Spring中,该对象由MyBatis-Spring使用 SqlSessionFactoryBean 来创建,该对象需要注入一个数据源datasource,本文使用的是c3p0数据源,如上所示。

        在Mybatis中,SqlSession相当于一个数据库连接,用以实现对数据库的各种操作,而Mybatis整合到Spring中,由MyBatis-Spring提供了SqlSessionTemplate代替SqlSession,如上文xml文件中的配置所示。上文中配置了一个新的UserMapper接口实现类UserMapperImpl,如下所示:

public class UserMapperImpl implements UserMapper{
    private SqlSessionTemplate sqlSession;
    public void setSqlSession(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }

    @Override
    public int insert(User sysUser) {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.insert(sysUser);
    }

    @Override
    public User selectById(int id) {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.selectById(id);
    }

    @Override
    public long selectUser(User sysUser) {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.selectUser(sysUser);
    }
}

        首先,该实现类注入了SqlSessionTemplate,用以执行接口定义的各项数据库操作,此实现类在单独使用Mybatis框架的时候是不需要的。此处在将Mybatis整合到Spring的过程中,就必须多创建一个UserMapperImpl类,用以执行具体的数据库操作,相比于原本的Mybatis框架,多创建的该类还是略显繁琐一些,还好,Spring提供了DAO包扫描,可以实现动态将DAO接口注入到Spring容器中,如下所示,但本文还是采用了上述的实现类的方式。

    <!-- 配置扫描dao包,动态实现Dao接口注入到spring容器中-->
    <!--解释 :https://www.cnblogs.com/jpfss/p/7799806.html-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 注入sqlSessionFactory -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!-- 给出需要扫描的Dao接口的包 -->
        <property name="basePackage" value="com.wyf.dao"/>
    </bean>

2.2 Service

        1. 编写接口

public interface UserService {
    /**
     * 新增用户
     *
     * @param sysUser
     * @return 返回影响行数
     */
    int insert(User sysUser);
    /**
     * 通过ID查询用户
     * @param id
     * @return
     */
    User selectById(int id);
    /**
     * 查询符合登录条件的用户数
     * @return
     */
    long selectUser(User sysUser);
}

        因为业务很简单,只是一个登录和注册,因此此处的Service功能也很简单,就是数据查询和数据插入。

        2. 编写业务实现类

public class UserServiceImpl implements UserService{
    private UserMapperImpl usermapper;
    public void setUsermapper(UserMapperImpl usermapper) {
        this.usermapper = usermapper;
    }

    @Override
    public int insert(User sysUser) {
        return usermapper.insert(sysUser);
    }

    @Override
    public User selectById(int id) {
        return usermapper.selectById(id);
    }

    @Override
    public long selectUser(User sysUser) {
        return usermapper.selectUser(sysUser);
    }

}

        可以看到,在此业务实现类中,注入了UserMapperImpl类,UserMapperImpl类属于DAO层,Service调用该对象实现对数据库的操作。

        3. 编写spring-service.xml文件,用以配置service层编写的类。

<?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"
       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">

    <!--Spring整合service层 -->
    <!-- 扫描service相关的bean -->
    <context:component-scan base-package="com.wyf.service"/>

    <!-- 将UserServiceImpl注入到IOC容器 -->
    <bean id="UserServiceImpl" class="com.wyf.service.UserServiceImpl">
        <property name="usermapper" ref="userMapper"/>
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dataSource" />
    </bean>

</beans>

2.3 SpringMVC

        1. 前端控制器 

        springmvc的核心是DispatcherServlet前端控制器,所有的请求都要经过DispatcherServlet然后通过适配器分发给合适的Controller去调用Service业务来进行处理,因此DispatcherServlet在Springmvc中有着举足轻重的低位,本质上,DispatcherServlet其实是一个Servlet,下面是在web.xml中配置DispatcherServlet:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--DispatcherServlet-->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationConfig.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!--encodingFilter-->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>
            org.springframework.web.filter.CharacterEncodingFilter
        </filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--Session过期时间-->
    <session-config>
        <session-timeout>15</session-timeout>
    </session-config>

</web-app>

         可以看到,上述的web.xml文件就配置了一个DispatcherServlet,这也就是springmvc的优势所在,所有的请求都给了这个servlet,由该servlet通过适配器找到合适的controller来调用相应的业务层代码去进行处理。这样代码清晰明了,配置也更加简洁方便。

        2. 编写Controller

@Controller
public class UserController {

    @Autowired
    @Qualifier("UserServiceImpl")
    private UserService userService;

    @GetMapping("/login")
    public String getLogin(Model model) {
        return "Login";
    }

    @PostMapping("/register")
    public String getRegister(Model model){
        return "Register";
    }

    @PostMapping("/registerUser")
    public String registerGetLogin(@RequestParam("name") String name,@RequestParam("pwd") String password, Model model){
        User user = new User();
        user.setUserName(name);
        user.setUserPassword(password);
        user.setCreateTime(new Date());
        int res = userService.insert(user);
        return "Login";
    }

    @PostMapping("/login")
    public String loginGetMain(@RequestParam("name") String name,@RequestParam("pwd") String password, Model model){
        User user = new User();
        user.setUserName(name);
        user.setUserPassword(password);
        long res = userService.selectUser(user);
        if(res>0){
            //登录成功
            model.addAttribute("message","登录成功!");
            return "Login";
        }else{
            model.addAttribute("message","用户名或密码错误,请重试!");
            return "Login";
        }
    }

}

        如上所示,所有的请求经过DispatcherServlet之后,在通过适配器找到合适的Controller去进行处理。上述请求使用了RestFul风格。

        3. spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 配置SpringMVC -->
    <!-- 1.开启SpringMVC注解驱动 -->
    <mvc:annotation-driven />
    <!-- 2.静态资源默认servlet配置-->
    <mvc:default-servlet-handler/>

    <!-- 3.配置jsp 显示ViewResolver视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
    <!-- 4.扫描web相关的bean -->
    <context:component-scan base-package="com.wyf.controller" />

</beans>

        至此,相关的代码以及配置文件编写完毕,回顾一下会发现,springmvc帮我们做了太多的事情,我们真正要写的就是Controller调用Service层的业务代码以及Service调用DAO层进行数据库操作的相关代码。可以直观的感受到springmvc是如何让我们更关注于业务逻辑本身。为了将上述几个Spring配置文件融合在一起,编写applicationConfig.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="spring-dao.xml"/>
    <import resource="spring-service.xml"/>
    <import resource="spring-mvc.xml"/>

</beans>

2.4 View

        表现层很简单,就两个页面,一个登录页面,一个注册页面。如下所示:

 登录页面

<%@ page isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <style>
        .h_title{position: relative;display: inline-block;}
        .box_div{
            width: 100%;
        }
        .box_main{
            position: absolute;
            top:50%;
            left: 50%;
            transform: translate(-50%,-50%);
            width: 60%;
            min-width: 700px;
            box-shadow: 0 0 30px #322f2f;
        }
        .box_main_right{
            width: 50%;
            height:450px;
            float: left;
            position: relative;
        }
        .box_form{
            position: absolute;
            top:50%;
            left: 50%;
            transform: translate(-50%,-50%);
        }
    </style>
    <title>Title</title>
</head>
<body style="text-align: center">

<div class="box_div">
    <div class="box_main">
        <div style="width:50%;height:450px;float: left;background: blueviolet">
            <br>
            <h2 class="h_title">智&nbsp;能&nbsp;仪&nbsp;表&nbsp;设&nbsp;备&nbsp;管&nbsp;理</h2>
        </div>
        <div class="box_main_right">
            <div class="box_form">
                <div style="width: 300px">
                    <h3 style="float: left">登&nbsp;&nbsp;录</h3>
                    <c:if test="${not empty message}">
                        <div style="width: 100%;height: 40px;clear: left;margin-bottom: 15px;background: rgba(252,158,158,0.3);border-radius: 5px">
                            <P style="font-size: 17px;color: #8a1717;line-height: 40px;">${message}</P>
                        </div>
                    </c:if>
                </div>
                <form action="login.do"  method="post" style="width: 300px;">
                    <input type="text" name="name" value="" placeholder="用户名" style="width: 100%;height: 40px;border-radius: 5px"><br><br>
                    <input type="password" name="pwd" value="" placeholder="密码" style="width: 100%;height: 40px;border-radius: 5px"><br><br>
                    <input type="submit"value="登&nbsp;&nbsp;录" name="login" style="width: 100%;height: 35px;background: orange;color: white;font-size: 17px;border-radius: 5px">
                </form>
                <form action="register" method="post" style="width: 300px">
                    <input type="submit" value="新用户注册" style="width: 100%;height: 35px;background: deepskyblue;color:white;font-size: 17px;border-radius: 5px">
                </form>
            </div>
        </div>
    </div>
</div>

</body>
</html>

 注册页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <style>
        .h_title{position: relative;display: inline-block;}
        .box_div{
            width: 100%;
        }
        .box_main{
            position: absolute;
            top:50%;
            left: 50%;
            transform: translate(-50%,-50%);
            width: 60%;
            min-width: 700px;
            box-shadow: 0 0 30px #322f2f;
        }
        .box_main_right{
            width: 50%;
            height:450px;
            float: left;
            position: relative;
        }
        .box_form{
            position: absolute;
            top:50%;
            left: 50%;
            transform: translate(-50%,-50%);
        }
    </style>
    <title>Title</title>
</head>
<body style="text-align: center">

<div class="box_div">
    <div class="box_main">
        <div style="width:50%;height:450px;float: left;background: blueviolet">
            <br>
            <h2 class="h_title">智&nbsp;能&nbsp;仪&nbsp;表&nbsp;设&nbsp;备&nbsp;管&nbsp;理</h2>
        </div>
        <div class="box_main_right">
            <div class="box_form">
                <div style="width: 300px">
                    <h3 style="float: left">注&nbsp;&nbsp;册</h3>
                </div>
                <form action="registerUser"  method="post" style="width: 300px;">
                    <input type="text" name="name" value="" placeholder="用户名" style="width: 100%;height: 40px;border-radius: 5px"><br><br>
                    <input type="password" name="pwd" value="" placeholder="密码" style="width: 100%;height: 40px;border-radius: 5px"><br><br>
                    <input type="submit"value="立即注册" name="login" style="width: 100%;height: 35px;background: orange;color: white;font-size: 17px;border-radius: 5px">
                </form>
                <form action="login" style="width: 300px">
                    <input type="submit" value="返回登录" style="width: 100%;height: 35px;background: deepskyblue;color:white;font-size: 17px;border-radius: 5px">
                </form>
            </div>
        </div>
    </div>
</div>

</body>
</html>

三、结束

        本文主要以一个登录注册的小案例介绍了SSM框架的整合,登录注册也可以看作是一般项目开发的起点,可以在其基础上进行其他内容的开发。

        SSM框架整合源代码:https://download.csdn.net/download/sssxlxwbwz/85090259