CanTechLab

Can

快速构建SSM项目

769
2024-05-26

1.开发环境配置

安装JDK8(Java Development Kit)

https://blog.csdn.net/m0_58503202/article/details/127161492

安装Maven3.6.3包管理工具(需要配置本地仓库和阿里云镜像仓库)

https://i.vycc.cn/article/1164454.html

阿里云镜像仓库配置

https://developer.aliyun.com/mvn/guide?spm=a2c6h.13651104.mirror-free-trial.5.43586e1alj2DQy

安装Tomcat9 Web容器

https://blog.csdn.net/qq_45344586/article/details/123943194

安装MySQL8数据库

https://blog.csdn.net/qq_55535816/article/details/120857636

IDEA IDE的安装与破解

IDEA下载地址:https://www.jetbrains.com/idea/download/

破解教程:见下方百度网盘链接

安装Navicat可视化数据库管理工具

安装文件:见下方百度网盘链接

破解教程:

软件下载链接:https://pan.baidu.com/s/1Hv_UqUqry6xT7yyTXmH3FQ 提取码:tkja

2.生成初始项目

使用Maven Archetype生成初始项目

这里需要注意选择的JDK版本和Archetype类型

组ID可以按照自己的喜好来 例如com.amy等 对实际的业务并没有影响 但后续有些代码需要自己注意修改

修改项目的Maven仓库配置

更改Maven仓库后刷新Maven项目

确认Web模板的Maven项目

其中pom.xml文件证明该项目是由Maven包管理工具进行管理(即该项目是Maven项目)

webapp文件夹证明该项目是一个Web项目

添加项目依赖坐标

<dependencies>
  <!--测试相关依赖-->
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
  </dependency>
  <!--Spring相关依赖-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.10.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.10.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.10.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.6</version>
  </dependency>
  <!--数据库相关依赖-->
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
  </dependency>
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.0</version>
  </dependency>
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
  </dependency>
  <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
  </dependency>
  <dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.2</version>
  </dependency>
  <!--springMVC相关依赖-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.10.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.12.4</version>
  </dependency>
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.4</version>
  </dependency>
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.12.4</version>
  </dependency>
  <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
  </dependency>
</dependencies>

按照MVC架构创建目录结构

3.整合SSM(Spring + SpringMVC + MyBatis)

编辑db.properties(配置数据库连接)

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/数据库名?zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
jdbc.username=你的数据库用户名
jdbc.password=你的数据库密码

注意区分MySQL8和MySQL5的不同配置

编辑log4j.properties(配置日志)

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

编辑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-4.3.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

    <!-- 1.配置数据库相关参数properties的属性:${url} -->
    <context:property-placeholder location="classpath:db.properties"/>

    <!-- 2.配置数据源 -->
    <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}"/>
        <property name="maxPoolSize" value="30"/>
        <property name="minPoolSize" value="2"/>
    </bean>

    <!-- 3.配置SqlSessionFactory对象 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 扫描bean包 使用别名  按情况自己修改-->
        <property name="typeAliasesPackage" value="com.can.domain"/>
        <!--配置加载映射文件-->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>

    <!-- 自动生成dao,mapper-->
    <!-- 4.配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 给出需要扫描Dao接口包  按情况自己修改-->
        <property name="basePackage" value="com.can.mapper"/>
        <!-- 注入sqlSessionFactory -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>
    <!--自动扫描-->
    <context:component-scan base-package="com.can"/>

    <!-- 配置事务-->
    <!-- 5.配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 6.开启事务注解-->
    <tx:annotation-driven />
</beans>

其中两处的value值需要根据你自己的包名进行相应修改 如果和我一样都是com.can则不需要修改

编辑spring-mvc.xml(SpringMVC相关配置)

<?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"
       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-4.3.xsd
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-4.3.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

    <!-- 加入注解解析-->
    <context:annotation-config />

    <!-- 1.注解扫描位置-->
    <context:component-scan base-package="com.can.controller">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <!-- 2.配置映射处理和适配器-->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

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

    <!-- 默认处理无法解决的http请求-->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
        </mvc:message-converters>
    </mvc:annotation-driven>

    <mvc:default-servlet-handler />

</beans>

编辑web.xml(总体web配置)

<!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>

  <!-- Spring和mybatis的配置文件 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

  <!-- 编码过滤器 -->
  <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>

  <!-- Spring监听器 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- 防止Spring内存溢出监听器 -->
  <listener>
    <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
  </listener>

  <!-- Spring MVC servlet -->
  <servlet>
    <servlet-name>SpringMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>/index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

4.编写示例

在domain文件下下创建User用户对象

package com.can.domain;

/**
 * @filename: User
 * @author: HXJ
 * @date: 2023/5/13 10:42 PM
 * @version: V1.0
 * @description: 用户实体类,与数据库字段相对应
 */
public class User {

    private int id;

    private String username;

    private String password;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

使用Navicat创建数据库和数据表

创建数据库

创建数据表

执行sql语句插入测试数据

insert into user(username,password) values('admin','admin')

在mapper文件夹下UserMapper接口文件中创建用户登录、注册、查询接口

package com.can.mapper;

import com.can.domain.User;
import org.apache.ibatis.annotations.Param;

/**
 * @filename: UserMapper
 * @author: HXJ
 * @date: 2023/5/13 10:49 PM
 * @version: V1.0
 * @description: 用户Mapper接口层,用于定义数据库CRUD语句接口
 */
public interface UserMapper {

    public User login(@Param("username") String username);

    public int register(@Param("username") String username,@Param("password") String password);

    public int findUserByUsername(@Param("username")String username);
}

在resource/mapper文件夹下UserMapper.xml中编写sql语句

<?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   命名空间,一般情况下一个mapper映射文件对应不同的命名空间,利于管理和维护
            书写:默认情况下可以随意输入,但是如果使用接口绑定的方式就必须要输入对应的接口的完整限定名
        namespace如果是基于statementId的方式去执行SQL就可以随便写
        如果是基于接口绑定的方式就需要输入相应接口的完整限定名-->
<mapper namespace="com.can.mapper.UserMapper">

    <insert id="register" parameterType="string" >
		insert into user(username,password) values(#{username},#{password})
    </insert>

    <select id="login" resultType="com.can.domain.User" parameterType="string">
		select username,password from user where username = #{username}
    </select>

    <select id="findUserByUsername" resultType="java.lang.Integer" parameterType="string">
		select count(1) from user where username = #{username}
    </select>

</mapper>

在service文件夹下UserService接口文件中创建用户登录、注册服务接口

package com.can.service;


/**
 * @filename: UserService
 * @author: HXJ
 * @date: 2023/5/13 10:49 PM
 * @version: V1.0
 * @description: 用户Service接口层,用于定义用户服务的通用接口
 */

public interface UserService {

    public int login(String username,String password);

    int register(String username, String password);
}

在service文件夹下impl文件夹下UserService类中调用UserMapper接口实现用户登录、注册业务代码

package com.can.service.impl;

import com.can.domain.User;
import com.can.mapper.UserMapper;
import com.can.service.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @filename: UserServiceImpl
 * @author: HXJ
 * @date: 2023/5/13 10:49 PM
 * @version: V1.0
 * @description: 用户Service实现层,该层完成了对接口层的实际业务实现
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    public int login(String username,String password) {
        //查询数据库中该用户名存储的密码
        User user = userMapper.login(username);
        //对比输入的账号密码和数据库中的账号密码
        if(username.equals(user.getUsername()) && password.equals(user.getPassword())){
            return 1;
        }else {
            return 0;
        }
    }
    public int register(String username, String password) {
        //判断是否存在同名用户
        int num = userMapper.findUserByUsername(username);
        if(num > 0){
            //num大于0证明已存在该用户,不允许注册
            return 0;
        }else {
            return userMapper.register(username,password);
        }
    }
}

在controller文件夹下UserController类中调用UserService接口实现用户登录、注册服务的调用

package com.can.controller;

import com.can.domain.User;
import com.can.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;

/**
 * @filename: UserController
 * @author: HXJ
 * @date: 2023/5/13 10:49 PM
 * @version: V1.0
 * @description: 用户Controller层,该层实现了请求的处理和服务的调用
 */

@RestController
public class UserController {

    @Resource
    private UserService userService;

    @GetMapping("/hello")
    public String sayHello(){
        return "hello";
    }

    @PostMapping(value = "/login")
    public ModelAndView login(User user){
        ModelAndView mv = new ModelAndView();
        //从User这个参数对象中获取输入的用户名和密码
        String username = user.getUsername().trim();
        String password = user.getPassword().trim();
        //对输入的账号密码进行空串、空格串、null引用的特殊判断
        if(StringUtils.isBlank(username) || StringUtils.isBlank(password) ){
            mv.setViewName("redirect:/login.jsp");
        } else {
            if(userService.login(username,password) == 0){
                //执行结果为0意味着数据库中的用户名和密码与输入的不匹配,重定向到登录页面
                mv.setViewName("redirect:/login.jsp");
            } else {
                //执行结果不为0(大于0)意味着数据库中的用户名和密码与输入的匹配,重定向到主页面
                mv.setViewName("redirect:/index.jsp");
            }
        }
        return mv;
    }

    @PostMapping(value = "/register")
    public ModelAndView register(User user){
        ModelAndView mv = new ModelAndView();
        //从User这个参数对象中获取输入的用户名和密码
        String username = user.getUsername().trim();
        String password = user.getPassword().trim();
        //对输入的账号密码进行空串、空格串、null引用的特殊判断
        if(StringUtils.isBlank(username) || StringUtils.isBlank(password) ){
            mv.setViewName("redirect:/register.jsp");
        } else {
            if(userService.register(username,password) == 0){
                //执行结果为0意味着数据库中已存在同名用户,重定向到注册页面
                mv.setViewName("redirect:/register.jsp");
            } else {
                //执行结果不为0意味着插入数据成功(用户注册成功),重定向到登录页面
                mv.setViewName("redirect:/login.jsp");
            }
        }
        return mv;
    }

}

引入Bootstrap搭配JSP模板引擎技术实现前端页面

编写index.jsp文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<html>
<body>
<h2>Hello World!</h2>
<a href="login.jsp">跳转到登录页面</a>
<br/>
<a href="register.jsp">跳转到注册页面</a>
</body>
</html>

编写register.jsp

<%--
  Created by IntelliJ IDEA.
  User: can
  Date: 2023/5/14
  Time: 8:02 PM
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" deferredSyntaxAllowedAsLiteral="false" %>
<html>
<head>
    <title>注册页面</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
    <!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap-theme.min.css" integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ" crossorigin="anonymous">
    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
</head>
<body>
<form class="form-horizontal" action="register" method="post">
    <div class="form-group">
        <label for="inputEmail3" class="col-sm-2 control-label">用户名</label>
        <div class="col-sm-10">
            <input type="text" name="username" class="form-control" id="inputEmail3" placeholder="Username">
        </div>
    </div>
    <div class="form-group">
        <label for="inputPassword3" class="col-sm-2 control-label">密码</label>
        <div class="col-sm-10">
            <input type="text" name="password" class="form-control" id="inputPassword3" placeholder="Password">
        </div>
    </div>
    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <button type="submit" class="btn btn-primary">注册</button>
        </div>
    </div>
</form>
</body>
</html>

编写login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录页面</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
    <!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap-theme.min.css" integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ" crossorigin="anonymous">
    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
</head>
<body>
<form class="form-horizontal" action="login" method="post">
    <div class="form-group">
        <label for="inputEmail3" class="col-sm-2 control-label">用户名</label>
        <div class="col-sm-10">
            <input type="text" name="username" class="form-control" id="inputEmail3" placeholder="Username">
        </div>
    </div>
    <div class="form-group">
        <label for="inputPassword3" class="col-sm-2 control-label">密码</label>
        <div class="col-sm-10">
            <input type="text" name="password" class="form-control" id="inputPassword3" placeholder="Password">
        </div>
    </div>
    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <button type="submit"  class="btn btn-success">登录</button>
        </div>
    </div>
</form>

</body>
</html>

5.测试运行结果

配置Tomcat服务器

选择 war exploded 井将应用程序上下文改为/

运行Tomcat后访问localhost:8080

跳转到注册页面

在注册页面进行用户注册

注册成功会自动跳转到登录页面

注册失败会停留在当前页面

注册成功跳转到登录页面

在登录页面进行用户登录

登录成功会自动跳转到生页

登录失败会停留在当前页面

修改数据库中对应的账号密码后再测试

访问localhost:8080,完成从主页--->注册页--->登录页--->主页的流程

如果以上流程你能够完成,那么恭喜你,一个拥有基础的注册和登录功能的SSM框架模板已经构建好了!