昨天我们实现了登录功能,但是用的是模拟数据。今天我们要链接数据库整合Spirng+Mybatis,读取数据库中的真实数据,用来跟我们输入的userCode和userPassword进行对比,来判断用户名和密码是否正确。还需要进行一些其他的微调
项目的开发流程可以根据具体需求和项目规模有所不同,但通常包括以下主要步骤:
关于数据库的创建,通常在数据库设计阶段会创建数据库模式和表结构。但在实际开发中,有时也可以在后期根据需求进行数据库的调整和扩展。
这是因为,项目开发是一个迭代和持续改进的过程,需要我们不断地与团队成员者进行沟通和协作。
一般来说都是要提前设计好数据库表结构等,然后再去进行一个前后端的开发。在自己进行一个全新项目开发的时候呢,基本上是得按照上面的流程来。
运行Navicat for Mysql等数据库管理工具,导入我们项目资源中的数据库文件supermarket.sql。
ps:Navicat 是一款强大的数据库管理工具,用于管理和维护多种数据库系统,包括 MySQL、MariaDB、SQLite、SQL Server、Oracle 和 PostgreSQL 等。它为数据库开发人员和管理员提供了丰富的功能和工具,使他们能够更轻松地管理和操作数据库。
创建出supermarket数据库。
自动生成pojo类这个部分,我也是前面的文章有发布过的,可以访问查看一下
如何使用IDEA链接数据库并自动生成POJO类?_Stevedash的博客-CSDN博客如何实现
看到这里可能会有疑惑
其实我们前面的文章也有讲到的,在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代码如下:
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.steveDash.dao.UserMapper">
<select id="getUserByUserCode" parameterType="String" resultType="User">
select * from user where userCode=#{userCode}
select>
mapper>
这里的返回类型本来是要写全类限名,但是我们在Mybatis-config配置文件中编写了别名,因此这里我们可以直接写User。
按照我们前面讲的,这里应该还需要去mybatis-config里面注册好我们的mapper映射文件的地址吧?
但是呢,这里我们选择在spring-config中去写入配置Dao层,这样的话我们就不用一个一个的映射文件都要注册到配置文件中,这段代码它会自动扫描该包下的所有映射文件并且注册好。
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 {
@Resource
private UserMapper userMapper;
public UserMapper getUserMapper() {
return userMapper;
}
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Override
public 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中查看一下,是否开启了注解的代码
这种方式就是我们前几天学到的,依赖注入和IOC控制反转,由IOC容器创建对象,通过getBean的方式来获取实例对象。
UserService userService=(UserServiceImpl)context.getBean("userServiceImpl");
和
UserServiceImpl userService=(UserServiceImpl)context.getBean("userServiceImpl");
答案如下:
两种方式的效果是一样的,但第一种方式更符合依赖注入和面向接口编程的原则,因为它将userService
声明为接口类型,而不是具体的实现类型。这样做有助于降低耦合度,使代码更具灵活性。如果以后更改了UserService
的实现类,第一种方式无需修改,而第二种方式则需要修改。因此,第一种方式通常更好一些。
测试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 {
@Resource
private 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.jsp
model.addAttribute("error", "用户名或密码不正确");
return "login";
}
}else{
//登录失败就返回login.jsp
model.addAttribute("error", "用户名不正确");
return "login";
}
}
}
退出登录模块的设计,其实就是清除httpSession中的Session,然后进行判断若是Session中没有用户,那就判断回到登录页面,若有就跳转到主功能页面,这样子就可以完成一个退出的功能。
所以在完成退出模块设计前,要对我们刚刚实现的登录功能进行一个优化
在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.jsp
model.addAttribute("error", "用户名或密码不正确");
return "login";
}
}else{
//登录失败就返回login.jsp
model.addAttribute("error", "用户名不正确");
return "login";
}
}
所以我们还需要添加一个去到welcome页面的映射,因此还是在UserController中进行如下操作
新增/main映射到welcome.jsp页面
@RequestMapping(value="/main")
public String welcome(HttpSession session) {
if(session.getAttribute("user") == null){ //如果用户没有登录就直接来到main.html就回到login
return "redirect:/syserror";
}
else
return "welcome";
}
@RequestMapping("/syserror")//出错页面
public String sysError(){
return "syserror";
}
这里为什么不是直接使用welcome作为页面的映射呢?这是基于一个网络安全的考虑,因为直接让映射名和文件名一致的话,很容易就被黑客找到关键资源文件,进行渗透攻击修改后台数据,因此我们都是用关键词代表这个映射的操作。
我们这里还加入了一个判断,若是没有登陆就想直接访问main界面,就会自动重定向到syserror.jsp报错页面。
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2023/9/17
Time: 11:39
To 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分