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 分钟前
Java已死?别慌,看我如何用Java手写一个Qwen Code Agent,拯救Java
java·人工智能·后端
lssjzmn2 分钟前
性能飙升!Spring异步流式响应终极指南:ResponseBodyEmitter实战与架构思考
java·前端·架构
LiuYaoheng18 分钟前
【Android】View 的基础知识
android·java·笔记·学习
勇往直前plus26 分钟前
Sentinel微服务保护
java·spring boot·微服务·sentinel
星辰大海的精灵26 分钟前
SpringBoot与Quartz整合,实现订单自动取消功能
java·后端·算法
小鸡脚来咯29 分钟前
一个Java的main方法在JVM中的执行流程
java·开发语言·jvm
江团1io029 分钟前
深入解析三色标记算法
java·开发语言·jvm
天天摸鱼的java工程师38 分钟前
RestTemplate 如何优化连接池?—— 八年 Java 开发的踩坑与优化指南
java·后端
你我约定有三42 分钟前
java--泛型
java·开发语言·windows
杨杨杨大侠1 小时前
第3章:实现基础事件总线
java·github·eventbus