文章目录
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框架中参数的输出和输入类型一定要注意细节。写数据库之前要搞清楚表与表之间的关系,注意要降低耦合性,如果是多对多的关系一定要建立中间关联表。在运行项目时先思考一下,代码的逻辑是否有问题,这样可以减少报错。
如果对你有帮助,可以点个赞加关注