springboot+mybatis实现多一对多查询demo(用前端列表显示所有的学生的选课信息,学生的选课信息通过级联查询获取 2、删除某条学生信息,并同步的删除该学生的选课信息

要求

某学生和课程的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什么的

效果展示

在这里插入图片描述
在这里插入图片描述
今天的分享结束有帮助就点个赞和收藏吧~~

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

H-rosy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值