本文已参与「新人创作礼」活动,一起开启掘金创作之路。
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 文件 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表示返回一行 或 多行 数据时,返回值的数据类型 及 映射关系。 -
属性
resultMap和resultType互斥。
<?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>