SSM框架整合之单表操作

1、Spring和Spring MVC父子容器 

概念介绍
1.在Spring与SpringMVC进行整合的时候,一般情况下我们会使用不同的配置文件来配置Spring和SpringMVC,因此我们的应用中会存在至少2个ApplicationContext的实例,由于是在Web应用中,因此最终实例化的是ApplicationContext的子接口 WebApplicationContext。

2.ServletWebApplicationContextRoot WebApplicationContext其中:

  • Servlet WebApplicationContext:这是对12E三层架构中的web层进行配置,如控制器(controller),视图解析器(view resolvers)等相关的bean。通过springmvc中提供的DispatchServlet来加载配置,通常情况下,配置文件的名称为springmvc.xml。
  • Root WebApplicationConte:这是对J2EE三层架构中的service层、dao层进行配置,如业务bean,数据源(DataSource)等。通常情况下,配置文件的名称为applicationContext.xml。在web应用中,其一般通过ContextLoaderListener来加载。
<?xm1 version="1.0"encoding="uTF-8"?>
<web-appversion="2.4"
xm1ns="http://java.sun.com/xm1/ns/j2ee"
xm1ns:xsi=“http://www.w3.ora/2001/XMLschema-instance"
xs1:schemaLocation="http://iava.sun.com/xm1/ns/i2eehttp://iava.sun.com/xm1/ns/i2ee/web
app_2_4.xsd">

3.同时通过两个容器同时来管理所有的类

会在两个父子IOC容器中生成大量的相同bean,这就会造成内存资源的浪费。

一般正常的操作:

@RequestMapping一般会和@Controller搭配使用。为了防止重复注册bean,建议在springMVC.xml配置文件中只扫描含有Controller bean的包,其它的共用bean的注册定义到applicationContext.xml文件中。

applicationContext.xml

<!--扫播的是com.hp包,但是不扫描contro1ler的注解。--><context:component-scan base-package=com.hp">
<context:exc1ude-filter type="annotation”expression="org.springframework.stereotype.contro1ler"/></contextcomponent-scan>

springMVC.xml

<!--扫描的是com.hp包,但是只扫描contro1ler的注解。-->
<context:component-scan base-package="com.hp”use-default-filters="false">
<context:inc1ude-filter type="annotation”expression="org.springframework.stereotypeContro1ler"/></context:component-scan>

2、项目实例

辅助编程:Navicat、phpstudy_pro、IDEA2020.2.2、TomCat

技术框架:MySQL8.0、Spring、SpringMVC、MyBatis

1.项目架构和相关jar包;

 2.创建t_user和goods表

drop database if exists mydb;
create database mydb;
use mydb;
#创建表
create table t_user (
  uid int(11) primary key not null AUTO_INCREMENT,
  username varchar(20),
  password varchar(20),
  birthday varchar(20),
  phone varchar(11),
  address varchar(50)
);
#插入数据
insert into t_user values (1, '张三','111','2022-05-03', '13865430001', '北京');
insert into t_user values (2, '李四','222','2022-05-19', '13598765002', '广州');
insert into t_user values (3, '小红','333','2022-05-19', '15964598003', '郑州');
insert into t_user values (4, '小美','444','2022-05-20', '15765482006', '郑州');

select * from t_user;
#判断删除
drop table if exists goods;
#创建商品信息表
create table goods(
gid int primary key auto_increment,
	gname varchar(20),
	price double,
	stock int,
	supplier varchar(50)
);
#插入数据
insert into goods values(1,'泡面',3.5,50,'康师傅');
insert into goods values(2,'牛奶',5.5,60,'蒙牛');
insert into goods values(3,'瓜子',6.5,30,'金鸽');


select * from goods;

 3.,创建Module命名为ssm01,成为Web项目,并部署到tomcat服务器中测试项目是否能够正常加载并访问首页

bean包中的实体类分别根据数据库的表名和表的字段名创建,alt+insert快捷键增加setter和getter方法以及toString方法;

注意:属性名全部小写,int和double类型使用封装类Integer和Double,private修饰符修饰

 

4.创建SSM框架对应的配置文件,三层架构Controller、service、dao

springmvc.xml配置

  1. 扫描 controller
  2. 配置视图解析器;
  3. 静态资源不拦截;
  4. 开启注解驱动支持(自动配置映射器和适配器);
<?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">
    <!--1.扫描控制器,把控制器对象交给springMVC的IOC统一管理-->
    <context:component-scan base-package="com.zhan.controller"/>
    <!--2.配置视图解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!--3.静态资源不拦截-->
    <mvc:resources mapping="/css/**" location="/css/"/>
    <mvc:resources mapping="/js/**" location="/js/"/>
    <mvc:resources mapping="/fonts/**" location="/fonts/" />
    <mvc:resources mapping="/img/**" location="/img/"/>
    <!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean id="myInterceptor" class="com.zhan.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
    <!--4.开启注解驱动支持:默认配置 映射器 和 适配器-->
    <mvc:annotation-driven/>
</beans>

 spring.xml配置

  1. 管理除了 controller 外所有的类;
  2. 配置数据源(数据库连接参数);
  3. 配置SqlSessionFactoryBean,自动获得数据库连接并得到代理对象;
  4. 配置扫描器,告诉 mybatis 要创建哪些接口的代理对象;
<?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"
       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">
    <!--1.让spring框架管理com.chen包中所有的对象,但是排除使用了Controller注解的类-->
    <context:component-scan base-package="com.zhan">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    <!--2.让sprin框架的jdbc管理数据库的连接-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
    <!--3.配置SqlSessionFactoryBean,把SqlSessionFactory对象交给IOC管理,他会自动创建
    sqlSession对象,会根据mapper接口再创建代理对象-->
    <bean id="factoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis.xml"/>
    </bean>
    <!--4.配置扫描器,扫描mapper文件,让mybatis知道要创建什么接口的实现类-->
    <bean id="scannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.zhan.dao"/>
    </bean>
</beans>

mybatis.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="log4j"/>-->
<!--    </settings>-->
</configuration>

配置web项目的核心配置文件web.xml  

1. 配置监听器,检测 servlet 容器创建的时候加载 spring.xml 配置文件 ;
2. 配置核心控制器 DispatcherServlet ,创建的时候加载 springmvc.xml 配置文件;
3. 配置字符集过滤器,设置中文编码;
<?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">
    <!--1.配置监听器,检测servlet容器创建的时候加载 spring.xml-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring.xml</param-value>
    </context-param>
    <!--2.配置核心控制器DispatcherServlet,创建的时候加载 springmvc.xml-->
    <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:springmvc.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!--3.配置字符集过滤器,设置中文编码-->
    <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>
</web-app>

5.登录页面的实现

 index.jsp首页点击超链接去到登录页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>首页</title>
  </head>
  <body>
  <h2>欢迎来到项目首页!</h2>
  <h3><a href="login.jsp">去登录</a></h3>
  </body>
</html>

 

login.jsp页面输入用户名和密码,正确跳转到主页,错误跳转到错误页;

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录页</title>
</head>
<body>
<h2>登录页</h2>
<form action="login" method="post">
    帐号:<input type="text" name="username" value="" /> <br/>
    密码:<input type="password" name="password" value="" /> <br/>
    <input type="submit" value="登录" /> <br/>
</form>
</body>
</html>

 zhuye.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>项目主页</title>
</head>
<h2>欢迎${user.username}来到主页</h2>
<h3><a href="addGoods.jsp">添加商品</a></h3>
<body>
<table>
    <thead>
    <tr>
        <th>编号</th>
        <th>商品</th>
        <th>价格</th>
        <th>库存</th>
        <th>品牌</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    <c:forEach items="${goodsList}" var="goods">
        <tr>
            <td>${goods.gid}</td>
            <td>${goods.gname}</td>
            <td>${goods.price}</td>
            <td>${goods.stock}</td>
            <td>${goods.supplier}</td>
            <td>
                <a href="delGoods?gid=${goods.gid}">删除</a>
                <a href="findByGid?gid=${goods.gid}">修改</a>
            </td>
        </tr>
    </c:forEach>
    </tbody>
</table>
</body>
</html>
请求发生后,自动进行数据绑定,拿到用户提交的用户名和密码执行数据的查询,获得数据中该用
户的信息;
如果信息为空说明登录失败;否则表示登录成功;然后请求查询所有的商品信息;
控制层
@Controller
@SessionAttributes({"user"})
public class UserController {
    @Autowired
    UserService userService;

    @RequestMapping("/login")
    public ModelAndView login(User user){
        //System.out.println("UserController......login");
        ModelAndView mv = new ModelAndView();
        User login = userService.login(user);
        System.out.println(login);
        if(login!=null){
            mv.addObject("user",login);
            mv.setViewName("redirect:/findAll");
        }else{
            mv.addObject("error","用户名或密码错误!");
            mv.setViewName("error");
        }
        return mv;
    }
}

业务层

public interface UserService {
    User login(User user);
}
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserDao userDao;

    @Override
    public User login(User user) {
        return userDao.selectForLogin(user);
    }
}

持久层

@Repository
public interface UserDao {
    @Select("select * from t_user where username=#{username} and password=#{password}")
    User selectForLogin(User user);
}

2.实现商品信息的增删改查

增:当点击保存的时候请求 saveGoods ,且传递表单录入的数据,控制器对应的请求处理方法获得商品信息执行数据库的添加操作;

删:点击主页的删除按钮,请求 delGoods 同时携带商品的编号; 在控制器对应的方法中执行请求处理,并根据获取到的商品编号执行数据库 的删除操作;
改:修改功能分为两步:
1.点击修改按钮执行的是根据id的查询,查询该信息然后在页面中做数据的回显;
2.在数据展示页面的表单中根据需要修改完数据后提交执行数据库的更新操作;
点击主页的修改按钮,请求 findByGid 同时携带商品的编号;
在控制器对应的方法中执行请求处理,并根据获取到的商品编号执行数据库的查询操作;
当点击修改按钮时执行数据更新操作
模糊查询
addGoods.jsp添加页面 
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>添加页</title>
</head>
<body>
<h2>商品信息添加</h2>
<form action="saveGoods" method="post">
    商品:<input type="text" name="goodsName" value="" /> <br/>
    价格:<input type="number" step="0.01" name="price" value="" /> <br/>
    库存:<input type="number" name="stock" value="" /> <br/>
    供货商:<input type="text" name="supplier" value="" /> <br/>
    <input type="submit" value="保存" /> <br/>
</form>
</body>
</html>

  

showGoods.jsp修改页面;使用EL表达式把数据显示在表单元素中;由于修改时需要根据id进行修改,所以在数据展示页面的表单中需要显式id且设置为只读状态;

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>修改页</title>
</head>
<body>
<h2>商品信息修改</h2>
<form class="form-horizontal" action="updateGoods" method="post">
    编号:<input type="text" name="goodsId" value="${goods.goodsId}" readonly="readonly"> <br/>
    商品:<input type="text" name="goodsName" value="${goods.goodsName}"><br/>
    价格:<input type="number" step="0.01" name="price" value="${goods.price}"> <br/>
    库存:<input type="number" name="stock" value="${goods.stock}"> <br/>
    供货商:<input type="text" name="supplier" value="${goods.supplier}"><br/>
    <input type="submit" value="修改">
</form>
</body>
</html>

  

控制层

package com.zhan.controller;

import com.zhan.bean.Goods;
import com.zhan.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;

@Controller
@SessionAttributes({"goodsList"})
public class GoodsController {
    @Autowired
    GoodsService goodsService;

    @RequestMapping("/findAll")
    public ModelAndView findAll(){
        ModelAndView mv=new ModelAndView();
        List<Goods> goodsList = goodsService.findAll();
        mv.addObject("goodsList",goodsList);
        mv.setViewName("zhuye");

        return mv;
    }

    @RequestMapping("/delGoods")
    public ModelAndView delGoods(int gid){
        ModelAndView mv=new ModelAndView();
        int n = goodsService.delGoods(gid);
        if(n>0){
            //继续查询数据,跳转主页
            mv.setViewName("redirect:/findAll");
        } else{
            mv.addObject("error","删除出错了!");
            mv.setViewName("error"); //经过视图解析器,去指定位置 找到指定后缀的页面
        }
        return mv;
    }

    @RequestMapping("/addGoods")
    public ModelAndView addGoods(Goods goods){
        ModelAndView mv=new ModelAndView();
        int n = goodsService.addGoods(goods);
        if(n>0){
            //重新获取一次最新的数据,跳转到主页
            mv.setViewName("redirect:/findAll");
        } else{
            mv.addObject("error","添加出错了!");
            mv.setViewName("error");
        }
        return mv;
    }

    @RequestMapping("/findById")
    public ModelAndView findById(int gid){
        ModelAndView mv=new ModelAndView();
        Goods goods = goodsService.findById(gid);
        //把数据发送到页面中做展示---数据回显
        mv.addObject("goods",goods); //request域
        mv.setViewName("showGoods"); //请求转发
        return mv;
    }

    @RequestMapping("/updateGoods")
    public ModelAndView updateGoods(Goods goods){
        ModelAndView mv=new ModelAndView();
        int n = goodsService.updateGoods(goods);
        if(n>0){
            //重新获取一次最新的数据,跳转到主页
            mv.setViewName("redirect:/findAll");
        } else{
            mv.addObject("error","修改出错了!");
            mv.setViewName("error");
        }
        return mv;
    }

    @RequestMapping("/seach")
    public ModelAndView seach(String gname){
        ModelAndView mv=new ModelAndView();
        List<Goods> goodsList = goodsService.findByGname(gname);
        mv.addObject("goodsList",goodsList);
        mv.setViewName("zhuye");
        return mv;
    }
}

业务层

public interface GoodsService {
    List<Goods> findAll();
    Goods findById(int gid);
    List<Goods> findByGname(String gname);
    int delGoods(int gid);
    int addGoods(Goods goods);
    int updateGoods(Goods goods);
}
package com.zhan.service.impl;

import com.zhan.bean.Goods;
import com.zhan.dao.GoodsDao;
import com.zhan.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    GoodsDao goodsDao;
    @Override
    public List<Goods> findAll() {
        return goodsDao.selectAll();
    }

    @Override
    public Goods findById(int gid) {
        return goodsDao.selectById(gid);
    }

    @Override
    public List<Goods> findByGname(String gname) {
        return goodsDao.selectByGname(gname);
    }

    @Override
    public int delGoods(int gid) {
        return goodsDao.delete(gid);
    }

    @Override
    public int addGoods(Goods goods) {
        return goodsDao.insert(goods);
    }

    @Override
    public int updateGoods(Goods goods) {
        return goodsDao.update(goods);
    }
}

持久层

package com.zhan.dao;
import com.zhan.bean.Goods;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;
public interface GoodsDao {
    @Select("select * from goods")
    List<Goods> selectAll();

    @Select("select * from goods where gid=#{gid}")
    Goods selectById(int gid);

    @Select("select * from goods where gname like concat('%',#{gname},'%')")
    List<Goods> selectByGname(String gname);

    @Delete("delete from goods where gid=#{gid}")
    int delete(int gid);

    @Insert("insert into goods(gname,price,stock,supplier) values(#{gname},#{price},#{stock},#{supplier})")
    int insert(Goods goods);

    @Update("update goods set gname=#{gname} , price=#{price} ,stock=#{stock} ,supplier=#{supplier} where gid=#{gid}")
    int update(Goods goods);
}

登录拦截

判断是否为登录请求,是的话放行,否则继续判断session中是否用用户信息,有表示已登录放行,没有则拦截并强制跳转到登录页

public class MyInterceptor implements HandlerInterceptor{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String path = request.getServletPath();
        //判断是否为登录请求,是的话放行,否则继续判断session中是否用用户信息,有表示已登录放行,没有则拦截并强制跳转到登录页
        if (path.equals("/login")) {
            return true;
        } else {
            User user = (User) request.getSession().getAttribute("user");
            if (user != null) {
                return true;
            } else {
                response.sendRedirect("login.jsp");
                return false;
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值