要求
某学生和课程的ER图如下图所示,根据ER图创建数据库表,往数据库表中添加若干测试数据,用SpringBoot+SpringMVC+ Mybatis完成如下功能:
1、用前端列表显示所有的学生的选课信息,学生的选课信息通过级联查询获取
2、删除某条学生信息,并同步的删除该学生的选课信息
3、前端完成输入用户的姓名后查询该用户所选的课程
技术要求
- 数据库使用Mysql8.0 后端
- 使用SpringBoot + SpringMVC+ Mybatis实现
- 前端使用html+Thymeleaf
其它要求
- 后端工程的包名以com.hnucm.c+学号来命名(命名不符合要求得分不超过60分)
- 数据库学生表以student+姓名拼音首字母命名如张三同学命名为student_zs,课程表以course _ + 姓名- 拼音首字母命名如张三同学命名为course_zs(命名不符合要求得分不超过60分)
后端学生实体类以Student+姓名拼音首字母命名如张三同学命名为StudentZS,课程实体类以Course+姓名拼音首字母命名如张三同学命名为CourseZS(命名不符合要求得分不超过60分)
真服了,写完了才发现自己的命名不符合要求。所以我会教你们如何把这个作业变成你们“自己”的作业!!!!当然如果单纯知识来学习知识的就不用关注这么多啦~~
建项目:
依赖包选择:
手动补一个依赖:
<!--thymeleaf是适用于Web和独立环境的现代服务器端Java模板引擎,方便html中数据传递-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
数据库设计:
course表
student表
stu_course表
pojo对象类:
新建两个Java类:
Course:
package com.hnucm.c202001090145.pojo;
import lombok.Data;
@Data
public class Course {
private int id;
private String c_name;
private float score;
}
Student类:
package com.hnucm.c202001090145.pojo;
import lombok.Data;
import java.util.List;
@Data
public class Student {
private String num;
private String name;
private String classname;
private List<Course> courseList;
}
配置application.properties数据库文件
我在这里数据库配置后面新增了一个属性:allowMultiQueries=true
你们直接复制粘贴就OK。这条配置项的作用是允许执行多条sql语句,我这里是使用在delete标签删除时里面含有两条独立的SQL语句。不配置会报错
#设置端口号
server.port=9090
#前缀值,路劲前面加上/springboot
server.servlet.context-path=/springboot
#设置静态文件访问地址
spring.web.resources.static-locations=classpath:/templates
#把你自己的数据库名写在‘3306/’ 后面
#spring.datasource.url=jdbc:mysql://localhost:3306/homework_tow?
characterEncoding=utf8&serverTimezone=UTC
spring.datasource.url=jdbc:mysql://localhost:3306/homework_tow?characterEncoding=utf8&serverTimezone=UTC&allowMultiQueries=true
# 用户名密码
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.name=defaultDataSource
#改成你自己的路径。!!!!!!改
mybatis.type-aliases-package=com.hnucm.c202001090145.pojo
mybatis.mapper-locations=classpath:mappers/*.xml
# 日志
logging.level.com.example.csdn_release=debug
简单的我就快速过了,仔细讲讲核心代码
mapper层
StudentMapper接口
在这里主要是定义了几个方法,以及与StudentMapper.xml文件关联
package com.hnucm.c202001090145.mapper;
import com.hnucm.c202001090145.pojo.CourseOYH;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface StudentMapper {
// 查询所有学生以及选课情况
public List<CourseOYH> findAllStuAndCourse();
int deleteStudentByNum(String num);
}
CourseMapper接口
package com.hnucm.c202001090145.mapper;
import com.hnucm.c202001090145.pojo.CourseOYH;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface CourseMapper {
public List<CourseOYH> findCourseById(String num);
// 输入用户姓名查询所选课程
List<CourseOYH> findCourseByName(String name);
}
与mapper对应的xml文件
StudentMapper.xml
着重讲xml文件。首先是一个select标签。因为要展示学生的所有信息,所以直接select*。与之对应的是resultMap标签,因为学生和选课是一对多的关系,所以需要一个集合关系。这也是为什么在pojo中的student加了一个List的原因。其实主要还是collection标签中的类容,里面的property=“courseList” 中的courseList是属性名,什么叫属性名呢?以及一些springboot中一些常用的名词解释可以看我这篇文章:springboot+mybatis实现多表一对一查询以及名词解释
里面的column是
select=“com.hnucm.c202001090145.mapper.CourseMapper.findCourseById” 这个对应方法所需要的参数
ofType意思是这个集合的类型。
下面的delete标签是删除学生信息和选课信息。可以看见这里面包含了两条独立的sql语句。springboot默认是不允许的所以我们在上面的配置文件中加了spring.datasource.url=jdbc:mysql://localhost:3306/homework_tow?characterEncoding=utf8&serverTimezone=UTC**&allowMultiQueries=true**
标红的部分就可以实现同时执行多条SQL语句了
<?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.c202001090145.mapper.StudentMapper">
<select id="findAllStuAndCourse" resultMap="studentCourse">
select * from student_oyh
</select>
<resultMap id="studentCourse" type="com.hnucm.c202001090145.pojo.StudentOYH">
<id column="num" property="num"></id>
<result property="name" column="name"></result>
<result column="classname" property="classname"></result>
<collection property="courseList"
ofType="com.hnucm.c202001090145.pojo.CourseOYH"
column="num"
select="com.hnucm.c202001090145.mapper.CourseMapper.findCourseById">
</collection>
</resultMap>
<delete id="deleteStudentByNum" parameterType="String" >
delete from student_oyh where student_oyh.num=#{num};
delete from stu_course where stu_course.num=#{num}
</delete>
</mapper>
CourseMapper.xml
这里面的第一个select语句就是实现了学生信息以及选课信息的级联查询。只不过我们把它们放在了一条sql语句中了。解释一下,就是先执行
select courseId from stu_course where num=#{num}这条代码,有人说这里的num参数 是怎么来的呢,其实就是StudentMapper.xml文件中collection中的colum传递过来的,并且是一条一条穿过来,所以这条sql语句就会查询出多个 courseId。之后继续执行
select * from course_oyh where id in(一个courseId数组)这条语句。
第二个select语句,就是输入学生信息查询选课信息。标准的查法应该是
输入姓名查询student表中的num
通过num查询在stu_course表中的所有courseId
将id拿到继续在course中查询
但是我不一样呀,我偷懒一句搞定算了~~~~
<?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.c202001090145.mapper.CourseMapper">
<select id="findCourseById"
resultType="com.hnucm.c202001090145.pojo.CourseOYH"
parameterType="String">
select * from course_oyh where id in(
select courseId from stu_course where num=#{num}
)
</select>
<!--分布实现:
输入姓名查询student表中的num
通过num查询在stu_course表中的所有courseId
将id拿到继续在course中查询
~~~~~~~~~~~太麻烦一个语句搞定算了
-->
<select id="findCourseByName" parameterType="String" resultType="com.hnucm.c202001090145.pojo.CourseOYH">
SELECT DISTINCT course_oyh.id,course_oyh.c_name,course_oyh.score
from stu_course,course_oyh,student_oyh
where student_oyh.num=stu_course.num AND course_oyh.id=stu_course.courseId and student_oyh.`name`=#{name};
</select>
</mapper>
Service层
StudentService接口:
一般接口没有什么好看的就是定义了一些方法
package com.hnucm.c202001090145.service;
import com.hnucm.c202001090145.pojo.CourseOYH;
import java.util.List;
public interface StudentService {
public List<CourseOYH> findAllStuAndCourse();
int deleteStudentByNum(String num);
List<CourseOYH> findCourseByName(String name);
}
StudentService接口实现类
这里也没什么好讲的,就是调用了Mapper层的接口。注意一下“deleteStudentByNum”这个方法上面我多加了一个注解@Transactional,目的是为了防止你只删除了学生信息而没有删除选课信息,从而实现事务回滚
package com.hnucm.c202001090145.service;
import com.hnucm.c202001090145.mapper.CourseMapper;
import com.hnucm.c202001090145.mapper.StudentMapper;
import com.hnucm.c202001090145.pojo.CourseOYH;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class StudentServiceImpl implements StudentService{
@Autowired
StudentMapper studentMapper;
@Autowired
CourseMapper courseMapper;
@Override
public List<CourseOYH> findAllStuAndCourse() {
return studentMapper.findAllStuAndCourse() ;
}
@Override
@Transactional
public int deleteStudentByNum(String num) {
return studentMapper.deleteStudentByNum(num);
}
@Override
public List<CourseOYH> findCourseByName(String name) {
return courseMapper.findCourseByName(name);
}
}
断点测试是否有数据。如果有数据就继续写html文件
前端展示代码:
studentlist.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
</head>
<body>
<!--一个基本的 html表格-->
<table border="1px" cellspacing="0px">
<tr>
<th th:width="40px">学号</th>
<th th:width="40px">姓名</th>
<th th:width="150px">班级</th>
<th th:width="150px">选课信息</th>
<th >删除</th>
<th>更新</th>
</tr>
<tr th:each="student:${studentlist}">
<td th:text="${student.num}"></td>
<td th:text="${student.name}"></td>
<td th:text="${student.classname}"></td>
<td>
<ul th:each="course:${student.courseList}" >
<li th:text="${course.c_name}"></li>
<li th:text="${course.score}"></li>
</ul>
</td>
<td><a th:href="@{'/deletestudentbyid?num='+${student.num}}">删除用户</a> </td>
<td><a th:href="@{updatepersonbyid(num=${student.num},courseId=${student.courseList},classname=${student.classname})}">更新用户</a> </td>
</tr>
</table>
<form th:action="@{/lookinfo} " method="post" style="margin-top: 20px">
请输入用户名:<input name="name"><br>
<div><input type="submit" value="查询"></div>
</form>
</body>
</html>
courseList.html
用户查询展示页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
</head>
<body>
<!--一个基本的 html表格-->
<h2>你所查询的用户:</h2>
<h2 th:text="${name}"></h2>
<h2>选课信息如下:</h2>
<table border="1px" cellspacing="0px">
<tr>
<th th:width="40px">课程号</th>
<th th:width="40px">课程名</th>
<th th:width="150px">学分</th>
</tr>
<tr th:each="course:${courseList}">
<td th:text="${course.id}"></td>
<td th:text="${course.c_name}"></td>
<td th:text="${course.score}"></td>
</tr>
</table>
</body>
</html>
如何变为自己的代码
学习知识的不用管这里,完成作业有需要的看看就好了。
第一步修改数据库命名:直接在Navicat中右键表重命名就好了,之后继续在代码中改
与数据库先关的只在xml文件中。只需在每一个xml文件Ctrl+F键搜索没改之前的数据库名,涉及到相关的一个一个手动改!!!注意一定是手动一个一个检查改,不要使用替换!!。
第二步:修改pojo对象类命名:
只需要右键那个类选择refactor,在选择里面的rename就OK了,这里其他的应该不用自己改。
继续重命名Java下面的那个包名,只需要重命名然后在每个文件的最上方改成你的名字就好了。
最容易忽视的地方就是数据库配置文件application.properties中的数据库名,用户名和密码。
还有mybatis对应的pojo类。
然后因为我在配置类中设置了前缀地址/springboot和端口号所以,你运行项目后记得是localhost:9090/springboot/xxx什么的
效果展示
今天的分享结束有帮助就点个赞和收藏吧~~