【基于轻量型架构的WEB开发】课程 实验一 mybatis操作 Java EE企业级应用开发教程 Spring+SpringMVC+MyBatis

实验一 mybatis操作

实验目的

  1. 掌握MyBatis环境搭建,MyBatis核心配置文件及其元素的使用,MyBatis映射文件及其元素的使用。
  2. 掌握MyBatis中动态SQL元素的使用,MyBatis的条件查询操作,MyBatis的复杂查询操作。
  3. 掌握MyBatis的关联映射和缓存机制。
  4. 掌握MyBatis的基于注解的多对多关联查询开发。

实验环境

  1. IntelliJ IDEA Ultimate2024
  2. jdk-17
  3. MySQL 8.0

实验内容

1 数据准备

  1. 创建学生表(student)、课程表(course)、成绩表(score)。
sql 复制代码
CREATE DATABASE experiment;
USE experiment;
CREATE TABLE student (
                         id INT PRIMARY KEY AUTO_INCREMENT, -- 学生ID,主键,自动递增
                         name varchar(32),                      -- 学生姓名,最多32字符
                         sex VARCHAR(8),                        -- 性别,最多8字符,通常为"男"或"女"
                         age INT,                               -- 年龄,整数类型
                         sclass INT                             -- 班级编号,整数类型
);

CREATE TABLE course (
                        id INT PRIMARY KEY AUTO_INCREMENT, -- 课程ID,主键,自动递增
                        name varchar(32),                      -- 课程名称,最多32字符
                        semester char(10)                       -- 学期标识,例如'2024-1'表示2024年第一学期
);

CREATE TABLE score (
                       id INT PRIMARY KEY AUTO_INCREMENT, -- 成绩记录ID,主键,自动递增
                       student_id INT,                    -- 学生ID,外键引用student表的id
                       course_id INT,                     -- 课程ID,外键引用course表的id
                       score INT,                             -- 分数,整数类型
                       FOREIGN KEY(student_id) REFERENCES student(id),
                       FOREIGN KEY(course_id) REFERENCES course(id)
);

2.插入代表个人信息的真实数据。

sql 复制代码
-- 插入学生信息
INSERT INTO student (name, sex, age, sclass)
VALUES ('lql', '女', 21, 1),
       ('大学生2', '男', 20, 2);

-- 插入课程信息
INSERT INTO course (name, semester)
VALUES ('程序设计基础', '2022-1'),
       ('管理学原理', '2022-1'),
       ('Java核心技术', '2023-1'),
       ('基于轻量型架构的WEB开发', '2024-1');

-- 插入学生成绩信息
INSERT INTO score (student_id, course_id, score)
VALUES (1, 1, 92),
       (1, 2, 95),
       (1, 3, 93),
       (2, 1, 88),
       (2, 2, 90);

2 环境准备

2.1安装和配置IntelliJ IDEA Ultimate 2024

  • 下载和安装:
  • 访问JetBrains官网,下载IntelliJ IDEA Ultimate 2024版。安装并启动IDEA。
  • 配置JDK:
  • 在IDEA中,打开"File" > "Project Structure" > "SDKs"。添加JDK 17,确保其为项目使用的JDK。

2.2 安装和配置MySQL 8.0

  • 下载和安装:
  • 访问MySQL官网,下载MySQL 8.0版本。安装MySQL并设置root用户密码。
  • 配置MySQL:
  • 运行MySQL服务。创建数据库。
  • 配置数据库连接:
  • 在IDEA中,打开"Database"视图。配置MySQL 8.0数据库连接,输入数据库地址、端口、用户名和密码。

2.3 创建Maven项目

  • 创建项目:
  • 在IDEA中,选择"File" > "New" > "Project..."。选择"Maven"项目,点击"Next"。输入项目名称,选择项目存储位置,点击"Finish"。
  • 配置pom.xml:

添加MyBatis和MySQL驱动的依赖。

示例pom.xml配置:

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>bigDataWeb</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- MyBatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.16</version>
        </dependency>
        <!-- MySQL Connector -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
        <!-- JUnit 5 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.7.0</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.7.0</version>
        </dependency>
        <!-- Logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.30</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- Connection Pool -->
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>3.4.5</version>
        </dependency>


    </dependencies>
</project>

2.4 配置MyBatis

  • 创建MyBatis配置文件:

在src/main/resources目录下创建mybatis-config.xml。

示例配置:

XML 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="db.properties"/>

    <typeAliases>
        <package name="com.example.domain"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mapper/StudentMapper.xml"/>
    </mappers>

</configuration>
  • 创建映射文件:

在src/main/resources/mapper目录下创建映射文件,如StudentMapper.xml。

2.5 创建实体类和Mapper接口

  • 实体类:
  • 创建Student.java、Course.java和Score.java。
  • package com.example.domain;
  • Mapper接口:

创建StudentMapper.java、CourseMapper.java和ScoreMapper.java。

3 动态SQL(使用xml配置文件方式)

1.学生信息多条件查询(条件之间存在制约)

a)当用户输入的学生姓名不为空时,则只根据学生姓名进行学生信息的查询;

b)当用户输入的学生姓名为空而学生班级不为空时,则只根据学生班级进行学生信息的查询;

c)当用户输入的学生姓名和班级都为空,则要求查询出所有学号不为空的学生信息。

java 复制代码
@Test
public void testFindStudentsByConditions() {
    try (SqlSession session = MyBatisUtil.getSqlSession()) {
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        List<Student> students = mapper.findStudentsByConditions(null, null);
        students.forEach(System.out::println);
    }
}

2.学生信息多条件查询

可以通过学生的姓名和班级来查找学生,也可以只通过学生姓名或只通过学生班级来查找学生,还可以没有条件查找出所有学生。

3.单条件查询

a)查询出所有id值小于5的学生的信息。

java 复制代码
@Test
public void testFindStudentsByIdLessThanFive() {
    try (SqlSession session = MyBatisUtil.getSqlSession()) {
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        List<Student> students = mapper.findStudentsByIdLessThanFive();
        students.forEach(System.out::println);
    }
}

4 关联映射(使用xml配置文件方式)

查询某个学生的所有课程成绩

要求输入学生姓名,输出学生信息和课程信息以及分数。

java 复制代码
@Test
public void testFindStudentScoresByName() {
    try (SqlSession session = MyBatisUtil.getSqlSession()) {
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        List<Score> scores = mapper.findStudentScoresByName("lql");
        scores.forEach(System.out::println);
    }
}

5 缓存机制

1.一级缓存测试

对Course表根据id进行两次相同的查询。

java 复制代码
@Test
public void testFirstLevelCache() {
    try (SqlSession session = MyBatisUtil.getSqlSession()) {
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        // 第一次查询
        List<Student> students = mapper.findAll();
        System.out.println("第一次查询结果: " + students);

        // 修改数据
        Student student = new Student();
        student.setName("测试");
        student.setAge(20);
        student.setSex("男");
        student.setSclass(1);
        mapper.insert(student);

        // 第二次查询,应该使用缓存数据
        students = mapper.findAll();
        System.out.println("第二次查询结果: " + students);
    }
}

2.一级缓存的清空

在两次相同查询之间,使用插入、更新或删除语句对Course表中的信息进行修改,第二次查询时Mybatis依然会从数据库查询。

java 复制代码
@Test
public void testClearFirstLevelCache() {
    try (SqlSession session = MyBatisUtil.getSqlSession()) {
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        // 查询
        List<Student> students = mapper.findAll();
        System.out.println("查询结果: " + students);

        // 清空一级缓存
        session.clearCache();

        // 再次查询,这次不会使用缓存
        students = mapper.findAll();
        System.out.println("清空缓存后查询结果: " + students);
    }
}

3.二级缓存测试

除了参照教材的方式开启二级缓存,还需要序列化对象,比如在CourseMapper开启了二级缓存,则Course这个POJO需要实现Serializable接口,即implements Serializable,否则程序会报错。

java 复制代码
package com.example;

import com.example.domain.Course;
import com.example.mapper.CourseMapper;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;

import java.util.List;

public class CourseMapperTest {
    @Test
    public void testFindAll() {
        try (SqlSession session = MyBatisUtil.getSqlSession()) {
            CourseMapper mapper = session.getMapper(CourseMapper.class);
            List<Course> courses = mapper.findAll();
            courses.forEach(System.out::println);
        }
    }
}

4.二级缓存的清空

参照一级缓存的清空,区别在于使用不同的sqlsession进行查询和修改操作。

在 MyBatis 中,二级缓存是全局的,可以跨 SqlSession 使用。二级缓存的清空通常涉及到使用不同的 SqlSession 来执行查询和修改操作。这是因为二级缓存是全局的,所以它不受单个 SqlSession 的限制。

要清空二级缓存,可以在 MyBatis 配置文件中设置 eviction 策略。MyBatis 提供了几种不同的清空策略,例如 LRU(最近最少使用)、FIFO(先进先出)、SOFT(软引用) 和 NO(无)。这些策略决定了在什么情况下二级缓存会被清空。

java 复制代码
@Test
public void testClearSecondLevelCache() {
    try (SqlSession session1 = MyBatisUtil.getSqlSession()) {
        CourseMapper mapper1 = session1.getMapper(CourseMapper.class);
        List<Course> courses = mapper1.findAll();
        session1.evict();
        try (SqlSession session2 = MyBatisUtil.getSqlSession()) {
            CourseMapper mapper2 = session2.getMapper(CourseMapper.class);
            List<Course> coursesAfterEvict = mapper2.findAll();
            System.out.println("二级缓存清空成功");
        }
    }
}

6 注解开发

使用注解的开发方式实现实验内容三的第1个任务:查询某个学生的所有课程成绩,要求使用面向接口的开发方式。

java 复制代码
/**
 * 根据姓名查询学生的课程与分数
 *
 * @param name 学生姓名
 * @return 学生对象,包含课程和分数信息
 */
@Select("SELECT s.*, c.id AS cid, c.name AS cname, sc.score AS score " +
        "FROM student s " +
        "JOIN score sc ON s.id = sc.student_id " +
        "JOIN course c ON sc.course_id = c.id " +
        "WHERE s.name = #{name}")
@Results({
        @Result(property = "id", column = "id"),
        @Result(property = "name", column = "name"),
        @Result(property = "age", column = "age"),
        @Result(property = "sex", column = "sex"),
        @Result(property = "sclass", column = "sclass"),
        @Result(property = "courseList", column = "cid",
                many = @Many(select = "com.example.domain.CourseMapper.findByStudentId"))
})
Student findByNameCourseAndScore(String name);

实验总结

在本次实验中,我通过一系列步骤掌握了

  • 环境搭建与配置:我成功安装并配置了IntelliJ IDEA Ultimate 2024、JDK 17和MySQL 8.0,为后续的MyBatis开发打下了坚实的基础。通过配置IDEA和MySQL,我加深了对开发环境搭建的理解。
  • MyBatis核心配置:我学会了如何编写MyBatis的核心配置文件,包括数据源配置、事务管理器配置以及映射文件的引用。这些配置是MyBatis工作的基础,通过实践我掌握了它们的具体含义和作用。
  • 动态SQL与条件查询:通过实验,我掌握了MyBatis中动态SQL的使用,包括条件查询操作和复杂查询操作。我学会了如何使用<if>、<choose>、<when>等动态SQL元素来构建灵活的查询语句。
  • 关联映射与缓存机制:我探索了MyBatis的关联映射功能,通过编写映射文件和Mapper接口,实现了学生与课程成绩的关联查询。此外,我还了解了MyBatis的一级缓存和二级缓存机制,并掌握了如何在实际开发中使用和配置缓存。
  • 注解开发:我尝试了使用注解的方式进行MyBatis开发,这种方式简化了XML配置文件的编写,使我能够更专注于业务逻辑的实现。通过注解,我实现了查询某个学生的所有课程成绩的功能。
  • 问题解决:在实验过程中,我遇到了一些问题,如SLF4J的警告和MyBatis的PersistenceException。通过查阅文档和资料,我成功解决了这些问题,这不仅提升了我的问题解决能力,也加深了我对MyBatis和相关技术的理解。
相关推荐
snow@li33 分钟前
前端组件开发:组件开发 / 定义配置 / 配置驱动开发 / 爬虫配置 / 组件V2.0 / form表单 / table表单
前端·组件化·定义配置
Mr_sun.37 分钟前
day01-HTML-CSS——基础标签样式&表格标签&表单标签
前端·css·html
多多*1 小时前
后端技术选型 sa-token校验学习 下 结合项目学习 后端鉴权
java·开发语言·前端·学习·算法·bootstrap·intellij-idea
guihong0042 小时前
深入探秘 ZooKeeper:架构、设计、角色与 ZNode 全解析 前言
分布式·zookeeper·架构
wangbing11253 小时前
开发指南090-使用python做微服务
微服务·云原生·架构
dengjiayue3 小时前
单体 vs 微服务 怎么选?
微服务·云原生·架构
落霞的思绪3 小时前
苍穹外卖07——来单提醒和客户催单(涉及SpringTask、WebSocket协议、苍穹外卖跳过微信支付同时保证可以收到订单功能)
linux·前端·数据库
binqian3 小时前
【harbor】离线安装2.9.0-arm64架构服务制作和升级部署
运维·架构
JINGWHALE13 小时前
设计模式 行为型 解释器模式(Interpreter Pattern)与 常见技术框架应用 解析
前端·人工智能·后端·设计模式·性能优化·系统架构·解释器模式