《超市订单管理系统》(第二天) 基于SSM框架的Web项目开发
昨天我们实现了登录功能,但是用的是模拟数据。今天我们要链接数据库整合Spirng+Mybatis,读取数据库中的真实数据,用来跟我们输入的userCode和userPassword进行对比,来判断用户名和密码是否正确。还需要进行一些其他的微调
今日目标:链接数据库完成以下模块设计
- 完成登录模块(登录页面设计+登录功能)
- 完成用户退出模块
项目的开发流程(一般来说)
项目的开发流程可以根据具体需求和项目规模有所不同,但通常包括以下主要步骤:
- 需求分析和规划:
- 理解项目的需求和目标。
- 制定项目计划和时间表。
- 确定项目的范围和功能。
- 数据库设计:
- 根据项目需求设计数据库结构,包括表和关系。
- 创建数据库模式和表结构。
- 确保数据库的正常运行和性能。
- 后端开发:
- 开发后端应用程序,包括业务逻辑和数据访问层。
- 集成数据库,实现数据的增删改查操作。
- 编写 API 和服务端逻辑。
- 前端开发:
- 开发前端界面和用户体验。
- 使用 HTML、CSS、JavaScript 等前端技术。
- 与后端进行通信,调用后端提供的 API。
- 集成和测试:
- 集成前后端组件,确保它们协同工作。
- 进行单元测试和集成测试,检查功能和性能。
- 解决和修复问题。
- 部署和上线:
- 部署应用程序到生产环境。
- 配置服务器和数据库。
- 监控应用程序性能,并处理生产问题。
- 维护和优化:
- 定期监控和维护应用程序,确保其稳定性。
- 进行性能优化,提高应用程序效率。
- 根据用户反馈和需求进行功能扩展和更新。
- 文档和培训:
- 编写项目文档,包括用户手册和开发文档。
- 培训用户和开发团队,确保他们了解项目和工具。
关于数据库的创建,通常在数据库设计阶段会创建数据库模式和表结构。但在实际开发中,有时也可以在后期根据需求进行数据库的调整和扩展。
这是因为,项目开发是一个迭代和持续改进的过程,需要我们不断地与团队成员者进行沟通和协作。
一般来说都是要提前设计好数据库表结构等,然后再去进行一个前后端的开发。在自己进行一个全新项目开发的时候呢,基本上是得按照上面的流程来。
一、开发前准备
①数据库准备:
运行Navicat for Mysql等数据库管理工具,导入我们项目资源中的数据库文件supermarket.sql。
ps:Navicat 是一款强大的数据库管理工具,用于管理和维护多种数据库系统,包括 MySQL、MariaDB、SQLite、SQL Server、Oracle 和 PostgreSQL 等。它为数据库开发人员和管理员提供了丰富的功能和工具,使他们能够更轻松地管理和操作数据库。
创建出supermarket数据库。
②查看用户表中的所有字段,我们要确保我们的类中的属性和表中的字段名一致,一 一对应映射,这样涉及到前后端传值的时候就比较清晰,不会太迷糊,降低出错的风险。
二、开始完善登录功能
自动生成pojo类这个部分,我也是前面的文章有发布过的,可以访问查看一下
如何使用IDEA链接数据库并自动生成POJO类?_Stevedash的博客-CSDN博客如何实现
①确保正确的项目结构和资源文件的齐全
②使用idea自带链接数据库生成数据库表的pojo类与pojo包下,然后进行检查。
③dao层(dao包)下创建Mybatis的映射文件和接口,我们这里是对user表进行的操作,那么就是UserMapper接口和UserMapper.xml(也就是Mybatis映射文件)
看到这里可能会有疑惑
为什么dao层中的UserMapper接口要和UserMapper.xml的命名一样呢?
其实我们前面的文章也有讲到的,在MyBatis这样的持久化框架中,UserMapper接口和UserMapper.xml的命名之间通常需要保持一致,这是为了确保MyBatis能够正确地将接口与XML配置文件关联起来并执行相应的SQL操作。
UserMapper接口代码如下:
package com.steveDash.dao;import com.steveDash.pojo.User;public interface UserMapper {public User getUserByUserCode(String userCode);
}
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.steveDash.dao.UserMapper"><!--根据账户名userCode查询user表,返回一个User类型对象记录--><select id="getUserByUserCode" parameterType="String" resultType="User">select * from user where userCode=#{userCode}</select>
</mapper>
这里的返回类型本来是要写全类限名,但是我们在Mybatis-config配置文件中编写了别名,因此这里我们可以直接写User。
按照我们前面讲的,这里应该还需要去mybatis-config里面注册好我们的mapper映射文件的地址吧?
但是呢,这里我们选择在spring-config中去写入配置Dao层,这样的话我们就不用一个一个的映射文件都要注册到配置文件中,这段代码它会自动扫描该包下的所有映射文件并且注册好。
④根据分层思想,在Service层下,编写UserService接口。
UserService接口中添加查询用户的方法getUserByUserCode()
package com.steveDash.service;import com.steveDash.pojo.User;public interface UserService {public User getUserByUserCode(String userCode);
}
(使用给接口生成实现类的快捷键ALT+ENTER)编写业务实现类UserServiceImpl,
package com.steveDash.service;import com.steveDash.dao.UserMapper;
import com.steveDash.pojo.User;
import org.springframework.stereotype.Service;import javax.annotation.Resource;@Service("userServiceImpl")
public class UserServiceImpl implements UserService {@Resourceprivate UserMapper userMapper;public UserMapper getUserMapper() {return userMapper;}public void setUserMapper(UserMapper userMapper) {this.userMapper = userMapper;}@Overridepublic User getUserByUserCode(String userCode) {try{return userMapper.getUserByUserCode(userCode);}catch (RuntimeException e){e.printStackTrace();throw e;}}
}
代码说明:在这里我们将dao中的接口UserMapper
的实例注入到UserServiceImpl,并调用它的getUserByUserCode方法查询数据
所以这里一定要添加getter,setter方法!!! 因为依赖注入:Spring框架通过setter方法来注入userMapper
的实例
因为我们是使用注解的方式,所以我们需要去Spring-config.xml中查看一下,是否开启了注解的代码
⑤打开controller包下的,UserController,进行登录方法doLogin()的修改
这种方式就是我们前几天学到的,依赖注入和IOC控制反转,由IOC容器创建对象,通过getBean的方式来获取实例对象。
这里请思考一下:下面这俩种写法效果都是一样的,那么为什么我们要选择第一种呢?
UserService userService=(UserServiceImpl)context.getBean("userServiceImpl");
和
UserServiceImpl userService=(UserServiceImpl)context.getBean("userServiceImpl");
答案如下:
两种方式的效果是一样的,但第一种方式更符合依赖注入和面向接口编程的原则,因为它将userService
声明为接口类型,而不是具体的实现类型。这样做有助于降低耦合度,使代码更具灵活性。如果以后更改了UserService
的实现类,第一种方式无需修改,而第二种方式则需要修改。因此,第一种方式通常更好一些。
⑥运行一下tomcat服务
测试1首先进行正确的账号密码输入测试:
可以看到正常运行,并且没有错误。
还需要进行其他情况的测试2,比如用户名不存在的情况admin1,预期输出结果:用户名错误
与预期结果一致。
那么在进行登录测试3:账号正确,密码错误的情况。预期结果:用户名或者密码错误
与预期结果一致。
⑦代码反思优化,采用依赖注入的方式
上面的代码还有优化的空间,因为
蓝色标注的这一段,我们只是为了获取userServiceImpl的Bean,所以我们可以使用依赖注入的方式,代码如下:
package com.steveDash.controller;import com.steveDash.pojo.User;
import com.steveDash.service.UserService;
import com.steveDash.service.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;import javax.annotation.Resource;
import javax.servlet.http.HttpSession;@Controller
public class UserController {@Resourceprivate UserService userService;@RequestMapping(value="/login")public String showLoginPage(){System.out.println("进入登录页面");return "login";}@RequestMapping(value="/dologin")public String doLogin(@RequestParam("userCode") String userCode, @RequestParam("userPassword") String userPassword, Model model, HttpSession session){//读取用户和密码System.out.println("帐号和密码是"+userCode+"-"+userPassword);User user=userService.getUserByUserCode(userCode);if(user!=null){if(userPassword.equals(user.getUserPassword())){session.setAttribute("userCode",userCode);//添加session值return "welcome"; //密码正确就去welcome.jsp}else{//登录失败就回到login.jspmodel.addAttribute("error", "用户名或密码不正确");return "login";}}else{//登录失败就返回login.jspmodel.addAttribute("error", "用户名不正确");return "login";}}}
⑧重新运行服务,看看需求是否满足,登录功能是否正常?
三、完成退出模块
退出登录模块的设计,其实就是清除httpSession中的Session,然后进行判断若是Session中没有用户,那就判断回到登录页面,若有就跳转到主功能页面,这样子就可以完成一个退出的功能。
所以在完成退出模块设计前,要对我们刚刚实现的登录功能进行一个优化
①我们Session中只存了用户的账号名:userCode,可是我们其他页面或许需要user用户的其他参数,因此我们修改Session中存储的值,修改为存储user用户
在UserController.java找到doLogin并且进行修改
@RequestMapping(value="/dologin")
public String doLogin(@RequestParam("userCode") String userCode, @RequestParam("userPassword") String userPassword, Model model, HttpSession session){//读取用户和密码System.out.println("帐号和密码是"+userCode+"-"+userPassword);User user=userService.getUserByUserCode(userCode);if(user!=null){if(userPassword.equals(user.getUserPassword())){session.setAttribute("user",user);//添加session值,修改成存入user对象return "redirect:/main"; //密码正确就去welcome.jsp(main是welcome页面的映射)}else{//登录失败就回到login.jspmodel.addAttribute("error", "用户名或密码不正确");return "login";}
}else{//登录失败就返回login.jspmodel.addAttribute("error", "用户名不正确");return "login";}
}
所以我们还需要添加一个去到welcome页面的映射,因此还是在UserController中进行如下操作
新增/main映射到welcome.jsp页面
@RequestMapping(value="/main")
public String welcome(HttpSession session) {if(session.getAttribute("user") == null){ //如果用户没有登录就直接来到main.html就回到loginreturn "redirect:/syserror";}elsereturn "welcome";
}@RequestMapping("/syserror")//出错页面public String sysError(){return "syserror";}
这里为什么不是直接使用welcome作为页面的映射呢?这是基于一个网络安全的考虑,因为直接让映射名和文件名一致的话,很容易就被黑客找到关键资源文件,进行渗透攻击修改后台数据,因此我们都是用关键词代表这个映射的操作。
我们这里还加入了一个判断,若是没有登陆就想直接访问main界面,就会自动重定向到syserror.jsp报错页面。
<%--Created by IntelliJ IDEA.User: AdministratorDate: 2023/9/17Time: 11:39To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title>
</head>
<body>
<h1>请登录后再访问该页面!</h1>
<a href="${pageContext.request.contextPath }/login">返回</a>
</body>
</html>
**
**
上面这样子就完善了登录页面的操作,并且设置了主页welcome的main映射,然后还编写了未登录就访问主页的错误提示。
②编写退出操作
代码如下:
@RequestMapping(value = "/logout")
public String logout(HttpSession session){session.removeAttribute("user");//清除掉Session 中的user值return "redirect:/login";//返回login.jsp
}
使用removeAttribute()方法清除掉session中存储的user对象,然后重定向到登录界面即可完成退出操作。
重新运行服务看看效果
可以看到了退回了登录界面,退出功能也完成了。
总结
今天是综合项目超市订单管理系统开发的第二天,我们完善了登录的功能模块和退出的功能模块。项目现在已经整合了SpringMVC和Spring、以及Mybatis,算是SSM的综合项目了,接下里的就是把之前学习过的知识,应用在这个项目中。还讲解了一下项目的开发流程,希望通过今天的学习,希望各位读者可以对整体的项目开发流程有个大致的了解,为框架开发打下坚实基础。
想要跟着学习的可以去我的资源里面找对应的文件下载,我的md文件也会发上去,项目文件会上传可以自己跟着学习一下。(ps:前俩天有事,所以今天补上)
作者:Stevedash
发表于:2023年9月17日 13点23分