【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统

刚刚学习完SSM整合 就想着自己写一个学生管理系统…
一.搭建环境
1.创建数据库和创建表
做学生管理系统 肯定是需要2张表的
第一就是User表 用来管理用户名和密码
第二就是Student表 用来存储学生的信息
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第1张图片
在这里插入图片描述
2.SSM环境搭建
创建一个Maven的web项目之后
首先导入我们之前自己整合的一些文件(这里我博客都有写,这里就不一一列举了)
pom.xml坐标文件,
applicationContext.xml配置文件,
jdbc.properties文件,
log4j.properties文件,
spring-mvc.xml配置文件,
web.xml配置文件(我经常忘记配这个文件 所以经常404~~)

【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第2张图片
创建我们的三层架构
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第3张图片

引入我们前端的页面
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第4张图片

创建测试类代码(主要做一些测试)
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第5张图片
二,项目流程分析
点击Tomcat运行>>index.jsp
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第6张图片
首页可以>>查询所有学生信息
我这边写了一个过滤器 如果没有登陆的话会让我们去登陆
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第7张图片
当然如果你是第一次访问的话还没有账号可以去注册>>点击还没账号?去注册
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第8张图片
我这边注册页面就写的比较简单 只有用户名和密码
当然如果你向后台提交空的用户名和密码还是会有相应的错误提示
记得在过滤器中一定要放行我们的登陆方法和注册方法
不然就会一直让你登陆 不会出现错误页面
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第9张图片
点击>>重新注册返回注册界面>>注册成功>>跳转到登陆界面
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第10张图片
输入正确的账号密码和验证码>>跳转到首页
这边红框中的两个功能我在后台是有逻辑判断的.但自动登陆的过滤器我这边就没有写
后期会补上~
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第11张图片
这时候已经是登陆状态了>>查询所有学生信息
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第12张图片
添加学生功能
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第13张图片
这边重置和返回功能我这边还没写 后期完善会补上~
修改学生功能
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第14张图片
修改学生这边会回显数据 所以在修改学生之前 我们实际上先要获取要修改的学生id
通过id去后台找到这个学生 再将找到的学生对象存到域对象中 获取回显数据
然后修改信息再提交到后台
删除学生功能
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第15张图片
为了防止用户误操作 删除信息之前给出相应的提示
当用户点击确定 再去操作删除功能
点击取消 则返回界面
同理删除选中按钮功能也会给出相应的提示
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第16张图片
接下来就是这个项目我个人认为比较复杂的功能
多条件查询和分页功能
思考一下,由于用户需要查询的条件不同的话,那么向我们后台传递的条件也可能是不同的
所以我们访问数据库时需要查询的sql语句也是不同的.
这个时候就需要用到Mybatis的动态sql
常见的Mybatis的动态sql写法是XML文件配置
我这个项目在Dao层都是用注解来开发的
那么注解是如何实现动态sql的呢?
我个人也在网上找了一些资料
然后向同学也取了取经,给出一种比较简单的用法.
在Dao层创建一个Provider的包 创建一个StudentDaoProvider 类

package com.itheima.dao.Provider;

import com.itheima.domain.Student;

public class StudentDaoProvider {

public String findStudentByPage(Student student) {
        String name = student.getName();
        String sex = student.getSex();
        String address = student.getAddress();

        String sql = "select * from student where 1 = 1";
        if(name!=null&&!"null".equalsIgnoreCase(name)&&!"".equals(name)){
            sql += " and name like '%"+name+"%' ";
        }
        if(sex!=null&&!"null".equalsIgnoreCase(sex)&&!"".equals(sex)){
            sql += " and sex = '"+sex+"' ";
        }
        if(address!=null&&!"null".equalsIgnoreCase(address)&&!"".equals(address)){
            sql += " and address = '"+address+"' ";
        }
        return sql;  
   }
}

这个类会返回一个sql语句 它会根据你从后台传来是Student对象取里面的属性值判断有没有内容
如果有内容就会给你判断 然后拼接你的sql
Dao层用到的是@SelectProvider注解
里面的参数是类型 加载类的字节码文件
方法 你要调用的是类中的哪个方法
也就相当于将类中返回的sql返回到这里执行查询条件了!

@SelectProvider(type = StudentDaoProvider.class,method = "findStudentByPage")
List findStudentByPage(Student student);

我们来看一下日志效果
比如我们就查询两个条件在这里插入图片描述
查询
在这里插入图片描述
红框中就是动态生成的sql 可以看到是两个参数并且会自动给我们带上分页的语句
返回的对象是一个
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第17张图片
接下来说一下分页功能
在JavaWeb阶段我们在做分页功能的时候其实是非常的繁琐的 需要很多参数
比如当前页 开始页码 每页要展示的条数 总页数 总条数
有时候还需要计算一些值
在Mybatis框架中就很好的为我们解决了这个问题
所以这可能就是Mybatis框架带来的魅力吧!
直接先上代码
配置分页插件

    
        
        
        
        
        
        
            
                
                    
                        dialect=mysql
                    
                
            
        
    

在查询语句前调用方法(传入当前页+每页显示的条数)两个参数

//设置分页相关参数   当前页+每页显示的条数
 PageHelper.startPage(pageNums,pageSizes);
 List studentList = studentService.findStudentByPage(student);
 //将查询条件存到request共享域中
 request.setAttribute("student",student);
//获得与分页相关参数
 PageInfo pageInfo = new PageInfo(studentList);

将返回的List集合封装到PageInfo这个类中
这个类很强大包括刚才提到的要计算的属性 这个类都统统给你计算好了
你只需要把这个list集合set进去 然后返回这个类给前端就可以了
可以看一下效果【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第18张图片
我为什么要把Student也放到共享域中呢? 其实是为了在查询条件出来结果的时候
能把查询条件也回显给用户
前台又是如何展示这个数据的呢?

 
                
                    
                    ${student.id}
                    ${student.name}
                    ${student.age}
                    ${student.sex}
                    ${student.date}
                    ${student.email}
                    ${student.address}
                    
                        修改 
                        删除
                    
                
  

分页条

分析
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第19张图片
判断我们当前页码是否等于当前页码 如果等于就给当前页码一个class="active"属性
当前页是深蓝色按钮~
判断当前页码是否小于等于1 如果小于等于1 就将上一页按钮禁用
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第20张图片
判断当前页码是否大于等于总页数 如果大于等于总页数 就将下一页按钮禁用
【SSM】Spring+SpringMVC+MyBatis整合之学生管理系统_第21张图片
尽管我们在前台对上一页和下一页进行了禁用
但当我们点击时它还会访问我们的方法
所以就会产生下一页没有数据的情况
所以我们需要在后台代码也进行判断
但是我们在分页之前又拿不到总页数的值 所以针对这个问题我就思考了一下
我们从前端可以传一个总页数的值在地址栏
在这里插入图片描述
可以看到我们总页数是2
下一页页码成了3
我们要的效果应该是
当我们当前页码大于总页数 就把总页数的值赋给当前页面
也就是说 if3>2 就2=2
因为我们下一页是需要将当前页面+1的
为了在index.jsp不出现查询语句的错误
写了一段我自己也非常嫌弃的判断

int pagess;
        if (pageNum==null||"".equals(pageNum)){
            pageNum="1";
        }
        if (pages==null||"".equals(pages)){
            int pageNums = Integer.parseInt(pageNum);
            pagess = pageNums+1;
        }else{
            pagess = Integer.parseInt(pages);
        }
        if (pageSize==null||"".equals(pageSize)){
            pageSize="5";
        }
        int pageNums = Integer.parseInt(pageNum);
        if (pageNums<=0){
            pageNums=1;
        }
        int pageSizes = Integer.parseInt(pageSize);
        if (pageNums>pagess){
            pageNums = pagess;
        }

我这个分页条就没有测试很多页会自动伸缩的功能 所以后期可能还会改进~

controller>>StudentController

package com.itheima.controller;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.domain.Student;
import com.itheima.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Controller
public class StudentController {

    @Autowired
    private StudentService studentService;

    /**
     * 查找学生 条件查询
     * */
    @RequestMapping("/findStudentByPage")
    public ModelAndView findStudentByPage(HttpServletRequest request,ModelAndView modelAndView,String pageNum,String pageSize,String pages,Student student/*String name,String sex ,String address*/){
        int pagess;
        if (pageNum==null||"".equals(pageNum)){
            pageNum="1";
        }
        if (pages==null||"".equals(pages)){
            int pageNums = Integer.parseInt(pageNum);
            pagess = pageNums+1;
        }else{
            pagess = Integer.parseInt(pages);
        }
        if (pageSize==null||"".equals(pageSize)){
            pageSize="5";
        }
        int pageNums = Integer.parseInt(pageNum);
        if (pageNums<=0){
            pageNums=1;
        }
        int pageSizes = Integer.parseInt(pageSize);
        if (pageNums>pagess){
            pageNums = pagess;
        }
        //设置分页相关参数   当前页+每页显示的条数
        PageHelper.startPage(pageNums,pageSizes);
        List studentList = studentService.findStudentByPage(student);
        //将查询条件存到request共享域中
        request.setAttribute("student",student);
        //获得与分页相关参数
        PageInfo pageInfo = new PageInfo(studentList);
        modelAndView.addObject("pageInfo",pageInfo);
        modelAndView.setViewName("/list.jsp");
        return modelAndView;
    }


    /**
     * 添加学生
    * */
    @RequestMapping("/addStudent")
    public String addStudent(Student student){
        studentService.addStudent(student);
        return "redirect:/findStudentByPage";
    }

    /**
     *查找学生
    * */
    @RequestMapping("/findStudentById")
    public String findStudentById(int id,HttpServletRequest request)  {
        Student student = studentService.findStudentById(id);
        request.setAttribute("student",student);
        return "forward:/update.jsp";
    }


    /**
     * 修改学生
    * */
    @RequestMapping("/updateStudent")
    public String updateStudent(Student student){
        studentService.updateStudent(student);
        return "redirect:/findStudentByPage";
    }

    /**
     * 删除学生
    * */
    @RequestMapping("/deleteStudentById")
    public String deleteStudentById(int id){
        studentService.deleteStudentById(id);
        return "redirect:/findStudentByPage";
    }

    /**
     * 删除选中学生
    * */
    @RequestMapping("/deleteSelectedStudent")
    public String deleteSelectedStudent(int[] uid){
        studentService.deleteSelectedStudent(uid);
        return "redirect:/findStudentByPage";

    }
}

controller>>UserController

package com.itheima.controller;
import com.itheima.domain.User;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    /**
     * 登陆
     * */
    @RequestMapping("/login")
    public ModelAndView login(User user,String checkCode,HttpServletRequest request,HttpServletResponse response) {
        ModelAndView modelAndView = new ModelAndView();
        HttpSession session = request.getSession();
        String checkCode_session = (String) session.getAttribute("checkCode_session");
        session.removeAttribute("checkCode_session");
        //判断验证码
        if (checkCode_session != null && checkCode_session.equalsIgnoreCase(checkCode)) {
            User user1 = userService.findUsernameAndPassword(user);
            if (user1 == null) {
                modelAndView.addObject("login_error", "用户名密码错误");
                modelAndView.setViewName("/login.jsp");
                return modelAndView;
            } else {
                //登录成功 获取用户是否勾选了保存用户名
                String check_user = request.getParameter("check_user");
                //获取用户是否勾选了自动登陆
                String check_auto = request.getParameter("check_auto");
                if ("true".equalsIgnoreCase(check_user)) {
                    //说明用户勾选了记住用户名
                    //将用户名保存到Cookie中
                    Cookie cookie_uu = new Cookie("uu_name", user1.getUsername());
                    cookie_uu.setMaxAge(60 * 60 * 24 * 7);
                    cookie_uu.setPath(request.getContextPath());
                    response.addCookie(cookie_uu);
                }
                if ("true".equalsIgnoreCase(check_auto)){
                    //说明用户勾选了自动登陆
                    //将用户名和密码保存到Cookie
                    Cookie cookie_auto = new Cookie("auto_login", user1.getUsername() + "#" + user1.getPassword());
                    cookie_auto.setMaxAge(60*60*24*7);
                    cookie_auto.setPath(request.getContextPath());
                    response.addCookie(cookie_auto);
                }
                //将用户信息存入session
                session.setAttribute("user1",user1);
                modelAndView.setViewName("/index.jsp");
                return modelAndView;
            }
        }else {
            session.setAttribute("cc_error","验证码错误");
            modelAndView.setViewName("redirect:/login.jsp");
            return modelAndView;
        }
    }
    /**
     * 注册
     * */
    @RequestMapping("/register")
    public ModelAndView register(ModelAndView modelAndView,String username, String password){
        if (username==null||username.equals("")&&password==null||password.equals("")){
            //如果用户名为空 返回错误消息
            modelAndView.addObject("error","用户名或密码为空");
            modelAndView.setViewName("forward:/error.jsp");
            return modelAndView;
        }
        userService.registerUser(username,password);
        modelAndView.setViewName("forward:/login.jsp");
        return modelAndView;
    }
    /**
     * 验证码
    * */
    @RequestMapping("/checkCode")
    public void CheckCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //服务器通知浏览器不要缓存
        response.setHeader("pragma","no-cache");
        response.setHeader("cache-control","no-cache");
        response.setHeader("expires","0");
        //在内存中创建一个长100,宽40的图片,默认黑色背景
        //参数一:长
        //参数二:宽
        //参数三:颜色
        int width = 100;
        int height = 40;
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        //获取画笔
        Graphics g = image.getGraphics();
        //设置画笔颜色为灰色
        g.setColor(Color.GRAY);
        //填充图片
        g.fillRect(0,0, width,height);
        //产生4个随机验证码,12Ey
        String checkCode_session = getCheckCode();
        //将验证码放入HttpSession中
        request.getSession().setAttribute("checkCode_session",checkCode_session);
        //设置画笔颜色为黄色
        g.setColor(Color.YELLOW);
        //设置字体的小大
        g.setFont(new Font("黑体", Font.BOLD,26));
        //向图片上写入验证码
        g.drawString(checkCode_session,25,30);
        //将内存中的图片输出到浏览器
        //参数一:图片对象
        //参数二:图片的格式,如PNG,JPG,GIF
        //参数三:图片输出到哪里去
        ImageIO.write(image,"PNG",response.getOutputStream());
    }
    /**
     * 产生4位随机字符串
     */
    private String getCheckCode() {
        String base = "0123456789ABCDEFGabcdefg";
        int size = base.length();
        Random r = new Random();
        StringBuffer sb = new StringBuffer();
        for(int i=1;i<=4;i++){
            //产生0到size-1的随机值
            int index = r.nextInt(size);
            //在base字符串中获取下标为index的字符
            char c = base.charAt(index);
            //将c放入到StringBuffer中去
            sb.append(c);
        }
        return sb.toString();
    }
}

dao>>StudentDao

package com.itheima.dao;

import com.itheima.dao.Provider.StudentDaoProvider;
import com.itheima.domain.Student;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface StudentDao {

    @Select("select * from student")
    List findAllStudent();

    @Insert("insert into student Values(null,#{name},#{age},#{sex},#{date},#{email},#{address})")
    Integer addStudent(Student student);

    @Select("select * from student where id = #{id}")
    Student findStudentById(int id);

    @Update("update student set name=#{name},age=#{age},sex=#{sex},date=#{date},email=#{email},address=#{address}where id=#{id}")
    void updateStudent(Student student);

    @Delete("delete from student where id = #{id}")
    void deleteStudentById(int id);

    @SelectProvider(type = StudentDaoProvider.class,method = "findStudentByPage")
    List findStudentByPage(Student student);
}

dao>>UserDao

package com.itheima.dao;


import com.itheima.domain.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;

@Repository
public interface UserDao {

    @Insert("insert into user values(null,#{username},#{password})")
    public  void registerUser(@Param("username")String username, @Param("password")String password);


    @Select("select * from user where username = #{username} and password = #{password}")
    User findUsernameAndPassword(User user);
}

domain实体类(忽略)

interceptor>>过滤器

package com.itheima.interceptor;

import com.itheima.domain.User;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class PrivilegeInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user1");
        if (user==null){
            //没有登陆
            response.sendRedirect(request.getContextPath()+"/login.jsp");
            return false;

        }
        return true;
    }
}

service>>impl>>StudentServiceImpl

package com.itheima.service.impl;

import com.itheima.dao.StudentDao;
import com.itheima.domain.Student;
import com.itheima.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentDao studentDao;

    @Override
    public List findAllStudent() {
        return studentDao.findAllStudent();
    }

    @Override
    public void addStudent(Student student) {
        studentDao.addStudent(student);

    }

    @Override
    public Student findStudentById(int id) {
        return studentDao.findStudentById(id);
    }

    @Override
    public void updateStudent(Student student) {
        studentDao.updateStudent(student);
    }

    @Override
    public void deleteStudentById(int id) {
        studentDao.deleteStudentById(id);
    }

    @Override
    public void deleteSelectedStudent(int[] uid) {
        for (int id : uid) {
            studentDao.deleteStudentById(id);
        }
    }

    @Override
    public List findStudentByPage(Student student) {
        return studentDao.findStudentByPage(student);
    }


}

user>>impl>>UserServiceImpl

package com.itheima.service.impl;

import com.itheima.dao.UserDao;
import com.itheima.domain.User;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    public void registerUser(String username, String password) {

        userDao.registerUser(username,password);
    }

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

三.项目总结
整个学生信息管理系统就这样写完了…其实不算是很复杂…
因为之前也写过Servlet版的…
所以在使用SSM整合的时候…
其实Dao层很多代码非常的简洁.都是框架帮我们完成…
之前我们每个功能都需要写一个Servlet…
SpringMVC的话只需要写方法就好了…
使用注解开发效率也会很高…
我已经将源码放到我的码云上面
码云地址:https://gitee.com/gubingkun/ssm_student_manage.git

以上内容自己整理 如有不正确的地方 欢迎批评指正~

Java笔记-坤坤

你可能感兴趣的:(Java)