MyBatis从入门到精通(五):MyBatis 注解方式的基本用法
1. @Select 注解
1.1 使用Sql语句设置别名方式
假设现在有个需求:根据id查询角色信息。使用注解方式该如何实现呢?
首先,在接口SysRoleMappper中添加如下方法:
@Select({"SELECT id,role_name roleName,enabled,create_by createBy,create_time createTime ","FROM sys_role ","WHERE id = #{id}"})
SysRole selectById(Long id);
上面的代码也可以写成如下格式:
@Select({"SELECT id,role_name roleName,enabled,create_by createBy,create_time createTime FROM sys_role WHERE id = #{id}"})
SysRole selectById(Long id);
以上2种方式都是传递字符串数组的形式,我们还可以用直接传递字符串的形式:
@Select("SELECT id,role_name roleName,enabled,create_by createBy,create_time createTime FROM sys_role WHERE id = #{id}")
SysRole selectById(Long id);
使用注解方式同样需要考虑表字段和Java属性字段映射的问题,使用注解方式主要有3种方式来实现。
第1种方式是通过Sql语句设置别名,上面的代码就用的是这种方式。
1.2 使用 mapUnderscoreToCamelCase 配置方式
打开src/main/resources目录下我们之前新建的mybatis-config.xml文件,添加如下配置:
<settings>
<!--其他配置-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
该配置打开后,MyBatis会按照“下划线转驼峰“规则自动映射,即将数据库列role_name自动转换为属性roleName。
此时,上面的代码可以修改为:
@Select("SELECT id,role_name,enabled,create_by,create_time FROM sys_role WHERE id = #{id}")
SysRole selectById(Long id);
虽然也可以写为如下格式,但是不推荐这么使用:
@Select("SELECT * FROM sys_role WHERE id = #{id}")
SysRole selectById(Long id);
1.3 使用 resultMap 方式
在xml中,我们使用过resultMap来配置映射:
<resultMap id="sysUserMap" type="com.zwwhnly.mybatisaction.model.SysUser">
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
<result property="userPassword" column="user_password"/>
<result property="userEmail" column="user_email"/>
<result property="userInfo" column="user_info"/>
<result property="headImg" column="head_img" jdbcType="BLOB"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
</resultMap>
在注解方式中,有一个对应的注解@Results来配置映射:
@Results({
@Result(property = "id", column = "id", id = true),
@Result(property = "roleName", column = "role_name"),
@Result(property = "enabled", column = "enabled"),
@Result(property = "createBy", column = "create_by"),
@Result(property = "createTime", column = "create_time")
})
@Select("SELECT id,role_name,enabled,create_by,create_time FROM sys_role WHERE id = #{id}")
SysRole selectById2(Long id);
代码简单讲解:
1)@Results注解对应着xml中的resultMap标签
2)@Result对应着xml中的result标签
3)@Result(property = "id", column = "id", id = true)对应着xml中的<id property="id" column="id"/>
也许有人会问,我在xml中,为resultMap设置了一个id,这样我就能复用该resultMap了,在注解方式中,支持吗?
带着这个疑问,让我们来试着修改下代码:
@Results(id = "roleResultMap", value = {
@Result(property = "id", column = "id", id = true),
@Result(property = "roleName", column = "role_name"),
@Result(property = "enabled", column = "enabled"),
@Result(property = "createBy", column = "create_by"),
@Result(property = "createTime", column = "create_time")
})
@Select("SELECT id,role_name,enabled,create_by,create_time FROM sys_role WHERE id = #{id}")
SysRole selectById2(Long id);
结果发现代码编译错误,找不到id属性。

按下Ctrl+B,发现@Results的源码如下:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Results {
Result[] value() default {};
}
从源码我们可以发现,这个注解没有id属性,难道我们每个方法上都要加上重复的映射吗?
答案当然是否定的,不过在MyBatis 3.3.0及以前的版本中,注解定义的@Results不能共用,需要在每一个方法上都写一遍。但是从MyBatis 3.3.1版本开始,@Results注解增加了一个id属性,设置了id属性后,就可以通过id属性引用同一个@Results配置了。
看过之前几篇博客的读者可能知道,我们的MyBatis 刚好使用的是3.3.0版本,所以刚好不支持设置id属性,哈哈。
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
修改MyBatis的版本为3.3.1(如果没有设置自动导入变化的话,需要手动点下Import Changes):
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.1</version>
</dependency>
这时会发现,上面原本编译报错的代码可以编译通过了。
此时@Results的源码如下,相比于之前的代码,增加了id属性:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Results {
String id() default "";
Result[] value() default {};
}
那如何引用这个@Results注解呢?请看如下代码:
@ResultMap("roleResultMap")
@Select("SELECT * FROM sys_role")
List<SysRole> selectAll();
说明:当配合XML方式使用的时候,这里引用的id值还可以是XML中resultMap元素的id属性值。
为了使篇幅不至于过长,这里不再贴出这3个方法的单元测试代码和输出日志,相信看过前几篇博客的读者已经可以自己写出单元测试代码了,也可以参考文末的源码地址下载下源码。
2. @Insert 注解
2.1 不需要返回主键
和XML中的使用方式几乎一样,代码如下:
@Insert({"INSERT INTO sys_role(id, role_name, enabled, create_by, create_time) ",
"VALUES (#{id},#{roleName},#{enabled},#{createBy},#{createTime,jdbcType=TIMESTAMP})"})
int insert(SysRole sysRole);
2.2 返回自增主键
如果需要返回数据库的自增主键,代码如下:
@Insert({"INSERT INTO sys_role(role_name, enabled, create_by, create_time) ",
"VALUES (#{roleName},#{enabled},#{createBy},#{createTime,jdbcType=TIMESTAMP})"})
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertUseGeneratedKeys(SysRole sysRole);
和XML中的使用方式差不多,@Options(useGeneratedKeys = true, keyProperty = "id")等价于XML中的useGeneratedKeys="true" keyProperty="id"。
2.3 返回非自增主键
在之前的博客中,我们知道selectKey既支持主键自增的数据库,比如MySql,也支持主键不自增的数据库,如Oracle,在XML中的写法是这样的:
<selectKey keyColumn="id" resultType="long" keyProperty="id" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
那么使用注解方式该如何实现呢?代码如下所示:
@Insert({"INSERT INTO sys_role(role_name, enabled, create_by, create_time) ",
"VALUES (#{roleName},#{enabled},#{createBy},#{createTime,jdbcType=TIMESTAMP})"})
@SelectKey(statement = "SELECT LAST_INSERT_ID()", keyColumn = "id", keyProperty = "id", resultType = Long.class, before = false)
int insertUseSelectKey(SysRole sysRole);
before = false相当于XML中的order="AFTRE",这是MySql数据库的配置。
before = true相当于XML中的order="BEFORE",这是Oracle数据库的配置。
注意事项:不同的数据库statement的值会不同,上面中的值适用于MySql数据库,使用其他类型的数据库时要注意修改。
3. @Update 注解
和XML中的使用方式几乎一样,代码如下:
@Update({"UPDATE sys_role ", "SET role_name = #{roleName},enabled = #{enabled},create_by=#{createBy}, ",
"create_time=#{createTime,jdbcType=TIMESTAMP} ", " WHERE id=#{id}"})
int updateById(SysRole sysRole);
4. @Delete 注解
和XML中的使用方式几乎一样,代码如下:
@Delete("DELETE FROM sys_role WHERE id = #{id}")
int deleteById(Long id);
5. Provider注解
MyBatis提供了4种Provider注解,分别是@SelectProvider、@InsertProvider、@UpdateProvider和@DeleteProvider。
我们以@SelectProvider为例了解下Provider注解的使用方法。
首先在com.zwwhnly.mybatisaction.mapper包下新建如下类:
package com.zwwhnly.mybatisaction.mapper;
import org.apache.ibatis.jdbc.SQL;
public class SysPrivilegeProvider {
public String selectById(final Long id) {
return new SQL() {
{
SELECT("id,privilege_name,privilege_url");
FROM("sys_privilege");
WHERE("id = #{id}");
}
}.toString();
}
}
以上代码也可以写成如下方式:
public String selectById(final Long id) {
return "SELECT id,privilege_name,privilege_url FROM sys_privilege WHERE id = #{id}";
}
然后在接口SysPrivilegeProvider中添加如下方法:
@SelectProvider(type = SysPrivilegeProvider.class, method = "selectById")
SysPrivilege selectById(Long id);
最后在src/test/java下的com.zwwhnly.mybatisaction.mapper包下新建测试类SysPrivilegeMapperTest:
package com.zwwhnly.mybatisaction.mapper;
import com.zwwhnly.mybatisaction.model.SysPrivilege;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.Test;
public class SysPrivilegeMapperTest extends BaseMapperTest {
@Test
public void testSelectById() {
SqlSession sqlSession = getSqlSession();
try {
SysPrivilegeMapper sysPrivilegeMapper = sqlSession.getMapper(SysPrivilegeMapper.class);
SysPrivilege sysPrivilege = sysPrivilegeMapper.selectById(1L);
Assert.assertNotNull(sysPrivilege);
Assert.assertEquals("用户管理", sysPrivilege.getPrivilegeName());
} finally {
sqlSession.close();
}
}
}
运行测试代码,测试通过,输出日志如下:
DEBUG [main] - ==> Preparing: SELECT id,privilege_name,privilege_url FROM sys_privilege WHERE (id = ?)
DEBUG [main] - ==> Parameters: 1(Long)TRACE [main] - <== Columns: id, privilege_name, privilege_url
TRACE [main] - <== Row: 1, 用户管理, /users
DEBUG [main] - <== Total: 1
6. 源码及参考
源码地址:https://github.com/zwwhnly/mybatis-action.git,欢迎下载。
刘增辉《MyBatis从入门到精通》
MyBatis从入门到精通(五):MyBatis 注解方式的基本用法的更多相关文章
- MyBatis从入门到精通:使用XML方式(映射文件之类的)
2.3节笔记部分: package tk.mybatis.simple; public class Temp { } /* 2.2 使用XML方式 MyBatis使用了Java的动态代理可以直接通过接 ...
- MyBatis从入门到精通(第3章):MyBatis注解方式的基本使用
MyBatis 注解方式就是将 SQL 语句直接写在DAO层的接口上. 在黑马录制的2018年双元视频课:\08 SSM整合案例[企业权限管理系统]\07.订单操作 有使用MyBatis注解进行多表 ...
- MyBatis从入门到精通(一):MyBatis入门
最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. MyBatis简介 2001 ...
- MyBatis从入门到精通(三):MyBatis XML方式的基本用法之多表查询
最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. 多表查询 上篇博客中,我们示例的 ...
- MyBatis从入门到精通(1):MyBatis入门
作为一个自学Java的自动化专业211大学本科生,在学习和实践过程中"趟了不少雷",所以有志于建立一个适合同样有热情学习Java技术的参考"排雷手册". 最近在 ...
- MyBatis从入门到精通(第9章):Spring集成MyBatis(下)
MyBatis从入门到精通(第9章):Spring集成MyBatis(下) springmvc执行流程原理 mybatis-spring 可以帮助我们将MyBatis代码无缝整合到Spring中.使 ...
- MyBatis从入门到精通(第9章):Spring集成MyBatis(中)
MyBatis从入门到精通(第9章):Spring集成MyBatis(中) 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法.应该将应用自身的设计和具体 ...
- MyBatis从入门到精通(第9章):Spring集成MyBatis(上)
MyBatis从入门到精通(第9章):Spring集成MyBatis(上) Spring是一个为了解决企业级Web应用开发过程中面临的复杂性,而被创建的一个非常流行的轻量级框架. mybatis-sp ...
- MyBatis基础入门《十五》ResultMap子元素(collection)
MyBatis基础入门<十五>ResultMap子元素(collection) 描述: 见<MyBatis基础入门<十四>ResultMap子元素(association ...
随机推荐
- 简明Python3教程 18.下一步是什么
如果你有认真通读本书之前的内容并且实践其中包含的大量例程,那么你现在一定可以熟练使用python了. 同时你可能也编写了一些程序用于验证python特性并提高你的python技能.如果还没有这样做的话 ...
- Chrome扩展,应用开发学习笔记之2---恶搞百度一下
Chrome扩展,应用开发学习笔记之2 恶搞百度一下 前面我们介绍了一个最简单的chrome扩展时钟,如今我来介绍一下一个恶搞百度一下的chrome扩展程序. 前面说过,manifest.json文件 ...
- The bundle does not contain an app icon for iPhone / iPod Touch of exactly '120x120' pixels, in .pn
xcode 6.3 载发生时的应用'Missing recommended icon file - The bundle does not contain an app icon for iPhone ...
- ASP.NET Core 中间件 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 中间件 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 中间件 上一章节中,我们我们有讲到 Startup 类中的 Confi ...
- 信小程序支付(C#后台+前台)
今天为大家带来比较简单的支付后台处理 首先下载官方的c#模板(WxPayAPI),将模板(WxPayAPI)添加到服务器上,然后在WxPayAPI项目目录中添加两个“一般处理程序” (改名为GetOp ...
- 傻瓜突破linux--rootpassword
破password该方法: 方法1.单用户模式改动 (表示进入到单用户模式) ,按回车键,按b键启动.进入单用户模式.进行password改动,重新启动 init 5 口诀:e2e 空格1 回车b 开 ...
- malloc()与calloc差异
Both the malloc() and the calloc() functions are used to allocate dynamic memory. Each operates slig ...
- WPF 4 DataGrid 控件(基本功能篇)
原文:WPF 4 DataGrid 控件(基本功能篇) 提到DataGrid 不管是网页还是应用程序开发都会频繁使用.通过它我们可以灵活的在行与列间显示各种数据.本篇将详细介绍WPF 4 中 ...
- MultiBinding
<StackPanel> <Slider x:Name="sl1" Minimum="10" Maximum="100"/ ...
- UWP使用AppService向另一个UWP客户端应用程序提供服务
原文:UWP使用AppService向另一个UWP客户端应用程序提供服务 在上篇里,我使用的是寄宿在WPF上的WCF进行两个程序间的通信,在解决问题的同时,我的同事也在思考能否使用UWP来做这件事.于 ...