Spring boot整合Mybatis实现级联一对多CRUD操作的完整步骤

下面是“Spring boot整合Mybatis实现级联一对多CRUD操作的完整步骤”的攻略。

一、准备工作

首先,需要搭建好Spring Boot项目,并将Mybatis集成到项目中。可以参考官方文档。然后,需要确保数据库中有两张表,一张父表和一张子表。例如,下面是一个父表和一个子表的示例:

父表 student:

| id | name |

| ---- | ---- |

| 1 | 张三 |

| 2 | 李四 |

子表 course:

| id | name | student_id |

| ---- | ------ | ---------- |

| 1 | 语文 | 1 |

| 2 | 数学 | 1 |

| 3 | 英语 | 2 |

二、建立实体类

在父表和子表对应的包中,建立两个实体类 Student 和 Course。实体类中需要使用注解来定义表名和字段名,例如:

Student.java:

public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @Transient
    private List<Course> courses;

    // getter/setter 省略
}

Course.java:

public class Course {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @Column(name = "student_id")
    private Long studentId;

    // getter/setter 省略
}

这里使用了注解 @Id 和 @GeneratedValue 来定义主键和自动增长策略。同时,使用了 @Column 注解来定义字段名,因为在实际数据库表中,字段名可能跟变量名不一致。

注意到 Student 实体类中还定义了一个 courses 属性,该属性用于存储所有和该学生相关的课程对象,因为该示例中实现的是一对多关系。

三、建立Mapper接口

接下来,建立父表和子表对应的 Mapper 接口。例如,Mapper.java 中定义如下:

StudentMapper.java:

public interface StudentMapper {

    List<Student> selectAll();

    Student selectById(Long id);

    void insert(Student student);

    void update(Student student);

    void delete(Long id);

    List<Course> selectCoursesByStudentId(Long studentId);

    void insertCourse(Course course);

    void updateCourse(Course course);

    void deleteCourse(Long id);
}

CourseMapper.java:

public interface CourseMapper {

    List<Course> selectAll();

    Course selectById(Long id);

    void insert(Course course);

    void update(Course course);

    void delete(Long id);
}

需要注意的是,StudentMapper 中包含了一个 selectCoursesByStudentId 方法,用于根据学生 ID 查询该学生所有的课程列表。同时,StudentMapper 中还包含了 insertCourse、updateCourse 和 deleteCourse 方法,用于分别新增、修改和删除学生的课程。

四、建立Mapper XML文件

在resources目录下建立一个mapper目录,然后分别在其中建立“StudentMapper.xml”和“CourseMapper.xml”两个XML文件。

StudentMapper.xml:

<mapper namespace="com.example.mapper.StudentMapper">
    <select id="selectAll" resultType="Student">
        select * from student
    </select>
    <select id="selectById" resultType="Student">
        select * from student where id = #{id}
    </select>
    <insert id="insert" useGeneratedKeys="true" keyProperty="id" parameterType="Student">
        insert into student (name) values (#{name})
    </insert>
    <update id="update" parameterType="Student">
        update student set name = #{name} where id = #{id}
    </update>
    <delete id="delete" parameterType="Long">
        delete from student where id = #{id}
    </delete>
    <select id="selectCoursesByStudentId" resultMap="courseResultMap">
        select * from course where student_id = #{studentId}
    </select>
    <insert id="insertCourse" parameterType="Course">
        insert into course (name, student_id) values (#{name}, #{studentId})
    </insert>
    <update id="updateCourse" parameterType="Course">
        update course set name = #{name} where id = #{id}
    </update>
    <delete id="deleteCourse" parameterType="Long">
        delete from course where id = #{id}
    </delete>

    <resultMap id="courseResultMap" type="Course">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="studentId" column="student_id"/>
    </resultMap>

    <resultMap id="studentResultMap" type="Student">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <collection property="courses" ofType="Course" resultMap="courseResultMap"/>
    </resultMap>
</mapper>

CourseMapper.xml:

<mapper namespace="com.example.mapper.CourseMapper">
    <select id="selectAll" resultType="Course">
        select * from course
    </select>
    <select id="selectById" resultType="Course">
        select * from course where id = #{id}
    </select>
    <insert id="insert" useGeneratedKeys="true" keyProperty="id" parameterType="Course">
        insert into course (name, student_id) values (#{name}, #{studentId})
    </insert>
    <update id="update" parameterType="Course">
        update course set name = #{name} where id = #{id}
    </update>
    <delete id="delete" parameterType="Long">
        delete from course where id = #{id}
    </delete>
</mapper>

其中,StudentMapper.xml 中定义了一个 courseResultMap 和 studentResultMap 两个 resultMap,用于将结果集映射成对应的实体类。

五、建立Service层

在 service 包下建立两个 Service 接口和实现类,对应 Student 和 Course 实体类。

例如,StudentServiceImpl.java 中定义如下:

@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private CourseMapper courseMapper;

    @Override
    public List<Student> selectAll() {
        List<Student> students = studentMapper.selectAll();
        for (Student student : students) {
            List<Course> courses = courseMapper.selectCoursesByStudentId(student.getId());
            student.setCourses(courses);
        }
        return students;
    }

    @Override
    public Student selectById(Long id) {
        Student student = studentMapper.selectById(id);
        if (student != null) {
            List<Course> courses = courseMapper.selectCoursesByStudentId(student.getId());
            student.setCourses(courses);
        }
        return student;
    }

    @Override
    @Transactional
    public void insert(Student student) {
        studentMapper.insert(student);
        List<Course> courses = student.getCourses();
        if (courses != null) {
            for (Course course : courses) {
                course.setStudentId(student.getId());
                courseMapper.insert(course);
            }
        }
    }

    @Override
    @Transactional
    public void update(Student student) {
        studentMapper.update(student);
        List<Course> oldCourses = courseMapper.selectCoursesByStudentId(student.getId());
        List<Course> newCourses = student.getCourses();
        if (newCourses == null) {
            newCourses = new ArrayList<>();
        }
        for (Course oldCourse : oldCourses) {
            boolean exist = false;
            for (Course newCourse : newCourses) {
                if (newCourse.getId() != null && newCourse.getId().equals(oldCourse.getId())) {
                    exist = true;
                    courseMapper.update(newCourse);
                    break;
                }
            }
            if (!exist) {
                courseMapper.delete(oldCourse.getId());
            }
        }
        for (Course newCourse : newCourses) {
            if (newCourse.getId() == null) {
                newCourse.setStudentId(student.getId());
                courseMapper.insert(newCourse);
            }
        }
    }

    @Override
    public void delete(Long id) {
        studentMapper.delete(id);
        courseMapper.selectCoursesByStudentId(id).forEach(course -> courseMapper.delete(course.getId()));
    }

    @Override
    public void insertCourse(Course course) {
        courseMapper.insert(course);
    }

    @Override
    public void updateCourse(Course course) {
        courseMapper.update(course);
    }

    @Override
    public void deleteCourse(Long id) {
        courseMapper.delete(id);
    }
}

实现类中重写了各自的方法,例如 selectAll() 方法中,先查询出所有学生,然后再循环查询每个学生的课程列表,赋值给学生对象的 courses 属性。

六、建立Controller层

最后,在 controller 包下建立对应的 Controller 类。例如,StudentController.java 中定义如下:

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

    @Autowired
    private StudentService studentService;

    @GetMapping
    public List<Student> selectAll() {
        return studentService.selectAll();
    }

    @GetMapping("/{id}")
    public Student selectById(@PathVariable Long id) {
        return studentService.selectById(id);
    }

    @PostMapping
    public void insert(@RequestBody Student student) {
        studentService.insert(student);
    }

    @PutMapping
    public void update(@RequestBody Student student) {
        studentService.update(student);
    }

    @DeleteMapping("/{id}")
    public void delete(@PathVariable Long id) {
        studentService.delete(id);
    }
}

在 Controller 类中,各个方法分别调用对应的 Service 方法来实现 CRUD 操作。

七、测试效果

完成以上全部步骤后,运行项目,可以使用 Postman 或其他工具进行测试。例如,使用 GET 请求 http://localhost:8080/students 可以查询出所有学生和他们的课程列表。

[
    {
        "id": 1,
        "name": "张三",
        "courses": [
            {
                "id": 1,
                "name": "语文",
                "studentId": 1
            },
            {
                "id": 2,
                "name": "数学",
                "studentId": 1
            }
        ]
    },
    {
        "id": 2,
        "name": "李四",
        "courses": [
            {
                "id": 3,
                "name": "英语",
                "studentId": 2
            }
        ]
    }
]

可以使用其他 HTTP 方法来执行增、删、改操作。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring boot整合Mybatis实现级联一对多CRUD操作的完整步骤 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Java+swing+Mysql实现商品销售管理系统

    让我来讲解“Java+swing+Mysql实现商品销售管理系统”的完整攻略。这个系统主要涉及到 Java 编程语言、swing GUI 工具包以及 Mysql 数据库的应用。下面是具体的步骤: 步骤一:环境搭建与项目创建 在搭建环境之前需要安装 Java JDK、Eclipse/IDEA 编辑器、Mysql 数据库工具等软件。具体过程可以参考网上教程进行安…

    Java 2023年5月19日
    00
  • Spring Boot thymeleaf模板引擎的使用详解

    感谢你对Spring Boot和Thymeleaf模板引擎的关注。下面是Spring Boot Thymeleaf模板引擎的使用详解攻略: 1. Thymeleaf简介 Thymeleaf是一个现代化的服务器端Java模板引擎,可以将模板渲染成HTML、XML、JavaScript等格式,并提供模板缓存机制,允许HTML页面的热部署。 2. Spring B…

    Java 2023年6月15日
    00
  • Java8 Stream流的合并

    最近的需求里有这样一个场景,要校验一个集合中每个对象的多个Id的有效性。比如一个Customer对象,有3个Id:id1,id2,id3,要把这些Id全部取出来,然后去数据库里查询它是否存在。 @Data @AllArgsConstructor public class Customer { private String name; private Stri…

    Java 2023年5月6日
    00
  • JavaScript中的数组特性介绍

    关于JavaScript中的数组特性,我们可以从以下几个方面进行介绍: 数组的创建和初始化 JavaScript中的数组可以使用字面量和构造函数两种方式进行创建和初始化。其中,字面量方式如下: const array = [‘a’, ‘b’, ‘c’]; 构造函数方式如下: const array = new Array(‘a’, ‘b’, ‘c’); 需要…

    Java 2023年5月26日
    00
  • 详解Java中对象池的介绍与使用

    详解Java中对象池的介绍与使用 对象池是一种常见的对象创建和管理技术,主要用于提高对象创建和销毁的性能和效率。在Java中,使用对象池可以有效地减少垃圾回收和对象创建的开销,提高系统的性能和稳定性。 对象池的概述 对象池是一种对象创建和存储技术,主要用于缓存和复用经常使用的对象,避免重复创建和销毁对象导致的性能开销。相比于直接创建和销毁对象,使用对象池可以…

    Java 2023年5月26日
    00
  • spring boot tomcat jdbc pool的属性绑定

    关于“spring boot tomcat jdbc pool的属性绑定”的完整攻略,我可以从以下几个方面进行讲解: 引入依赖 首先,我们需要在pom.xml文件中引入相关的依赖,在该文件中添加如下内容: <dependency> <groupId>org.springframework.boot</groupId> &l…

    Java 2023年5月19日
    00
  • Spring Security账户与密码验证实现过程

    下面我来详细讲解“Spring Security账户与密码验证实现过程”的完整攻略。 1. 配置Spring Security 首先,我们需要在项目中配置Spring Security。在Spring Boot项目中,可以通过在pom.xml文件中添加依赖,并在application.properties文件中添加配置字段的方式来完成配置。 在pom.xml…

    Java 2023年6月3日
    00
  • SpringBoot项目集成依赖Mybatis步骤

    下面是SpringBoot项目集成依赖Mybatis步骤的完整攻略。 1. 引入Mybatis相关依赖 在pom.xml文件中添加以下依赖,其中包括Mybatis核心依赖 mybatis-spring-boot-starter ,Mysql驱动包mysql-connector-java以及Mybatis分页插件pagehelper。 <!– myba…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部