spring boot整合mybatis

项目结构

controller

复制代码
package com.qcby.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/")
    public String index() {
        return "index";
    }
}
复制代码
package com.qcby.controller;


import com.qcby.domain.Student;
import com.qcby.domain.Teacher;
import com.qcby.service.StudentService;
import com.qcby.service.TeacherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("/students")
public class StudentController {

    @Autowired
    private StudentService studentService;

    @Autowired
    private TeacherService teacherService;

    // 显示所有学生
    @GetMapping
    public String list(Model model) {
        model.addAttribute("students", studentService.findAll());
        return "student/list";
    }

    // 显示添加学生表单
    @GetMapping("/add")
    public String addForm(Model model) {
        model.addAttribute("student", new Student());
        model.addAttribute("teachers", teacherService.findAll());
        return "student/form";
    }

    // 保存学生
    @PostMapping("/save")
    public String save(@ModelAttribute Student student) {
        if (student.getId() == null) {
            studentService.insert(student);
        } else {
            studentService.update(student);
        }
        return "redirect:/students";
    }

    // 显示编辑学生表单
    @GetMapping("/edit/{id}")
    public String editForm(@PathVariable Integer id, Model model) {
        model.addAttribute("student", studentService.findById(id));
        model.addAttribute("teachers", teacherService.findAll());
        return "student/form";
    }

    // 删除学生
    @GetMapping("/delete/{id}")
    public String delete(@PathVariable Integer id) {
        studentService.delete(id);
        return "redirect:/students";
    }

    // 按教师ID查询学生
    @GetMapping("/by-teacher/{teacherId}")
    public String listByTeacher(@PathVariable Integer teacherId, Model model) {
        model.addAttribute("students", studentService.findByTeacherId(teacherId));
        Teacher teacher = teacherService.findById(teacherId);
        model.addAttribute("teacherName", teacher != null ? teacher.getName() : "未知教师");
        return "student/list-by-teacher";
    }
}
复制代码
package com.qcby.controller;


import com.qcby.domain.Teacher;
import com.qcby.service.TeacherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("/teachers")
public class TeacherController {

    @Autowired
    private TeacherService teacherService;

    // 显示所有教师
    @GetMapping
    public String list(Model model) {
        model.addAttribute("teachers", teacherService.findAll());
        return "teacher/list";
    }

    // 显示添加教师表单
    @GetMapping("/add")
    public String addForm(Model model) {
        model.addAttribute("teacher", new Teacher());
        return "teacher/form";
    }

    // 保存教师
    @PostMapping("/save")
    public String save(@ModelAttribute Teacher teacher) {
        if (teacher.getId() == null) {
            teacherService.insert(teacher);
        } else {
            teacherService.update(teacher);
        }
        return "redirect:/teachers";
    }

    // 显示编辑教师表单
    @GetMapping("/edit/{id}")
    public String editForm(@PathVariable Integer id, Model model) {
        model.addAttribute("teacher", teacherService.findById(id));
        return "teacher/form";
    }

    // 删除教师
    @GetMapping("/delete/{id}")
    public String delete(@PathVariable Integer id) {
        teacherService.delete(id);
        return "redirect:/teachers";
    }
}

domain

复制代码
package com.qcby.domain;

import lombok.Data;
import java.time.LocalDateTime;

@Data
public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private String gender;
    private String grade;
    private Integer teacherId;
    private String teacherName; // 用于显示教师姓名,不映射到数据库
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}
复制代码
package com.qcby.domain;

import lombok.Data;
import java.time.LocalDateTime;

@Data
public class Teacher {
    private Integer id;
    private String name;
    private Integer age;
    private String subject;
    private String phone;
    private String email;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}

mapper

复制代码
package com.qcby.mapper;


import com.qcby.domain.Student;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;

@Mapper
public interface StudentMapper {
    // 查询所有学生
    List<Student> findAll();

    // 根据ID查询学生
    Student findById(Integer id);

    // 添加学生
    int insert(Student student);

    // 更新学生
    int update(Student student);

    // 删除学生
    int delete(Integer id);

    // 根据教师ID查询学生
    List<Student> findByTeacherId(Integer teacherId);
}
复制代码
package com.qcby.mapper;

import com.qcby.domain.Teacher;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;

@Mapper
public interface TeacherMapper {
    // 查询所有教师
    List<Teacher> findAll();

    // 根据ID查询教师
    Teacher findById(Integer id);

    // 添加教师
    int insert(Teacher teacher);

    // 更新教师
    int update(Teacher teacher);

    // 删除教师
    int delete(Integer id);
}

service

复制代码
package com.qcby.service;


import com.qcby.domain.Student;

import java.util.List;

public interface StudentService {
    List<Student> findAll();

    Student findById(Integer id);

    int insert(Student student);

    int update(Student student);

    int delete(Integer id);

    List<Student> findByTeacherId(Integer teacherId);
}
复制代码
package com.qcby.service;


import com.qcby.domain.Teacher;

import java.util.List;

public interface TeacherService {
    List<Teacher> findAll();

    Teacher findById(Integer id);

    int insert(Teacher teacher);

    int update(Teacher teacher);

    int delete(Integer id);
}
复制代码
package com.qcby.service.impl;


import com.qcby.domain.Student;
import com.qcby.mapper.StudentMapper;
import com.qcby.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Override
    public List<Student> findAll() {
        return studentMapper.findAll();
    }

    @Override
    public Student findById(Integer id) {
        return studentMapper.findById(id);
    }

    @Override
    public int insert(Student student) {
        return studentMapper.insert(student);
    }

    @Override
    public int update(Student student) {
        return studentMapper.update(student);
    }

    @Override
    public int delete(Integer id) {
        return studentMapper.delete(id);
    }

    @Override
    public List<Student> findByTeacherId(Integer teacherId) {
        return studentMapper.findByTeacherId(teacherId);
    }
}
复制代码
package com.qcby.service.impl;


import com.qcby.domain.Teacher;
import com.qcby.mapper.TeacherMapper;
import com.qcby.service.TeacherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class TeacherServiceImpl implements TeacherService {

    @Autowired
    private TeacherMapper teacherMapper;

    @Override
    public List<Teacher> findAll() {
        return teacherMapper.findAll();
    }

    @Override
    public Teacher findById(Integer id) {
        return teacherMapper.findById(id);
    }

    @Override
    public int insert(Teacher teacher) {
        return teacherMapper.insert(teacher);
    }

    @Override
    public int update(Teacher teacher) {
        return teacherMapper.update(teacher);
    }

    @Override
    public int delete(Integer id) {
        return teacherMapper.delete(id);
    }
}

mapper.xml

复制代码
<?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.qcby.mapper.StudentMapper">

    <resultMap id="StudentResultMap" type="com.qcby.domain.Student">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <result property="gender" column="gender"/>
        <result property="grade" column="grade"/>
        <result property="teacherId" column="teacher_id"/>
        <result property="teacherName" column="teacher_name"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
    </resultMap>

    <select id="findAll" resultMap="StudentResultMap">
        SELECT s.*, t.name as teacher_name
        FROM student s
                 LEFT JOIN teacher t ON s.teacher_id = t.id
        ORDER BY s.id DESC
    </select>

    <select id="findById" parameterType="int" resultMap="StudentResultMap">
        SELECT s.*, t.name as teacher_name
        FROM student s
                 LEFT JOIN teacher t ON s.teacher_id = t.id
        WHERE s.id = #{id}
    </select>

    <select id="findByTeacherId" parameterType="int" resultMap="StudentResultMap">
        SELECT s.*, t.name as teacher_name
        FROM student s
                 LEFT JOIN teacher t ON s.teacher_id = t.id
        WHERE s.teacher_id = #{teacherId}
        ORDER BY s.id DESC
    </select>

    <insert id="insert" parameterType="com.qcby.domain.Student">
        INSERT INTO student (name, age, gender, grade, teacher_id)
        VALUES (#{name}, #{age}, #{gender}, #{grade}, #{teacherId})
    </insert>

    <update id="update" parameterType="com.qcby.domain.Student">
        UPDATE student
        SET name = #{name},
            age = #{age},
            gender = #{gender},
            grade = #{grade},
            teacher_id = #{teacherId}
        WHERE id = #{id}
    </update>

    <delete id="delete" parameterType="int">
        DELETE FROM student WHERE id = #{id}
    </delete>
</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.qcby.mapper.TeacherMapper">

    <resultMap id="TeacherResultMap" type="com.qcby.domain.Teacher">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <result property="subject" column="subject"/>
        <result property="phone" column="phone"/>
        <result property="email" column="email"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
    </resultMap>

    <select id="findAll" resultMap="TeacherResultMap">
        SELECT * FROM teacher ORDER BY id DESC
    </select>

    <select id="findById" parameterType="int" resultMap="TeacherResultMap">
        SELECT * FROM teacher WHERE id = #{id}
    </select>

    <insert id="insert" parameterType="com.qcby.domain.Teacher">
        INSERT INTO teacher (name, age, subject, phone, email)
        VALUES (#{name}, #{age}, #{subject}, #{phone}, #{email})
    </insert>

    <update id="update" parameterType="com.qcby.domain.Teacher">
        UPDATE teacher
        SET name = #{name},
            age = #{age},
            subject = #{subject},
            phone = #{phone},
            email = #{email}
        WHERE id = #{id}
    </update>

    <delete id="delete" parameterType="int">
        DELETE FROM teacher WHERE id = #{id}
    </delete>
</mapper>

html

复制代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title th:text="${student.id != null ? '编辑学生' : '添加学生'}"></title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-4">
    <h2 th:text="${student.id != null ? '编辑学生' : '添加学生'}"></h2>

    <form th:action="@{/students/save}" th:object="${student}" method="post" class="mt-4">
        <input type="hidden" th:field="*{id}" />

        <div class="mb-3">
            <label for="name" class="form-label">姓名</label>
            <input type="text" class="form-control" id="name" th:field="*{name}" required />
        </div>

        <div class="mb-3">
            <label for="age" class="form-label">年龄</label>
            <input type="number" class="form-control" id="age" th:field="*{age}" min="6" max="20" />
        </div>

        <div class="mb-3">
            <label for="gender" class="form-label">性别</label>
            <select class="form-select" id="gender" th:field="*{gender}">
                <option value="">请选择</option>
                <option value="男">男</option>
                <option value="女">女</option>
            </select>
        </div>

        <div class="mb-3">
            <label for="grade" class="form-label">年级</label>
            <input type="text" class="form-control" id="grade" th:field="*{grade}" />
        </div>

        <div class="mb-3">
            <label for="teacherId" class="form-label">班主任</label>
            <select class="form-select" id="teacherId" th:field="*{teacherId}">
                <option value="">请选择</option>
                <option th:each="teacher : ${teachers}"
                        th:value="${teacher.id}"
                        th:text="${teacher.name}"></option>
            </select>
        </div>

        <div class="mb-3">
            <button type="submit" class="btn btn-primary">保存</button>
            <a href="/students" class="btn btn-secondary ms-2">取消</a>
        </div>
    </form>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
复制代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>学生列表</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-4">
    <div class="d-flex justify-content-between align-items-center mb-4">
        <h2>学生列表</h2>
        <a href="/students/add" class="btn btn-primary">添加学生</a>
    </div>

    <a href="/" class="btn btn-secondary mb-3">返回首页</a>

    <table class="table table-striped table-hover">
        <thead class="table-dark">
        <tr>
            <th>ID</th>
            <th>姓名</th>
            <th>年龄</th>
            <th>性别</th>
            <th>年级</th>
            <th>班主任</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="student : ${students}">
            <td th:text="${student.id}"></td>
            <td th:text="${student.name}"></td>
            <td th:text="${student.age}"></td>
            <td th:text="${student.gender}"></td>
            <td th:text="${student.grade}"></td>
            <td th:text="${student.teacherName}"></td>
            <td>
                <a th:href="@{/students/edit/{id}(id=${student.id})}" class="btn btn-sm btn-warning">编辑</a>
                <a th:href="@{/students/delete/{id}(id=${student.id})}" class="btn btn-sm btn-danger"
                   onclick="return confirm('确定要删除吗?')">删除</a>
            </td>
        </tr>
        </tbody>
    </table>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
复制代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>学生列表</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-4">
    <div class="d-flex justify-content-between align-items-center mb-4">
        <h2>
            <span th:text="${teacherName}"></span> 的学生列表
        </h2>
        <a href="/students/add" class="btn btn-primary">添加学生</a>
    </div>

    <div class="mb-3">
        <a href="/" class="btn btn-secondary">返回首页</a>
        <a href="/teachers" class="btn btn-info ms-2">返回教师列表</a>
        <a href="/students" class="btn btn-success ms-2">查看所有学生</a>
    </div>

    <table class="table table-striped table-hover">
        <thead class="table-dark">
        <tr>
            <th>ID</th>
            <th>姓名</th>
            <th>年龄</th>
            <th>性别</th>
            <th>年级</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="student : ${students}">
            <td th:text="${student.id}"></td>
            <td th:text="${student.name}"></td>
            <td th:text="${student.age}"></td>
            <td th:text="${student.gender}"></td>
            <td th:text="${student.grade}"></td>
            <td>
                <a th:href="@{/students/edit/{id}(id=${student.id})}" class="btn btn-sm btn-warning">编辑</a>
                <a th:href="@{/students/delete/{id}(id=${student.id})}" class="btn btn-sm btn-danger"
                   onclick="return confirm('确定要删除吗?')">删除</a>
            </td>
        </tr>
        </tbody>
    </table>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
复制代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title th:text="${teacher.id != null ? '编辑教师' : '添加教师'}"></title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-4">
    <h2 th:text="${teacher.id != null ? '编辑教师' : '添加教师'}"></h2>

    <form th:action="@{/teachers/save}" th:object="${teacher}" method="post" class="mt-4">
        <input type="hidden" th:field="*{id}" />

        <div class="mb-3">
            <label for="name" class="form-label">姓名</label>
            <input type="text" class="form-control" id="name" th:field="*{name}" required />
        </div>

        <div class="mb-3">
            <label for="age" class="form-label">年龄</label>
            <input type="number" class="form-control" id="age" th:field="*{age}" min="18" max="65" />
        </div>

        <div class="mb-3">
            <label for="subject" class="form-label">科目</label>
            <input type="text" class="form-control" id="subject" th:field="*{subject}" />
        </div>

        <div class="mb-3">
            <label for="phone" class="form-label">电话</label>
            <input type="text" class="form-control" id="phone" th:field="*{phone}" />
        </div>

        <div class="mb-3">
            <label for="email" class="form-label">邮箱</label>
            <input type="email" class="form-control" id="email" th:field="*{email}" />
        </div>

        <div class="mb-3">
            <button type="submit" class="btn btn-primary">保存</button>
            <a href="/teachers" class="btn btn-secondary ms-2">取消</a>
        </div>
    </form>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
复制代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>教师列表</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-4">
    <div class="d-flex justify-content-between align-items-center mb-4">
        <h2>教师列表</h2>
        <a href="/teachers/add" class="btn btn-primary">添加教师</a>
    </div>

    <a href="/" class="btn btn-secondary mb-3">返回首页</a>

    <table class="table table-striped table-hover">
        <thead class="table-dark">
        <tr>
            <th>ID</th>
            <th>姓名</th>
            <th>年龄</th>
            <th>科目</th>
            <th>电话</th>
            <th>邮箱</th>
            <th>学生</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="teacher : ${teachers}">
            <td th:text="${teacher.id}"></td>
            <td th:text="${teacher.name}"></td>
            <td th:text="${teacher.age}"></td>
            <td th:text="${teacher.subject}"></td>
            <td th:text="${teacher.phone}"></td>
            <td th:text="${teacher.email}"></td>
            <td>
                <a th:href="@{/students/by-teacher/{id}(id=${teacher.id})}" class="btn btn-sm btn-info">查看学生</a>
            </td>
            <td>
                <a th:href="@{/teachers/edit/{id}(id=${teacher.id})}" class="btn btn-sm btn-warning">编辑</a>
                <a th:href="@{/teachers/delete/{id}(id=${teacher.id})}" class="btn btn-sm btn-danger"
                   onclick="return confirm('确定要删除吗?')">删除</a>
            </td>
        </tr>
        </tbody>
    </table>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
复制代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>教师学生管理系统</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
    <div class="jumbotron text-center">
        <h1 class="display-4">教师学生管理系统</h1>
        <p class="lead">简单高效的教学管理解决方案</p>
        <hr class="my-4">
        <div class="d-flex justify-content-center gap-3">
            <a class="btn btn-primary btn-lg" href="/teachers" role="button">教师管理</a>
            <a class="btn btn-success btn-lg" href="/students" role="button">学生管理</a>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

properties

复制代码
# ?????
server.port=8080

# ?????
spring.datasource.url=jdbc:mysql://localhost:3306/teacher_student_management?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# MyBatis??
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.qcby.domain

# Thymeleaf??
spring.thymeleaf.cache=false
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.servlet.content-type=text/html

# ????
logging.level.com.example.mapper=debug
相关推荐
神仙别闹2 分钟前
基于QT(C++)实现(图形界面)选课管理系统
java·c++·qt
daixin88484 分钟前
SpringMVC的请求执行流程是什么样的?
java·开发语言·spring
pengzhuofan13 分钟前
Web开发系列-第9章 SpringBootWeb登录认证
java·spring boot·后端·web
愿你天黑有灯下雨有伞23 分钟前
Spring Boot集成RabbitMQ终极指南:从配置到高级消息处理
spring boot·rabbitmq·java-rabbitmq
手握风云-30 分钟前
JavaEE初阶第十二期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(十)
java·开发语言·java-ee
盖世英雄酱5813637 分钟前
加了锁,加了事务 还是重复报名❓
java·数据库·后端
Pigwantofly40 分钟前
SpringAI入门及浅实践,实战 Spring‎ AI 调用大模型、提示词工程、对话记忆、Adv‎isor 的使用
java·大数据·人工智能·spring
GEM的左耳返1 小时前
Java面试全方位解析:从基础到AI的技术交锋
spring boot·微服务·java面试·互联网大厂·rag技术·ai面试·java技术栈
微笑听雨1 小时前
Java 设计模式之单例模式(详细解析)
java·后端
微笑听雨1 小时前
【Drools】(二)基于业务需求动态生成 DRL 规则文件:事实与动作定义详解
java·后端