SpringBoot+SpringMVC+Mybatis+SpringSecurity实现搜索、删除学生选课信息以及教师端和管理端权限控制

1.引言

经过一段时间的SpringBoot框架的学习,越来越发觉它的强大,同时通过自主独立的完成作业也让我对这个框架的了解越来越深厚,虽然完成的过程会有比较多的bug,不够解决bug的过程也可以学到很多东西。

2.要求

某学生和课程的ER图如下图所示,根据ER图创建数据库表,往数据库表中添加若干测试数据,用SpringBoot+SpringMVC+Mybatis完成如下功能:
在这里插入图片描述
在第二次作业的基础上,增加SpringSecurity框架,并在数据库创建用户表(users)和权限表(roles),用户表和权限表之间是多对多关系。权限类型有教师权限、管理员权限 , 教师权限仅可查看所有的学生选课,管理员权限可删除学生的选课及根据用户的姓名后查询该用户所选的课程。并提供注册功能和登录功能,注册用户的数据存到user表中。

3.实现效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.数据库结构

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

5.后端项目结构

在这里插入图片描述
在这里插入图片描述

6.后端代码

Controller层

package com.hnucm.c202001090120.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;

/**
 * 报错实现错误代码的处理
 *
 */
@Controller
public class MyExceptionAdvice implements ErrorController {
    @Autowired
    HttpServletRequest request;
    @RequestMapping("/error")
    public String getErrorPath() {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        switch (statusCode) {
            case 404:
                return "fail.html";
            case 400:
                return "fail.html";
            default:
                return "fail.html";
        }
    }
}
package com.hnucm.c202001090120.controller;
import com.hnucm.c202001090120.pojo.StudentZHH;
import com.hnucm.c202001090120.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.yaml.snakeyaml.events.Event;
@Controller
public class StudentController {
    @Autowired
    StudentService studentService;
    @RequestMapping("studentlist")
    public String studentlist(Model model) {
        model.addAttribute("studentlist", studentService.findAllStudent());
        return "studentlist.html";
    }
    @RequestMapping("deletepersonbyid")
    public String deletepersonbyid(int id) {
        System.out.println(id+"deletepersonbyid");
        studentService.deletePersonById(id);
        return "redirect:/studentlist";
    }
    @RequestMapping("searchstudent")
    public String search(Model model, StudentZHH student) {

//        model.addAttribute("name", student.getName());
//        model.addAttribute("id", student.getId());
//        model.addAttribute("classname", student.getClassname());
        System.out.println(student+"searchstudent");
        return "searchstudent.html";

    }

    @RequestMapping("searchstudentcommit")
    public String Searchstudentcommit(Model model,String name) {
//        System.out.println(id+"searchstudentcommit");

        if(name!=null&&!name.equals(" ")){
            model.addAttribute("resultlist",  studentService.searStudent(name));
//            System.out.println(1);

            return "result.html";
        }
        model.addAttribute("error","未查询到响应的数据,请您检查输入的学生信息是否正确~");
        System.err.println("error");
        return "fail.html";

    }



}

package com.hnucm.c202001090120.controller;

import com.hnucm.c202001090120.pojo.UserZHH;
import com.hnucm.c202001090120.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;
@Controller
public class UserController {
    @Autowired
    UserService userService;
    @RequestMapping("register")
    public  String addUser(Model model, UserZHH person) {
//        model.addAttribute("id", person.getId());
        model.addAttribute("username", person.getUsername());
        model.addAttribute("password", person.getPassword());
        model.addAttribute("users_rolesZHH", person.getUsers_rolesZHH());
        return "register.html";
    }
    @RequestMapping("addusercommit")
    public String addusercommit(UserZHH person) {
        try {
            userService.addUser(person);
            System.out.println("可以正常执行");
            System.out.println(person);
            return "redirect:/login1";//注册成功则返回登录页面
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("主键错误");
        }return "false";

    }
    @RequestMapping("login1")
    public String login1() {

        return "login1.html";

    }
    @RequestMapping("mylogout")
    public String mylogout() {

        return "mylogout.html";

    }
    @RequestMapping("findAlluser")
    @ResponseBody
    public List<UserZHH> findAlluser() {

        List<UserZHH> userList = userService.findAllUser();
        return  userList;
    }
}

dao层

package com.hnucm.c202001090120.dao;

import com.hnucm.c202001090120.pojo.CourseZHH;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface CourseMapper {
    public List<CourseZHH> findCourseById(Integer studentid);

}

package com.hnucm.c202001090120.dao;

import com.hnucm.c202001090120.pojo.GradeZHH;
import com.hnucm.c202001090120.pojo.StudentZHH;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface GradeMapper {
    public List<GradeZHH> findGradeById(Integer gradeid);

}

package com.hnucm.c202001090120.dao;

import com.hnucm.c202001090120.pojo.RolesZHH;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface RoleMapper {


    public  int addrole(RolesZHH rolesZHH);
    public    RolesZHH findRolesByname(String username);


}

package com.hnucm.c202001090120.dao;

import com.hnucm.c202001090120.pojo.StudentZHH;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface StudentMapper {
    public List<StudentZHH> findStudentByinfoId();
    public int deletePersonById(Integer id);
    public List<StudentZHH> searStudent(String name);
}

package com.hnucm.c202001090120.dao;

import com.hnucm.c202001090120.pojo.UserZHH;
import com.hnucm.c202001090120.pojo.Users_RolesZHH;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface UserMapper {
    public int addUser(UserZHH userZHH);
    public List<UserZHH> findAllUser();
    public UserZHH findUserByUsername(String username);
    public  int addUsersRoles(Users_RolesZHH users_rolesZHH);


}

pojo层

package com.hnucm.c202001090120.pojo;

import lombok.Data;

import java.util.List;

@Data
public class CourseZHH {

    private int id;
    private String name;
    private  int studentid;
    private List<GradeZHH> gradeZHHList;

}

package com.hnucm.c202001090120.pojo;

import lombok.Data;

import java.util.List;

@Data
public class GradeZHH {
    private int id;
    private String name;
    private int number;
    private int grade;

}

package com.hnucm.c202001090120.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class RolesZHH {
    private int id;
    private String name;
    private Users_RolesZHH users_rolesZHH;

}

package com.hnucm.c202001090120.pojo;

import lombok.Data;

import java.util.List;

@Data
public class StudentZHH {
    private int id;
    private String name;
    private String classname;
    private List<CourseZHH> courseZHHList;

}

package com.hnucm.c202001090120.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
//resultType的类需要有空参构造,手动加一个或者加上@NoArgsConstructor注解即可
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Users_RolesZHH {
    private int id;
    private String username;
    private int roleid;
}

package com.hnucm.c202001090120.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserZHH {
    private int id;
    private String username;
    private String password;
    private  RolesZHH rolesZHH;
    private Users_RolesZHH users_rolesZHH;

}

service层

package com.hnucm.c202001090120.service.impl;
import com.hnucm.c202001090120.dao.StudentMapper;
import com.hnucm.c202001090120.pojo.StudentZHH;
import com.hnucm.c202001090120.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class StudentServicelmpl implements StudentService {

   @Autowired
    StudentMapper studentMapper;
    @Override
    public List<StudentZHH> findAllStudent() {
        return studentMapper.findStudentByinfoId();
    }
    @Override
    public int deletePersonById(Integer id) {

        return studentMapper.deletePersonById(id);
    }

    @Override
    public List<StudentZHH> searStudent(String name) {

        return studentMapper.searStudent(name);

    }



}

package com.hnucm.c202001090120.service.impl;

import com.hnucm.c202001090120.dao.UserMapper;
import com.hnucm.c202001090120.dao.RoleMapper;
import com.hnucm.c202001090120.pojo.RolesZHH;
import com.hnucm.c202001090120.pojo.UserZHH;
import com.hnucm.c202001090120.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServicelmpl implements UserService {
    @Autowired
    UserMapper userMapper;
    @Autowired
    RoleMapper roleMapper;
    @Override
    public int addUser(UserZHH userZHH) {
        int result1= userMapper.addUser(userZHH);
        int result2=  userMapper.addUsersRoles(userZHH.getUsers_rolesZHH());
        System.out.println(result2);
        System.out.println(result1);
        if(result2>0&&result1>0)
        {

            return result1;
        }
        return 0;
    }
    @Override
    public List<UserZHH> findAllUser() {
        return userMapper.findAllUser();

    }
    @Override
    public UserZHH findUserByUsername(String username) {
        return userMapper.findUserByUsername(username);
    }

    @Override
    public RolesZHH  findRolesByid(String username) {
        return roleMapper.findRolesByname(username);
    }
}

package com.hnucm.c202001090120.service;

import com.hnucm.c202001090120.pojo.StudentZHH;
import java.util.List;
public interface StudentService {
    public List<StudentZHH> findAllStudent();

    public int deletePersonById(Integer id);
    public List<StudentZHH> searStudent(String name);

}

package com.hnucm.c202001090120.service;

import com.hnucm.c202001090120.pojo.RolesZHH;
import com.hnucm.c202001090120.pojo.UserZHH;
import java.util.List;
public interface UserService {
    public int addUser(UserZHH userZHH);
    public List<UserZHH> findAllUser();
    public UserZHH findUserByUsername(String username);
    public RolesZHH findRolesByid(String username);
}

utils层

package com.hnucm.c202001090120.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity
public class MySercurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    MyUserService myUserService;
    @Override
    //认证-》从数据库获取用户 密码进行验证
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
    auth.userDetailsService(myUserService).passwordEncoder(new BCryptPasswordEncoder());
    }
    @Bean
    PasswordEncoder passwordEncoder()
    {
        return new BCryptPasswordEncoder();
    }
    //授权
    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.authorizeHttpRequests()//拦截所有请求
                .antMatchers("/login1","/register","/mylogout","/findAlluser","/addusercommit").permitAll()//放行某些接口
                .antMatchers("/studentlist").hasAuthority("teacher")
                .antMatchers("/deletepersonbyid","/searchstudent","/searchstudentcommit").hasAuthority("admin")//对页面配置权限
                .anyRequest().authenticated();//其他的接口拦截
        http.formLogin()
                .loginPage("/login1")//login 自己写的页面 默认需要权限
                .loginProcessingUrl("/user/login")//登录注册
                .and()
                .logout()
                .logoutUrl("/logout");
        //json接口配置
        http.cors();
        http.csrf().disable();
    }
}

package com.hnucm.c202001090120.utils;
import com.hnucm.c202001090120.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;

@Service
public class MyUserService implements UserDetailsService {
   //重写登录逻辑   username-》登录页面输入的用户名
    //第一步:数据库user (id,username,password)  username去数据库中查询用户select *from user where usename =? 0 1 多条(注册让username不能重复)
    //如果是0条throws UsernameNotFoundExeception 如果是1条 从用户信息取得密码
    //第二步根据username 去查询权限roles(id name) user表roles表多对多 中间表
  @Autowired
  UserService userService;
    @Override
    public UserDetails loadUserByUsername(String username1) throws UsernameNotFoundException {
//        String password="123456";

            String password = userService.findUserByUsername(username1).getPassword();//从数据库取密码
            System.out.println(password);

            String username = userService.findRolesByid(username1).getName();//从数据库取权限
            System.out.println(username);
            if (username == null) {


            }
            GrantedAuthority authority1 = new SimpleGrantedAuthority("teacher");
            GrantedAuthority authority2 = new SimpleGrantedAuthority("admin");
            List<GrantedAuthority> authorityList = new ArrayList<>();
            if (username.equals("teacher")) {
                authorityList.add(authority1);
            }
            if (username.equals("admin")) {
                authorityList.add(authority1);
                authorityList.add(authority2);
            }
            return new User(username, new BCryptPasswordEncoder().encode(password), authorityList);
        }


}

Mapper层

<?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.hnucm.c202001090120.dao.CourseMapper">
    <!--    id接口中方法的名字   resultType返回值的类型 集合对对象 可以省略集合 -->
    <!--    resultmap 数据库字段和实体类字段不一致-->
    <select id="findCourseById"
            resultMap="courseGrade"
            parameterType="Integer">
        select * from course_zhh where studentid = #{studentid}

    </select>
    <resultMap id="courseGrade" type="com.hnucm.c202001090120.pojo.CourseZHH">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <collection property="gradeZHHList"
                    ofType="com.hnucm.c202001090120.pojo.GradeZHH"
                    column="id"
                    select="com.hnucm.c202001090120.dao.GradeMapper.findGradeById">
        </collection>
        <!--            级联查询-->

    </resultMap>




</mapper>
<?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.hnucm.c202001090120.dao.GradeMapper">
    <!--    id接口中方法的名字   resultType返回值的类型 集合对对象 可以省略集合 -->
    <!--    resultmap 数据库字段和实体类字段不一致-->
    <select id="findGradeById"
            resultType="com.hnucm.c202001090120.pojo.GradeZHH"
            parameterType="Integer">
        select *
        from grade_zhh
        where id in (select grade_id
                     from course_grade_zhh
                     where course_id =#{course_id}
        )
    </select>
</mapper>
<?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.hnucm.c202001090120.dao.RoleMapper">
    <!--    id接口中方法的名字   resultType返回值的类型 集合对对象 可以省略集合 -->
    <!--    resultmap 数据库字段和实体类字段不一致-->
    <select id="findRolesByname"
            resultType="com.hnucm.c202001090120.pojo.RolesZHH"
            parameterType="String">
        select *
        from roles_zhh
        where id in (select roleid
                     from usersroles_zhh
                     where username = #{username})
    </select>


</mapper>
<?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.hnucm.c202001090120.dao.StudentMapper">
    <!--    id接口中方法的名字   resultType返回值的类型 集合对对象 可以省略集合 -->
    <!--    resultmap 数据库字段和实体类字段不一致-->

    <delete id="deletePersonById" parameterType="Integer">
        delete
        from student_zhh
        where id = #{id}
    </delete>
    <select id="searStudent" resultMap="searStudent">
        select * from student_zhh
         where   name= #{name}
    </select>

    <resultMap id="searStudent" type="com.hnucm.c202001090120.pojo.StudentZHH">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <result column="classname" property="classname"></result>
        <!--        id 配置主键column数据库中列名字property实体类字段名-->
        <!--            association 多个数据库字段映射一个实体类  Idcard-->
        <collection property="courseZHHList"
                    ofType="com.hnucm.c202001090120.pojo.CourseZHH"
                    column="id"
                    select="com.hnucm.c202001090120.dao.CourseMapper.findCourseById">

        </collection>
    </resultMap>

    <select id="findStudentByinfoId" resultMap="studentInfo">
        select * from student_zhh

    </select>

    <resultMap id="studentInfo" type="com.hnucm.c202001090120.pojo.StudentZHH">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <result column="classname" property="classname"></result>


        <!--        id 配置主键column数据库中列名字property实体类字段名-->
        <!--            association 多个数据库字段映射一个实体类  Idcard-->

        <collection property="courseZHHList"
                    ofType="com.hnucm.c202001090120.pojo.CourseZHH"
                    column="id"
                    select="com.hnucm.c202001090120.dao.CourseMapper.findCourseById">

        </collection>
    </resultMap>


</mapper>
<?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.hnucm.c202001090120.dao.UserMapper">
    <!--    id接口中方法的名字   resultType返回值的类型 集合对对象 可以省略集合 -->
    <!--    resultmap 数据库字段和实体类字段不一致-->
    <select id="findAllUser"
            resultType="com.hnucm.c202001090120.pojo.UserZHH">
        select *
        from users_zhh
    </select>
<!--    ofType指向集合 javaType-指向对象-->

        <select id="findUserByUsername"
                resultMap="user_zhh">
            select *
            from users_zhh
            where username =#{username}
        </select>
        <resultMap id="user_zhh" type="com.hnucm.c202001090120.pojo.UserZHH">
            <id column="id" property="id"></id>
            <result column="username" property="username"></result>
            <result column="password" property="password"></result>
            <collection property="rolesZHH"
                        javaType="com.hnucm.c202001090120.pojo.RolesZHH"
                        column="id"
                        select="com.hnucm.c202001090120.dao.RoleMapper.findRolesByname">
            </collection>
            <!--            级联查询-->
    </resultMap>

    <insert id="addUser" parameterType="com.hnucm.c202001090120.pojo.UserZHH">
        insert into users_zhh(username, password)
        values (#{username}, #{password})
    </insert>
    <insert id="addUsersRoles" parameterType="com.hnucm.c202001090120.pojo.Users_RolesZHH">
        insert into usersroles_zhh(username,roleid)
        values (#{username},#{roleid})
    </insert>

</mapper>

7.前端代码

异常处理

在这里插入图片描述

登录

在这里插入图片描述

退出登录

在这里插入图片描述

注册

在这里插入图片描述

搜索

在这里插入图片描述
在这里插入图片描述

学生列表

在这里插入图片描述

连接数据库

server.port=8086
#server.servlet.context-path=/springboot

#spring.web.resources.static-locations=classpath:/templates,file:C:/Users/86155/IdeaProjects
# ?????
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# ???????
spring.datasource.url=jdbc:mysql://localhost:3306/student?characterEncoding=utf8&serverTimezone=UTC
# ?????????
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.name=defaultDataSource

# mybatis??
mybatis.type-aliases-package=com.example.springboot.pojo
# mapers ??sql??->??????
mybatis.mapper-locations=classpath:Mapper/*.xml

# ??sql??
logging.level.com.example.springboot=debug

8.总结

对于从数据库取数据如果出现异常,可以通过输出来判别是那个地方出错,
Spring框架中参数的输出和输入类型一定要注意细节。写数据库之前要搞清楚表与表之间的关系,注意要降低耦合性,如果是多对多的关系一定要建立中间关联表。在运行项目时先思考一下,代码的逻辑是否有问题,这样可以减少报错。

如果对你有帮助,可以点个赞加关注

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学不懂人工智能的破茧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值