MyBatis从入门到精通(五):MyBatis 注解方式的基本用法

栏目: Java · 发布时间: 5年前

内容简介:最近在读刘增辉老师所著的《MyBatis从入门到精通》一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸!假设现在有个需求:根据id查询角色信息。使用注解方式该如何实现呢?首先,在接口SysRoleMappper中添加如下方法:

最近在读刘增辉老师所著的《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属性。

MyBatis从入门到精通(五):MyBatis 注解方式的基本用法

按下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 ,欢迎下载。

7. 参考

刘增辉《MyBatis从入门到精通》


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Boolean Reasoning

Boolean Reasoning

Brown, Frank Markham / 2003-4 / $ 19.15

A systematic treatment of Boolean reasoning, this concise, newly revised edition combines the works of early logicians with recent investigations, including previously unpublished research results. Th......一起来看看 《Boolean Reasoning》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

html转js在线工具
html转js在线工具

html转js在线工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具