SpringBoot 中配置 MyBatis 实现数据访问

370 阅读6分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

SpringBoot 中配置 MyBatis 实现数据访问

总结

  • 实体类 Entity 无需添加额外的注解或接口,以 Student.java 为例
package com.example.demo.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student implements Serializable {
	/**
	 * 学生 id
	 */
	private Long studentId;
	/**
	 * 学生 姓名
	 */
	private String studentName;
	/**
	 * 学生 年龄
	 */
	private Integer studentAge;
	/**
	 * 学生 性别
	 */
	private String studentSex;
	/**
	 * 学生 的家长 ID
	 */
	private Long patriarchId;
	/**
	 * 学生 的班级 ID
	 */
	private Long classRoomId;
	
	public Student(String studentName, Integer studentAge, String studentSex) {
		this.studentName = studentName;
		this.studentAge = studentAge;
		this.studentSex = studentSex;
	}
	
	public Student(String studentName, Integer studentAge, String studentSex, Long patriarchId, Long classRoomId) {
		this.studentName = studentName;
		this.studentAge = studentAge;
		this.studentSex = studentSex;
		this.patriarchId = patriarchId;
		this.classRoomId = classRoomId;
	}
}
  • 注解方式实现,较为 方便,直接通过注解添加 SQL 语句,无需添加 xml 文件。

  • 注解方式实现,在类属性名上较为 限定,需要按照驼峰命名,不支持其他命名方式。

  • 注解方式实现,表现为 @Select、@Update、@Delete、@Insert

  • xml 文件方式实现,较为 多样,可以添加 if 标签对 update 方法进行去‘空’处理,可以 添加常用的 SQL 段进行复用。

  • xml 文件方式实现,在查询输出上较为 繁琐,必须配置 查询返回值与实体类的映射关系,在类属性命名上没有限制。

  • xml 文件方式实现,表现为 select、update、delete、insert 四个标签

前置信息

  • 这个测试的技术框架是 SpringBoot + MySql + MyBatis + Druid

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.4.5</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>2.4.5</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>2.4.5</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.24</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.25</version>
        <scope>runtime</scope>
    </dependency>

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.2</version>
    </dependency>
</dependencies>
  • MyBatis 的依赖是

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>
  • MySql 连接配置
spring:
  # DataBase Connection -- MyBatis -- MySql
  datasource:
    druid:
      # serverTimezone可以设置为北京时间GMT%2B8、上海时间Asia/Shanghai或者香港时间Hongkong
      url: jdbc:mysql://localhost:3306/cloudtext?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
      username: 
      password: 
      min-idle: 3
      max-active: 10
      driver-class-name: com.mysql.cj.jdbc.Driver
      login-timeout: 60000
  • MyBatis 的配置,不需要添加 MyBatis 的全局配置文件了。
# MyBatis 配置
mybatis:
  # 配置全局配置 Xml 文件的文件路径(SpringBoot 配置 MyBatis 不需要添加这个全局配置文件了)
  #config-location: classpath:mybatis/mybatis-config.xml
  # 配置 Xml 文件路径(注意:文件在 resource 包中,不知道写在 java 包中可不可以)
  mapper-locations: classpath:mybatis/mapper/*.xml
  configuration:
    # 开启驼峰命名(必备,因为没有配置实体类属性与数据库表字段的对应方式,同时实体类属性名必须按照驼峰规则命名)
    map-underscore-to-camel-case: true
  • #{}参数占位符,即预编译,在处理添加了 #{} 的 SQL 语句时,会用 ? 来占位, 后续用元素替换,并且会添加 '' 来包裹元素。

  • ${}字符串替换符,即 SQL 拼接,在处理添加了 SQL语句时,会直接用里面的元素来替换{} 的 SQL 语句时, 会直接用 {} 里面的元素来``替换`` {}, 并且不添加 '' 来包裹元素。

  • SQL 文件 MySql 版。

SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for classroom
-- ----------------------------
DROP TABLE IF EXISTS `classroom`;
CREATE TABLE `classroom`
(
    `class_room_id`       tinyint unsigned NOT NULL AUTO_INCREMENT COMMENT '班级主键',
    `class_room_name`     varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '班级名称',
    `class_room_location` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '班级位置',
    `class_room_capacity` int unsigned                                     DEFAULT NULL COMMENT '班级人数',
    `class_room_grade`    varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '班级年级',
    PRIMARY KEY (`class_room_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 14
  DEFAULT CHARSET = utf8mb3
  COLLATE = utf8_bin;

-- ----------------------------
-- Table structure for patriarch
-- ----------------------------
DROP TABLE IF EXISTS `patriarch`;
CREATE TABLE `patriarch`
(
    `patriarch_id`      tinyint unsigned NOT NULL AUTO_INCREMENT COMMENT '家长主键',
    `patriarch_name`    varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '家长姓名',
    `patriarch_age`     int unsigned                  DEFAULT NULL COMMENT '家长年龄',
    `patriarch_sex`     varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '家长性别',
    `patriarch_phone`   varchar(11) COLLATE utf8_bin  DEFAULT NULL COMMENT '家长电话',
    `patriarch_address` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '家长住址',
    PRIMARY KEY (`patriarch_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 31
  DEFAULT CHARSET = utf8mb3
  COLLATE = utf8_bin;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`
(
    `student_id`    tinyint unsigned NOT NULL AUTO_INCREMENT COMMENT '学生主键',
    `student_name`  varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '学生姓名',
    `student_age`   int unsigned                  DEFAULT NULL COMMENT '学生年龄',
    `student_sex`   varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '学生性别',
    `patriarch_id`  tinyint unsigned NOT NULL COMMENT '家长外键',
    `class_room_id` tinyint unsigned              DEFAULT NULL COMMENT '班级外键',
    PRIMARY KEY (`student_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 21
  DEFAULT CHARSET = utf8mb3
  COLLATE = utf8_bin;

-- ----------------------------
-- Table structure for student_teacher
-- ----------------------------
DROP TABLE IF EXISTS `student_teacher`;
CREATE TABLE `student_teacher`
(
    `student_id` tinyint unsigned NOT NULL COMMENT '学生主键',
    `teacher_id` tinyint unsigned NOT NULL COMMENT '教师主键',
    PRIMARY KEY (`student_id`, `teacher_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb3
  COLLATE = utf8_bin;

-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher`
(
    `teacher_id`     tinyint unsigned NOT NULL AUTO_INCREMENT COMMENT '教师主键',
    `teacher_name`   varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '教师姓名',
    `teacher_age`    int unsigned                  DEFAULT NULL COMMENT '教师年龄',
    `teacher_sex`    varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '教师性别',
    `teacher_course` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '教师教授科目',
    PRIMARY KEY (`teacher_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 22
  DEFAULT CHARSET = utf8mb3
  COLLATE = utf8_bin;

MyBatis 的配置

  • 可以通过 注解的方式添加 SQL 语句。

  • 也可以通过 xml 文件的方式添加 SQL 语句。

  • 当然也可以 两个一起用,推荐

  • @Mapper 注解是两种方式都要添加的,必备的

注解方式

  • 简洁、可读性高。

查询

  • 根据 ID 查询,直接用 @Select 注解添加即可,单个数据直接用 #{} 获取,?1、?2 不能用。
/**
 * 根据 ID 查询 数据
 *
 * @param id ID
 *
 * @return 数据项
 */
@Select(value = "SELECT student_id, student_name, student_age, " +
		"student_sex, patriarch_id, class_room_id " +
		"FROM student WHERE student_id = #{id}")
Student findById(Long id);

  • 全查询,查询都是直接用 @Select 注解
/**
 * 查询 所有 数据
 *
 * @return 数据集
 */
@Select("SELECT student_id, student_name, student_age, " +
		"student_sex, patriarch_id, class_room_id " +
		"FROM student ")
List<Student> findAll();
  • 统计数量,查询都是直接用 @Select 注解
/**
 * 查询数据表数据数量
 *
 * @return 数量
 */
@Select("SELECT count(s.student_id) FROM student AS s")
int count();

删除

/**
 * 根据 ID 删除
 *
 * @param id ID
 *
 * @return 成功返回 1,失败返回 0
 */
@Delete("DELETE FROM student WHERE student_id = #{id}")
int deleteById(Long id);

更新

  • 与 findById(id) 不同,这次传入的参数是 ,不是用 ${参数} 的方式了,而是 ${类.属性1} 的方式。
/**
 * 根据 ID 更新
 *
 * @param student 实体类
 *
 * @return 成功返回 1,失败返回 0
 */
@Update("UPDATE student SET student_name = #{studentName}, " +
		"student_age = #{studentAge}, student_sex = #{studentSex}, " +
		"patriarch_id = #{patriarchId}, class_room_id = #{classRoomId} " +
		"WHERE student_id = #{studentId}")
int updateById(Student student);

添加

  • 与 updateById(id) 一样,传入的参数是 ,用 ${类.属性1} 的方式。
/**
 * 添加
 *
 * @param student 实体类
 *
 * @return 成功返回 1,失败返回 0
 */
@Insert("INSERT INTO student(student_name, student_age, " +
		"student_sex, patriarch_id, class_room_id) " +
		"VALUES (#{studentName}, #{studentAge}, #{studentSex}, " +
		"#{patriarchId}, #{classRoomId})")
int save(Student student);

xml 文件方式

  • 空白的 Mapper.xml 文件,注意一定要写对 namespace 属性,用全限定类名,如:com.example.xx.mapper.StudentMapper。

  • 其他的所有标签都是写在 <mapper></mapper> 标签中的。

  • mapper 是一级标签

  • 二级标签主要有:resultMap、parameterMap、sql、insert、update、delete、select

  • Mapper.xml 怎么写可以看这些文章:mybatis的xml文档编写springboot-mybatis中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.example.demo.mapper.StudentMapper">

</mapper>

查询

  • 统计数量,标签属性 ID 就是方法名

  • resultType 是返回值类型


<select id="count" resultType="java.lang.Integer">
    SELECT count(teacher_id)
    FROM teacher
</select>
  • 查询返回值的映射关系,column 是数据库字段名

  • property 是实体类属性名javaType 是实体类属性类型jdbcType 是数据库字段类型

<!--  Teacher 实体类与 数据表 teacher 的映射关系  -->
<!--  MyBatis 必须要加  -->
<resultMap id="TeacherMap" type="com.example.demo.entity.Teacher">
    <result column="teacher_id" property="teacherId" javaType="java.lang.Long" jdbcType="TINYINT"/>
    <result column="teacher_name" property="teacherName" javaType="java.lang.String" jdbcType="VARCHAR"/>
    <result column="teacher_age" property="teacherAge" javaType="java.lang.Integer" jdbcType="INTEGER"/>
    <result column="teacher_sex" property="teacherSex" javaType="java.lang.String" jdbcType="VARCHAR"/>
    <result column="teacher_course" property="teacherCourse" javaType="java.lang.String" jdbcType="VARCHAR"/>
</resultMap>
  • 根据 ID 查询,写了 resultMap 属性就不要写 resultType,两者互斥

  • parameterType 是 传入参数类型


<select id="findById" resultMap="TeacherMap" parameterType="java.lang.Long">
    SELECT teacher_id, teacher_name, teacher_age, teacher_sex, teacher_course
    FROM teacher
    WHERE teacher_id = #{id}
</select>
  • 全查询,全查询时也不需要额外设置,沿用 findById 即可

  • resultMap="xx" 表示将返回值用 xx 映射关系装配到对应的类中。


<select id="findAll" resultMap="TeacherMap">
    SELECT teacher_id, teacher_name, teacher_age, teacher_sex, teacher_course
    FROM teacher
</select>

删除

  • 根据 ID 删除。

<delete id="deleteById" parameterType="java.lang.Long">
    DELETE
    FROM teacher
    WHERE teacher_id = #{id}
</delete>

更新

  • 根据 ID 更新。

  • 标签 set 是 SET 关键字的变种,表示标签内有元素时才更新,没有元素就没有 SET 关键字

  • UPDATE teacher WHERE teacher_id = #{teacherId} 语句是可以运行,但没有任何更改的 SQL

  • if 标签 表示 test 的条件满足后,就用 if 标签内的元素替换掉整个 if 标签


<update id="updateById" parameterType="com.example.demo.entity.Teacher">
    UPDATE teacher
    <set>
        <if test="teacherName != null and teacherName != ''">
            teacher_name = #{teacherName},
        </if>
        <if test="teacherAge != null and teacherAge != ''">
            teacher_age = #{teacherAge},
        </if>
        <if test="teacherSex != null and teacherSex != ''">
            teacher_sex = #{teacherSex},
        </if>
        <if test="teacherCourse != null and teacherCourse != ''">
            teacher_course = #{teacherCourse})
        </if>
    </set>
    WHERE teacher_id = #{teacherId}
</update>

添加

  • 添加

<insert id="save" parameterType="com.example.demo.entity.Teacher">
    INSERT INTO teacher(teacher_name, teacher_age, teacher_sex, teacher_course)
    VALUES (#{teacherName}, #{teacherAge}, #{teacherSex}, #{teacherCourse})
</insert>

增删查改 都齐全的类的实体类、Mapper 以及 Mapper.xml 的完整版

Student 类,主要展示通过 @Select、@Update、@Delete、@Insert 四个注解来添加 SQL 语句

  • SQL 语句都写在 StudentMapper.java 中,StudentMapper.xml 是空的。

  • StudentMapper.xml 为空时是不需要加的,只是个人习惯会加上。

Student.java 文件

  • @Data、@NoArgsConstructor、@AllArgsConstructor 是 lombok 的注解。

  • 用来简化类的创建,创建默认的 Getter、Setter、toString、全参构造、无参构造 等方法。

package com.example.demo.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student implements Serializable {
	/**
	 * 学生 id
	 */
	private Long studentId;
	/**
	 * 学生 姓名
	 */
	private String studentName;
	/**
	 * 学生 年龄
	 */
	private Integer studentAge;
	/**
	 * 学生 性别
	 */
	private String studentSex;
	/**
	 * 学生 的家长 ID
	 */
	private Long patriarchId;
	/**
	 * 学生 的班级 ID
	 */
	private Long classRoomId;
	
	public Student(String studentName, Integer studentAge, String studentSex) {
		this.studentName = studentName;
		this.studentAge = studentAge;
		this.studentSex = studentSex;
	}
	
	public Student(String studentName, Integer studentAge, String studentSex, Long patriarchId, Long classRoomId) {
		this.studentName = studentName;
		this.studentAge = studentAge;
		this.studentSex = studentSex;
		this.patriarchId = patriarchId;
		this.classRoomId = classRoomId;
	}
}

StudentMapper.java 文件

  • @Mapper 注解是用来 添加该类到 Spring 容器中的,必须

  • select 查询的结果是通过 驼峰命名来映射的。

  • 批量 select 查询的结果 会自动填充到 List 中,无需其他配置。

package com.example.demo.mapper;

import com.example.demo.base.BaseMapper;
import com.example.demo.entity.Student;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

@Mapper
public interface StudentMapper {
	/**
	 * 根据 ID 查询 数据
	 *
	 * @param id ID
	 *
	 * @return 数据项
	 */
	@Select("SELECT student_id, student_name, student_age, " +
			"student_sex, patriarch_id, class_room_id " +
			"FROM student WHERE student_id = #{id}")
	Student findById(Long id);
	
	/**
	 * 查询 所有 数据
	 *
	 * @return 数据集
	 */
	@Select("SELECT student_id, student_name, student_age, " +
			"student_sex, patriarch_id, class_room_id " +
			"FROM student ")
	List<Student> findAll();
	
	/**
	 * 查询数据表数据数量
	 *
	 * @return 数量
	 */
	@Select("SELECT count(s.student_id) FROM student AS s")
	int count();
	
	/**
	 * 添加
	 *
	 * @param student 实体类
	 *
	 * @return 成功返回 1,失败返回 0
	 */
	@Insert("INSERT INTO student(student_name, student_age, " +
			"student_sex, patriarch_id, class_room_id) " +
			"VALUES (#{studentName}, #{studentAge}, #{studentSex}, " +
			"#{patriarchId}, #{classRoomId})")
	int save(Student student);
	
	/**
	 * 根据 ID 更新
	 *
	 * @param student 实体类
	 *
	 * @return 成功返回 1,失败返回 0
	 */
	@Update("UPDATE student SET student_name = #{studentName}, " +
			"student_age = #{studentAge}, student_sex = #{studentSex}, " +
			"patriarch_id = #{patriarchId}, class_room_id = #{classRoomId} " +
			"WHERE student_id = #{studentId}")
	int updateById(Student student);
	
	/**
	 * 根据 ID 删除
	 *
	 * @param id ID
	 *
	 * @return 成功返回 1,失败返回 0
	 */
	@Delete("DELETE FROM student WHERE student_id = #{id}")
	int deleteById(Long id);
}

StudentMapper.xml 文件

  • mapper 标签的 namespace 一定要写对(类的全限定名称)要不然就不要写这个 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.example.demo.mapper.StudentMapper">

</mapper>

Teacher类,主要展示通过 select、update、delete、insert 四个标签来添加 SQL 语句

Teacher.java 文件

  • 与 Student.java 一样,没有什么不同。

  • @Data、@NoArgsConstructor、@AllArgsConstructor 是 lombok 的注解。

  • 用来简化类的创建,创建默认的 Getter、Setter、toString、全参构造、无参构造 等方法。

package com.example.demo.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Teacher implements Serializable {
	/**
	 * 教师 id
	 */
	private Long teacherId;
	/**
	 * 教师 姓名
	 */
	private String teacherName;
	/**
	 * 教师 年龄
	 */
	private Integer teacherAge;
	/**
	 * 教师 性别
	 */
	private String teacherSex;
	/**
	 * 教师 所教的 科目
	 */
	private String teacherCourse;
	
	public Teacher(String teacherName, Integer teacherAge, String teacherSex, String teacherCourse) {
		this.teacherName = teacherName;
		this.teacherAge = teacherAge;
		this.teacherSex = teacherSex;
		this.teacherCourse = teacherCourse;
	}

}

TeacherMapper.java 文件

  • @Mapper 注解是用来 添加该类到 Spring 容器中的,必须
package com.example.demo.mapper;

import com.example.demo.base.BaseMapper;
import com.example.demo.entity.Teacher;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface TeacherMapper {
	
	/**
	 * 根据 ID 查询 数据
	 *
	 * @param id ID
	 *
	 * @return 数据项
	 */
	Teacher findById(Long id);
	
	/**
	 * 查询 所有 数据
	 *
	 * @return 数据集
	 */
	List<Teacher> findAll();
	
	/**
	 * 查询数据表数据数量
	 *
	 * @return 数量
	 */
	int count();
	
	/**
	 * 添加
	 *
	 * @param teacher 实体类
	 *
	 * @return 成功返回 1,失败返回 0
	 */
	int save(Teacher teacher);
	
	/**
	 * 根据 ID 更新
	 *
	 * @param teacher 实体类
	 *
	 * @return 成功返回 1,失败返回 0
	 */
	int updateById(Teacher teacher);
	
	/**
	 * 根据 ID 删除
	 *
	 * @param id ID
	 *
	 * @return 成功返回 1,失败返回 0
	 */
	int deleteById(Long id);
}

TeacherMapper.xml 文件

  • 标签 select、update、delete、insert 是用来添加 SQL 语句的。

  • 标签 set 是 SET 关键字,同样的 WHERE 也有 where 标签,其他的类似。

  • 属性 parameterType 表示 传入的参数的数据类型

  • 属性 resultType 表示返回单个数据时,返回值的数据类型

  • 属性 resultMap 表示返回一行 或 多行 数据时,返回值的数据类型 及 映射关系

  • 属性 resultMapresultType 互斥。

<?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.example.demo.mapper.TeacherMapper">

    <insert id="save" parameterType="com.example.demo.entity.Teacher">
        INSERT INTO teacher(teacher_name, teacher_age,
        teacher_sex, teacher_course)
        VALUES (#{teacherName}, #{teacherAge}, #{teacherSex}, #{teacherCourse})
    </insert>

    <update id="updateById" parameterType="com.example.demo.entity.Teacher">
        UPDATE teacher
        <set>
            <if test="teacherName != null and teacherName != ''">
                teacher_name = #{teacherName},
            </if>
            <if test="teacherAge != null and teacherAge != ''">
                teacher_age = #{teacherAge},
            </if>
            <if test="teacherSex != null and teacherSex != ''">
                teacher_sex = #{teacherSex},
            </if>
            <if test="teacherCourse != null and teacherCourse != ''">
                teacher_course = #{teacherCourse})
            </if>
        </set>
        WHERE teacher_id = #{teacherId}
    </update>

    <delete id="deleteById" parameterType="java.lang.Long">
        DELETE
        FROM teacher
        WHERE teacher_id = #{id}
    </delete>

    <select id="count" resultType="java.lang.Integer">
        SELECT count(teacher_id)
        FROM teacher
    </select>

    <!--  Teacher 实体类与 数据表 teacher 的映射关系  -->
    <!--  MyBatis 必须要加  -->
    <resultMap id="TeacherMap" type="com.example.demo.entity.Teacher">
        <result column="teacher_id" property="teacherId" javaType="java.lang.Long" jdbcType="TINYINT"/>
        <result column="teacher_name" property="teacherName" javaType="java.lang.String" jdbcType="VARCHAR"/>
        <result column="teacher_age" property="teacherAge" javaType="java.lang.Integer" jdbcType="INTEGER"/>
        <result column="teacher_sex" property="teacherSex" javaType="java.lang.String" jdbcType="VARCHAR"/>
        <result column="teacher_course" property="teacherCourse" javaType="java.lang.String" jdbcType="VARCHAR"/>
    </resultMap>

    <select id="findById" resultMap="TeacherMap" parameterType="java.lang.Long">
        SELECT teacher_id, teacher_name, teacher_age, teacher_sex, teacher_course
        FROM teacher
        WHERE teacher_id = #{id}
    </select>

    <select id="findAll" resultMap="TeacherMap">
        SELECT teacher_id, teacher_name, teacher_age, teacher_sex, teacher_course
        FROM teacher
    </select>

</mapper>