【java后端】通过一个简易的会员管理系统复习SSM框架整合

665 阅读7分钟

(一)介绍

本项目通过对 SSM框架的整合,实现对数据库表格的增删改查,目的是复习并巩固后端实现流程,因此主要工作量在后端代码,前端实现较简单,可根据自己的喜好对前端页面进行设计并实现。(可在文章最后的测试功能部分查看实现效果)

1.需要完成的功能

  • 在数据库中创建会员信息表来保存会员信息
  • 提供可供用户完成操作的前端界面
  • 增删改查会员的信息(id,姓名,年龄)

2.涉及技术

Java基础知识

框架:Spring, MyBatis, SpringMyBatis整合,SpringMVCSSM整合

数据库:MySQL

Web:JSPServletTomcat服务器

前端:htmlCSSjavascriptajaxjquery

开发工具:IDEA, Maven

3.框架介绍

SSMSpring+SpringMVC+Mybatis),目前较为主流的企业级架构方案。标准的MVC设计模式,将整个系统划分为显示层(SpringMVC)、Controller层(SpringMVC)、Service层(Spring)、Dao层四层(MyBatis),使用SpringMVC负责请求的转发和视图管理,Spring实现业务对象管理,MyBatis作为数据对象持久化引擎。

1.MyBatis

MyBatis 是一个优秀的基于 java 的持久层框架,内部封装了 jdbc,开发者只需要关注 sql 语句本身,而不需要处理加载驱动、创建连接、创建 statement、关闭连接,资源等繁杂的过程。

MyBatis 通过xml 或注解两种方式将要执行的各种 sql 语句配置起来,并通过 java 对象和 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。

2.Spring

Spring 是于 2003 年兴起的一个轻量级的 Java 开发框架,它是为了解决企业应用开发的复杂性而创建的。Spring 的核心是控制反转(IoC)和面向切面编程(AOP)。Spring 是可 以在 Java SE/EE 中使用的轻量级开源框架。

3.SpringMVC

Spring MVC 属于 SpringFrameWork 3.0 版本加入的一个模块,为 Spring 框架提供了构建 Web应用程序的能力。现在可以 Spring 框架提供的 SpringMVC 模块实现web 应用开发,在web 项目中 可以无缝使用 SpringSpring MVC 框架。

(二)准备工作

1.配置tomcat(已配置可跳过)

(1)下载与安装(以Tomcat9为例)

tomcat.apache.org ,在【Download】下选择 Tomcat9后,进入到 Tomcat.9下载页面 image.png

点击【64 bit Windows zip(pgp,sha512)】得到 Tomcat安装包

image.png

将压缩包解压,复制到D盘

image.png

image.png

(2)检查环境变量

JAVA_HOME:指向JDK安装地址

JRE_HOME:指向JRE安装地址(较少情况需要配置)

(3)Tomcat启动关闭

1)启动与关闭命令存放位置Tomcat安装位置/bin

2)启动命令:startup. bat 关闭命令:shutdown. bat

a.启动

来到bin目录下

image.png

打开命令行

image.png

输入startup,回车:

image.png

弹出窗口:

image.png

b.关闭

关闭弹出窗口,执行shutdown:

image.png

结果如图所示:

image.png

(4)IDEA管理Tomcat

a.导入Tomcat

打开设置

image.png

在弹出的窗口中选擇【Buid, Execution, Deployment】->【Application Servers】

image.png

选择并点击Tomcat Server:

image.png

找到Tomcat目录,点ok

image.png

image.png

继续点ok保存即可

b.添加开关

选择【RUN】-【Edit Configuration】设置 Tomcat启动与关闭按钮

image.png

点击左上的+,选择Tomcat Server-->Local,起个名字,其他不动,点击ok

image.png

2.配置maven(已配置可跳过)

可参考我的另一篇博客:juejin.cn/post/699740…

3.创建表Member

创建表,将id设置为主键,且自增

Snipaste_2021-09-06_17-15-50.jpg

(三)项目搭建

1.创建module

1.在IDEA中创建一个空项目,如图选择new->ModuleSnipaste_2021-09-06_17-22-31.jpg

2.如图设置,点击next Snipaste_2021-09-06_17-23-37.jpg

3.检查基本设置后,点击next

Snipaste_2021-09-06_17-29-21.jpg

4.直接finish

Snipaste_2021-09-06_17-29-33.jpg

2.整理项目的目录结构

按照模板创建的项目目录较简单,如图在其基础上增加一些包:

Snipaste_2021-09-06_17-56-59.jpg

3.整理pom文件

springmvc,spring,mybatis三个框架的依赖,jackson依赖,mysql驱动,druid连接池,jsp,servlet依赖

具体代码如下:

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
​
  <groupId>com.bupt</groupId>
  <artifactId>ssm-demo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
​
​
  <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>
  </properties>
​
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!--servlet依赖-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <!-- jsp依赖 -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.2.1-b03</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.1</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.1</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.9</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.12</version>
    </dependency>
  </dependencies>
​
  <build>
    <resources>
      <resource>
        <directory>src/main/java</directory><!--所在的目录-->
        <includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
​
      <resource>
        <directory>src/main/resources</directory><!--所在的目录-->
        <includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
​
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

4.修改web.xml

(1)更新版本

Snipaste_2021-09-06_19-12-32.jpg

Snipaste_2021-09-06_19-13-14.jpg

Snipaste_2021-09-06_19-15-38.jpg

Snipaste_2021-09-06_19-22-59.jpg

(2)具体内容

文件中主要包括以下三部分:

1)注册中央调度器DispatcherServlet

作用:

a.创建springmvc容器对象,才能创建Controller类对象。

b.创建的是Servlet,才能接受用户的请求。

2)注册spring的监听器

作用:

a.ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。 创建spring的容器对象,才能创建service,dao等对象。

b.如果在web.xml中不写任何参数配置信息,默认的路径是/WEB-INF/applicationContext.xml,在WEB-INF目录下创建的xml文件的名称必须是applicationContext.xml;如果是要自定义文件名可以在web.xml里加入contextConfigLocation这个context参数。

3)注册字符集过滤器

作用:解决post请求乱码的问题。

注:由于配置文件还未创建,代码中配置文件的路径(springmvc配置文件路径conf/dispatcherServlet.xml和spring配置文件路径conf/applicationContext.xml)会爆红,稍后创建。

具体代码如下:

<?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">
​
​
    <!--注册中央调度器-->
    <servlet>
        <servlet-name>myweb</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:conf/dispatcherServlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>myweb</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
​
    <!--注册spring的监听器-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:conf/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
​
    <!--注册字符集过滤器-->
    <filter>
        <filter-name>characterEncodingFilter</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>
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
​
​
</web-app>

5.创建数据库及ssm框架的配置文件

如图在资源文件夹下创建conf包,在其中创建配置文件:

Snipaste_2021-09-06_19-59-07.jpg

(1)数据库配置文件jdbc.properties

包括数据库连接需要的参数,用于被spring配置文件读取并创建数据库连接对象。

根据自己的数据库信息填写。

具体代码如下:

jdbc.url=jdbc:mysql://localhost:3306/springdb?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456

(2)spring配置文件applicationContext.xml

1)读取jdbc.properties,拿到参数

2)声明数据源,连接数据库

3)创建SqlSessionFactory

4)声明mybatis的扫描器,扫描mapper文件,通过getmapper创建dao对象

5)配置组件扫描器:扫描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">
​
    <context:property-placeholder location="classpath:conf/jdbc.properties" />
​
    <!--声明数据源,连接数据库-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close">
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>
​
    <!--创建SqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation"  value="classpath:conf/mybatis.xml" />
    </bean>
    
    <!--声明mybatis的扫描器-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        <property name="basePackage" value="com.bupt.dao" />
    </bean>
​
    <!--声明service的注解@Service所在的包名位置-->
    <context:component-scan base-package="com.bjpowernode.service" /></beans>

(3)springmvc配置文件dispatcherServlet.xml

1)配置组件扫描器:扫描controller包下的注解,根据注解创建对象。

2)视图解析器:controller方法返回页面时拼接为完整的页面地址。使用自负床拼接的方式,以本项目为例,假设返回result页面,则在controller方法中的返回值写result即可,内部通过拼接"/WEB-INF/jsp/"+"result"+".jsp"得到完整地址。

3)配置annotation-driven:响应ajax请求,返回json

具体代码如下:

<?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">
​
    <!--springmvc配置文件, 声明controller和其它web相关的对象-->
    <context:component-scan base-package="com.bupt.controller" />
​
    <!-- 视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
​
    <mvc:annotation-driven />
    <!--
      1. 响应ajax请求,返回json
      2. 解决静态资源访问问题。
    -->
</beans>

(4)mabatis配置文件mybatis.xml

1)设置别名,name为实体类所在的包名,设置后mapper文件的resultType写类名即可(否则要写实体类的全限定名称)

2)配置mapper(sql映射文件)的位置。namedao的包名, 这个包中的所有mapper.xml一次都能加载 使用package的要求:mapper文件名称和dao接口名必须完全一样,包括大小写,mapper文件和dao接口必须在同一目录

具体代码如下:

<?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>
        <!--name:实体类所在的包名-->
        <package name="com.bupt.domain"/>
    </typeAliases>
​
    <!-- sql mapper(sql映射文件)的位置-->
    <mappers>
        <package name="com.bupt.dao"/>
    </mappers>
</configuration>

6.创建实体类Member

domain包下创建类,属性与表的字段一致。

创建构造函数,setget方法,重写toString方法。

Member源代码如下:

package com.bupt.domain;
​
public class Member {
    private Integer id;
    private String name;
    private Integer age;
​
    public Member() {
    }
​
    public Member(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
​
    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 Integer getAge() {
        return age;
    }
​
    public void setAge(Integer age) {
        this.age = age;
    }
​
    @Override
    public String toString() {
        return "Member{" +
                "id=" + id +
                ", name='" + name + ''' +
                ", age=" + age +
                '}';
    }
}

7.创建Dao接口和mapper文件

在dao包下创建Dao接口和mapper文件

其中dao对象在spring配置文件中由spring容器创建 MemberDao代码如下:

package com.bupt.dao;
​
import com.bupt.domain.Member;
​
import java.util.List;
​
public interface MemberDao {
    int insertMember(Member member);
    List<Member> selectMembers();
    int updateMember(Member member);
    int deleteMember(Integer id);
}
​

MemberDao.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.bupt.dao.MemberDao">
​
    <!--查询-->
    <select id="selectMembers" resultType="Member">
        select id,name,age from member order by id desc
    </select>
​
    <!--插入-->
    <insert id="insertMember">
        insert into member(name,age) values(#{name},#{age})
    </insert>
​
    <!--修改-->
    <update id="updateMember">
        update member set name = #{name},age = #{age} where id = #{id}
    </update>
​
    <!--删除-->
    <delete id="deleteMember">
        delete from member where id=#{id}
    </delete>
</mapper>

8.创建service接口及其实现类

在service包下创建service接口及其实现类

1.service实现类对象通过注解@Service创建,在spring配置文件中由spring容器创建

2.service实现类的dao属性为MemberDao对象,通过注解@Resource创建

3.在此复习一下@Resource和@Autowired不同点: (1)提供方:@Autowired是由Spring提供;@Resource是由J2EE提供,需要JDK1.6及以上。 (2)注入方式:@Autowired只按照byType 注入;@Resource默认按byName自动注入,也提供按照byType 注入。 (3)属性:@Autowired按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。如果想使用按名称装配,可以结合@Qualifier注解一起使用。

4.复习@Resource装配顺序:

1)如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常

2)如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常

3)如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常

4)如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;

service接口MemberService代码如下:

package com.bupt.service;
​
import com.bupt.domain.Member;
​
import java.util.List;
​
public interface MemberService {
    int addMember(Member member);
    List<Member> findMembers();
    int modifyMember(Member member);
    int removeMember(Integer id);
}
​

实现类MemberServiceImpl代码如下:

package com.bupt.service.impl;
​
import com.bupt.dao.MemberDao;
import com.bupt.domain.Member;
import com.bupt.service.MemberService;
import org.springframework.stereotype.Service;
​
import javax.annotation.Resource;
import java.util.List;
​
@Service
public class MemberServiceImpl implements MemberService {
    @Resource
    private MemberDao dao;
    @Override
    public int addMember(Member member) {
        return dao.insertMember(member);
    }
​
    @Override
    public List<Member> findMembers() {
        return dao.selectMembers();
    }
​
    @Override
    public int modifyMember(Member member) {
        return dao.updateMember(member);
    }
​
    @Override
    public int removeMember(Integer id) {
        return dao.deleteMember(id);
    }
}
​

9.创建Controller类

在controller包下创建Controller类,接收前端处理器分派过来的请求,处理并返回处理结果。

1.controller实现类对象通过注解@Controller创建,在springmvc配置文件中由springmvc容器创建

2.controller实现类的service属性为MemberService对象,通过注解@Resource创建

MemberController

package com.bupt.controller;
​
import com.bupt.domain.Member;
import com.bupt.service.MemberService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
​
import javax.annotation.Resource;
import java.util.List;
​
@Controller
@RequestMapping("/member")
public class MemberController {
    @Resource
    private MemberService service;
​
    @RequestMapping("/addMember.do")
    public ModelAndView addMember(Member member){
        //System.out.println(member);
        ModelAndView mv = new ModelAndView();
        String tips = "注册失败";
        int nums = service.addMember(member);
        if( nums > 0 ){
            //注册成功
            tips = "会员【" + member.getName() + "】注册成功";
        }
        //添加数据
        mv.addObject("tips",tips);
        //指定结果页面
        mv.setViewName("result");
        return mv;
    }
​
    @RequestMapping("/deleteMember.do")
    public ModelAndView deleteMember(Integer id){
        ModelAndView mv = new ModelAndView();
        String tips = "删除失败";
        int nums = service.removeMember(id);
        if( nums > 0 ){
            tips = "id为【" + id + "】的会员删除成功";
        }
        //添加数据
        mv.addObject("tips",tips);
        //指定结果页面
        mv.setViewName("result");
        return mv;
    }
​
    @RequestMapping("/updateMember.do")
    public ModelAndView updateMember(Member member){
        ModelAndView mv = new ModelAndView();
        String tips = "更新失败";
        //调用service处理student
        int nums = service.modifyMember(member);
        if( nums > 0 ){
            //注册成功
            tips = "id为【" + member.getId() + "】的学生更新成功";
        }
        mv.addObject("tips",tips);
        mv.setViewName("result");
        return mv;
    }
​
    //处理查询,响应ajax
    @RequestMapping("/queryMember.do")
    @ResponseBody
    public List<Member> queryMember(){
        //参数检查, 简单的数据处理
        List<Member> members = service.findMembers();
        //框架会自动把集合转变为json数组
        return members;
    }
}

10.当前目录结构

至此,后端代码编写完成,目录结果如下:

Snipaste_2021-09-07_09-45-25.jpg

11.前端页面编写

(1)前端页面逻辑关系:

1.所需页面:共包括欢迎页面index.jsp,增删改查的功能页面addMember.jspdeleteMember.jspupdateMember.jsplistMember.jsp,以及返回的结果页面result.jsp共6个页面。其中欢迎页面及功能页面直接放在webapp目录下;返回的结果页面result.jsp放在WEB-INF目录下,不能被用户通过浏览器地址栏直接访问,保证了安全性。

2.其他资源:页面用到了jquery发起ajax请求,因此需要添加jquery的库文件jquery-3.4.1.js,页面用到的图片放到了image文件夹下。

3.逻辑关系:当用户访问网页时,默认弹出index.jsp页面,页面包括了增删改查四个选项供用户选择,点击选项后分别跳转到4个功能页面,在功能页面中输入参数发起请求,请求处理完成后返回结果页面展示处理结果。

(2)页面的目录结构

Snipaste_2021-09-07_10-23-00.jpg

(3)首页文件--- index.jsp

1.页面主要包括一个图片资源及四个跳转到功能页面的选项。

2.其中<base>标签为页面上的所有链接规定默认地址或默认目标。浏览器随后将不再使用当前文档的 URL,而使用指定的基本 URL 来解析所有的相对 URL。这其中包括 <a>、<img>、<link>、<form> 标签中的 URL。

3.用到的request方法说明:

request.getSchema()可以返回当前页面使用的协议,http 或是 https; request.getServerName()可以返回当前页面所在的服务器的名字; request.getServerPort()可以返回当前页面所在的服务器使用的端口; request.getContextPath()可以返回当前页面所在的应用的名字;

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String basePath = request.getScheme() + "://" +
            request.getServerName() + ":" + request.getServerPort() +
            request.getContextPath() + "/";
%>
<html>
<head>
    <title>功能入口</title>
    <base href="<%=basePath%>" />
</head>
<body>
    <div align="center">
    <p>会员管理系统demo</p>
    <img src="images/vip.png" />
    <table>
        <tr>
            <td><a href="addMember.jsp"> 注册会员</a></td>
        </tr>
        <tr>
            <td><a href="deleteMember.jsp"> 删除会员</a></td>
        </tr>
        <tr>
            <td><a href="updateMember.jsp"> 更新会员</a></td>
        </tr>
        <tr>
            <td><a href="listMember.jsp">浏览会员</a></td>
        </tr>
    </table>
    </div>
    
</body>
</html>

(4)注册会员页面 --- addMember.jsp

作用:发起请求,向表中添加一条记录。处理后跳转到结果页面。

使用表单标签发送请求:<form action="member/addMember.do" method="post">

表单标签命令不会被浏览器自动执行。在用户单击提交按钮时,此时表单标签命令被触发执行。执行时要求浏览器立刻按照action属性地址发送请求。

代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册会员</title>
</head>
<body>
    <div align="center">
        <form action="member/addMember.do" method="post">
            <table>
                <tr>
                    <td>姓名:</td>
                    <td><input type="text" name="name"></td>
                </tr>
                <tr>
                    <td>年龄:</td>
                    <td><input type="text" name="age"></td>
                </tr>
                <tr>
                    <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
                    <td><input type="submit" value="注册"></td>
                </tr>
            </table>
        </form>
    </div>
</body>
</html>

(5)删除会员页面 --- deleteMember.jsp

作用:发起请求,在表中删除一条记录。处理后跳转到结果页面。

代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <div align="center">
        <!--需添加对应方法-->
        <form action="member/deleteMember.do" method="post">
            <table>
                <tr>
                    <td>id:</td>
                    <td><input type="text" name="id"></td>
                </tr>
                <tr>
                    <!--  <p>       abc</p>  这时候浏览器会忽略掉abc前面得空格  -->
                    <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
                    <td><input type="submit" value="删除"></td>
                </tr>
            </table>
        </form>
    </div></body>
</html>

(6)修改会员页面 --- updateMember.jsp

作用:发起请求,在表中修改一条记录。处理后跳转到结果页面。

代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <div align="center">
        <form action="member/updateMember.do" method="post">
            <table>
                <tr>
                    <td>id:</td>
                    <td><input type="text" name="id"></td>
                </tr>
                <tr>
                    <td>姓名:</td>
                    <td><input type="text" name="name"></td>
                </tr>
                <tr>
                    <td>年龄:</td>
                    <td><input type="text" name="age"></td>
                </tr>
                <tr>
                    <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
                    <td><input type="submit" value="更新"></td>
                </tr>
            </table>
        </form>
    </div></body>
</html>

(7)浏览会员页面 --- listMember.jsp

作用:发送ajax请求,查询表中所有记录, 将结果展示到当前页面。

具体代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String basePath = request.getScheme() + "://" +
            request.getServerName() + ":" + request.getServerPort() +
            request.getContextPath() + "/";
%>
<html>
<head>
    <title>查询ajax</title>
    <base href="<%=basePath%>" />
    <script type="text/javascript" src="js/jquery-3.4.1.js"></script>
    <script type="text/javascript">
        //$(document).ready(function()的简洁写法
        $(function(){
            // #id 选择器通过 HTML 元素的 id 属性选取指定的元素。找到了id为btnLoader的元素,设置点击函数
            // 此外还有.class 选择器
            $("#btnLoader").click(function(){
                loadData();
            })
        })
​
        function loadData(){
            //使用 AJAX 请求改变 <info> 元素的文本
            $.ajax({
                url:"member/queryMember.do",
                type:"get",
                dataType:"json",
                success:function(data){
                    //清除旧的数据。设置为空
                    //html() - 设置或返回所选元素的内容(包括 HTML 标记)
                    $("#info").html("");
                    //增加新的数据
                    $.each(data,function(i,n){
                        //同一行的三列数据
                        //添加新的 HTML 内容:append() - 在被选元素的结尾插入内容
                        $("#info").append("<tr>")
                            .append("<td>"+n.id+"</td>")
                            .append("<td>"+n.name+"</td>")
                            .append("<td>"+n.age+"</td>")
                            .append("</tr>")
​
                    })
                }
            })
        }
    </script>
</head>
<body>
    <div align="center">
        <table>
            <thead>
             <tr>
                 <td>id</td>
                 <td>姓名</td>
                 <td>年龄</td>
             </tr>
            </thead>
            <tbody id="info">
​
            </tbody>
        </table>
        <input type="button" id="btnLoader" value="查询/更新数据">
​
    </div>
</body>
</html>

(8)结果页面 --- result.jsp

作用:展示传入的处理信息tips

代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
   操作结果: ${tips}
</body>
</html>

12.总体目录结构

(1)后端及配置文件

Snipaste_2021-09-07_11-11-57.jpg

(2)前端部分

Snipaste_2021-09-07_11-12-53.jpg

(四)测试网站功能

1.部署网页到tomcat

选择Run-->Edit Configurations

Snipaste_2021-09-07_11-16-08.jpg

2.访问web项目

启动tomcat,在浏览器访问http://localhost:8080/ssm_demo,其中ssm_demo为网站名称,需要与上一步部署网站时设置的名称一致。访问网站后,弹出默认欢迎页面index.jsp

Snipaste_2021-09-07_15-09-16.jpg 页面包括图片及四个选项。

3.测试增加功能

此时数据库中的member表是空的:

Snipaste_2021-09-07_15-15-57.jpg

index.jsp中选择注册会员,弹出addMember.jsp,输入参数,点击注册:

Snipaste_2021-09-07_15-16-31.jpg

操作成功,返回结果页面:

Snipaste_2021-09-07_15-17-13.jpg

查看数据库,此时数据库中增加了一条记录:

Snipaste_2021-09-07_15-17-23.jpg

4.测试查询功能

此时回退到欢迎页面index.jsp,选择浏览会员,跳转到listMember.jsp

Snipaste_2021-09-07_15-18-47.jpg

点击查询/更新,可以查询到刚刚添加的用户信息:

Snipaste_2021-09-07_15-19-05.jpg

以同样方法增加两条记录后,再次查询,得到全部会员用户的信息:

Snipaste_2021-09-07_15-25-51.jpg

此时数据库的member表中有3条记录:

Snipaste_2021-09-07_15-28-05.jpg

5.测试删除功能

再次回退到欢迎页面index.jsp,选择删除会员,跳转到deleteMember.jsp,输入要删除会员的id:

Snipaste_2021-09-07_15-29-02.jpg

点击删除:

Snipaste_2021-09-07_15-29-15.jpg

再次选择浏览会员:

Snipaste_2021-09-07_15-29-29.jpg

此时数据库的member表中有2条记录:

Snipaste_2021-09-07_15-29-43.jpg

6.测试修改功能

再次回退到欢迎页面index.jsp,选择更新会员(根据id进行更新):

Snipaste_2021-09-07_15-35-29.jpg

点击更新:

Snipaste_2021-09-07_15-35-37.jpg

再次选择浏览会员:

Snipaste_2021-09-07_15-35-48.jpg

此时数据库的member表中id为3的用户数据被更新了: Snipaste_2021-09-07_15-35-57.jpg

结语

有问题欢迎提出,我自身也在学习阶段,欢迎一起讨论和学习~