上面一篇博文介绍了mybatis + xml配置文件的使用方式,在上文中介绍到,xml文件是可以省略掉的,直接使用java注解来实现CURD,接下来我们看一下,如何使用注解来实现等同的效果
I. Mybatis注解开发
关于项目环境的搭建与前文一致,如有疑问,查看博文:
1. 基础配置
用于测试的数据库
CREATE TABLE `money` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名', `money` int(26) NOT NULL DEFAULT '0' COMMENT '钱', `is_deleted` tinyint(1) NOT NULL DEFAULT '0', `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), KEY `name` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=551 DEFAULT CHARSET=utf8mb4; 复制代码
对应的数据库实体类 MoneyPO
@Data @NoArgsConstructor @AllArgsConstructor public class MoneyPo { private Integer id; private String name; private Long money; private Integer isDeleted; private Timestamp createAt; private Timestamp updateAt; } 复制代码
Mapper接口类
@Mapper public interface MoneyMapper { } 复制代码
注意与前文的区别,这里我们没有xml文件
2. 数据插入
新增数据,使用注解 @Insert
,直接放在接口中定义的方法上即可
/** * 保存数据,并保存主键id * * @param po * @return int */ @Options(useGeneratedKeys = true, keyProperty = "po.id", keyColumn = "id") @Insert("insert into money (name, money, is_deleted) values (#{po.name}, #{po.money}, #{po.isDeleted})") int save(@Param("po") MoneyPo po); 复制代码
@Insert
注解中的内容与前面xml中标签内容一致,没有什么区别,重点关注一下 @Options
注解,用来指定一些配置信息,比如上面的case,就用来配置将插入的id,保存到参数MoneyPo的id字段上
3. 查询数据
查询则使用@Select
注解
/** * 主键查询 * * @param id id * @return {@link MoneyPo} */ @Select("select * from money where id = #{id}") @Results(id = "moneyResultMap", value = { @Result(property = "id", column = "id", id = true, jdbcType = JdbcType.INTEGER), @Result(property = "name", column = "name", jdbcType = JdbcType.VARCHAR), @Result(property = "money", column = "money", jdbcType = JdbcType.INTEGER), @Result(property = "isDeleted", column = "is_deleted", jdbcType = JdbcType.TINYINT), @Result(property = "createAt", column = "create_at", jdbcType = JdbcType.TIMESTAMP), @Result(property = "updateAt", column = "update_at", jdbcType = JdbcType.TIMESTAMP)}) MoneyPo getById(@Param("id") int id); 复制代码
select注解没有什么特别的,重点关注一下@Results
注解
这个注解的作用,与xml中的<resultMap>
标签功能一直,通过内部的@Result
来指定数据库表结构与java实体类的映射关系,最外层的id主要用于复用
@Select("select * from money where `name` = #{name}") @ResultMap(value = "moneyResultMap") MoneyPo getByName(@Param("name") String name); 复制代码
4. 数据更新
直接给出对应的case
/** * 更新 * * @param id id * @param money 钱 * @return int */ @Update("update money set `money`=#{money} where id = #{id}") int addMoney(@Param("id") int id, @Param("money") long money); 复制代码
5. 数据删除
/** * 删除数据 * * @param id id * @return int */ @Delete("delete from money where id = #{id}") int delete(@Param("id") int id); 复制代码
6. 小结
从注解的使用来看,与xml文件的方式基本上没有什么区别,当然从上面的示例来说,貌似使用注解的方式更加简洁,毕竟sql语句直接放在方法上,不需要像之前那样,两个文件来回切换
但是,请注意,注解的使用姿势并没有特别广泛使用也是有原因的,上面只是一些简单接触的case,当sql语句比较复杂的时,注解的方式写起来就没有那么爽快了
如in查询
/** * foreach 查询 * * @param ids * @return */ @Select("<script> select * from money where id in " + "<foreach collection='ids' index='index' item='id' open='(' separator=',' close=')'>" + "#{id}" + "</foreach></script>") List<MoneyPo> getByIds(@Param("ids") List<Integer> ids); 复制代码
注解上的内容太多,特别是上面的字符串拼接方式,会极大的影响阅读体验;当然在jdk14的新特性中,提供了文本块的支持,类似pyton中使用三个双引号来标注一个大的文本块,然而现实的是,实际上又有多少项目升级到了jdk14呢?