MyBatis注解开发

本文最后更新于:2 年前

引言

在现代应用开发中,快速开发和代码的易维护性至关重要。MyBatis作为一个广泛使用的持久层框架,提供了通过注解集成SQL语句和Java代码的能力,极大地简化了数据库操作的配置。注解开发模式允许开发者在单个Java文件中定义SQL映射和接口,减少了配置的复杂性,提高了开发效率。

简介

MyBatis注解开发是指在MyBatis中使用Java 注解(Annotations)来代替XML映射文件进行SQL映射配置的方法。这种方式提供了一种更直接、更简洁的方式来绑定SQL语句与Java方法,使得开发者可以在单个Java文件中即定义接口及配置SQL映射,提高了开发效率并降低了项目的复杂性。

常用的注解主要集中于映射SQL语句到接口方法。这些注解包括但不限于:

  • @Select:用于标注查询语句。
  • @Insert:用于标注插入语句。
  • @Update:用于标注更新语句。
  • @Delete:用于标注删除语句。
  • @Param:用于指定SQL参数的名称。
  • @Result、**@Results**:用于配置结果映射,对应XML配置中的<resultMap>
  • @ResultMap:用于引用已定义的XML resultMap
  • @Options:提供了执行语句时的控制,例如是否使用缓存,是否自动生成主键等。

特点

优点

  • 简洁:减少了配置的冗余,所有配置都在Java代码中完成,不需要额外的XML文件。
  • 直观:SQL语句紧邻其对应的Java方法,提高了代码的可读性和维护性。
  • 易于维护:代码和SQL语句的修改在同一个地方完成,不需要在项目中搜索对应的XML文件。

缺点

  • 灵活性有限:对于非常复杂的SQL语句或动态SQL,使用注解可能不如XML方式灵活。
  • 功能受限:一些高级的映射和配置选项在注解中不可用或表达不便。

DEMO

tt_student表结构定义

1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE `tt_student`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`class_id` bigint NOT NULL COMMENT '班级ID',
`name` varchar(50) NOT NULL COMMENT '姓名',
`height` double NOT NULL COMMENT '身高(cm)',
`gender` char NOT NULL COMMENT '性别',
`birthday` date NOT NULL COMMENT '出生日期',
`create_time` datetime NOT NULL default current_timestamp COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8mb4 COMMENT ='学生表';

Mapper接口定义对应的增删改查方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public interface StudentMapper {

@Insert("INSERT INTO tt_student (class_id, name, height, gender, birthday, create_time) VALUES (#{classId}, #{name}, #{height}, #{gender}, #{birthday}, #{createTime})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertStudent(StudentPO student);

@Delete("DELETE FROM tt_student WHERE id = #{id}")
int deleteStudent(long id);

@Update("UPDATE tt_student SET class_id = #{classId}, name = #{name}, height = #{height}, gender = #{gender}, birthday = #{birthday}, create_time = #{createTime} WHERE id = #{id}")
int updateStudent(StudentPO student);

@Select("SELECT id, class_id, name, height, gender, birthday, create_time FROM tt_student WHERE id = #{id}")
@Results({
@Result(property = "id", column = "id", id = true),
@Result(property = "classId", column = "class_id"),
@Result(property = "name", column = "name"),
@Result(property = "height", column = "height"),
@Result(property = "gender", column = "gender"),
@Result(property = "birthday", column = "birthday"),
@Result(property = "createTime", column = "create_time")
})
StudentPO selectStudentById(long id);

}

运行测试程序

1
2
3
4
5
6
7
8
9
10
11
12
SqlSession session = SqlSessionUtil.getSession();
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
StudentPO studentPO = new StudentPO().setName("zl")
.setClassId(1L)
.setHeight(176.1)
.setGender('男')
.setBirthday(dateSdf.parse("1990-01-01"))
.setCreateTime(dateTimeSdf.parse("2022-07-04 21:08:34"));
log.info("注解新增:{}", studentMapper.insertStudent(studentPO));
log.info("注解更新:{}", studentMapper.updateStudent(studentPO.setId(studentPO.getId()).setName("zhaoliu")));
log.info("注解查询:{}", studentMapper.selectStudentById(studentPO.getId()));
log.info("注解删除:{}", studentMapper.deleteStudent(studentPO.getId()));

控制台输出日志如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
08:55:25.932 [main] DEBUG space.yangtao.mapper.StudentMapper.insertStudent - ==> Preparing: INSERT INTO tt_student (class_id, name, height, gender, birthday, create_time) VALUES (?, ?, ?, ?, ?, ?)
08:55:25.957 [main] DEBUG space.yangtao.mapper.StudentMapper.insertStudent - ==> Parameters: 1(Long), zl(String), 176.1(Double), 男(String), 1990-01-01 00:00:00.0(Timestamp), 2022-07-04 21:08:34.0(Timestamp)
08:55:25.959 [main] DEBUG space.yangtao.mapper.StudentMapper.insertStudent - <== Updates: 1
08:55:25.965 [main] INFO space.yangtao.client.StudentMapperTest - 注解新增:1
08:55:25.965 [main] DEBUG space.yangtao.mapper.StudentMapper.updateStudent - ==> Preparing: UPDATE tt_student SET class_id = ?, name = ?, height = ?, gender = ?, birthday = ?, create_time = ? WHERE id = ?
08:55:25.966 [main] DEBUG space.yangtao.mapper.StudentMapper.updateStudent - ==> Parameters: 1(Long), zhaoliu(String), 176.1(Double), 男(String), 1990-01-01 00:00:00.0(Timestamp), 2022-07-04 21:08:34.0(Timestamp), 4(Long)
08:55:25.968 [main] DEBUG space.yangtao.mapper.StudentMapper.updateStudent - <== Updates: 1
08:55:25.968 [main] INFO space.yangtao.client.StudentMapperTest - 注解更新:1
08:55:25.969 [main] DEBUG s.yangtao.mapper.StudentMapper.selectStudentById - ==> Preparing: SELECT id, class_id, name, height, gender, birthday, create_time FROM tt_student WHERE id = ?
08:55:25.969 [main] DEBUG s.yangtao.mapper.StudentMapper.selectStudentById - ==> Parameters: 4(Long)
08:55:25.974 [main] TRACE s.yangtao.mapper.StudentMapper.selectStudentById - <== Columns: id, class_id, name, height, gender, birthday, create_time
08:55:25.975 [main] TRACE s.yangtao.mapper.StudentMapper.selectStudentById - <== Row: 4, 1, zhaoliu, 176.1, 男, 1990-01-01, 2022-07-04 21:08:34
08:55:25.976 [main] DEBUG s.yangtao.mapper.StudentMapper.selectStudentById - <== Total: 1
08:55:25.977 [main] INFO space.yangtao.client.StudentMapperTest - 注解查询:StudentPO(id=4, classId=1, name=zhaoliu, height=176.1, gender=男, birthday=Mon Jan 01 00:00:00 CST 1990, createTime=Mon Jul 04 21:08:34 CST 2022)
08:55:25.978 [main] DEBUG space.yangtao.mapper.StudentMapper.deleteStudent - ==> Preparing: DELETE FROM tt_student WHERE id = ?
08:55:25.978 [main] DEBUG space.yangtao.mapper.StudentMapper.deleteStudent - ==> Parameters: 4(Long)
08:55:25.979 [main] DEBUG space.yangtao.mapper.StudentMapper.deleteStudent - <== Updates: 1
08:55:25.979 [main] INFO space.yangtao.client.StudentMapperTest - 注解删除:1
...

由日志可知,MyBatis已通过@Insert@Delete@Update@Select实现了对数据库的增删改查。

总结

通过本文的介绍,开发者可以明白如何在MyBatis中使用注解来简化数据库操作的配置。尽管注解方式在处理非常复杂的SQL或需要高度灵活性的场景中可能存在局限,但对于大多数应用场景而言,它提供了一种更为直接和清晰的配置方式。对于那些追求快速开发和代码整洁的项目,注解开发无疑是一个优秀的选择。然而,选择使用注解还是传统的XML配置,应根据项目的具体需求和团队的偏好来决定。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!