Mybatis之映射器注解详解

9 篇文章 0 订阅
7 篇文章 0 订阅

Mybatis系列文章
Mybatis之配置详解
Mybatis之XML 映射器详解
Mybatis之动态 SQL详解
Mybatis之缓存详解
Mybatis之映射器注解详解
Mybatis之Mybatis Generator vs IDEA插件 自动生成代码

前言

设计初期的 MyBatis 是一个 XML 驱动的框架。配置信息是基于 XML 的,映射语句也是定义在 XML 中的。而在 MyBatis 3 中,我们提供了其它的配置方式。MyBatis 3 构建在全面且强大的基于 Java 语言的配置 API 之上。它是 XML 和注解配置的基础。注解提供了一种简单且低成本的方式来实现简单的映射语句。

接下来我会尽可能全面地讲述映射器注解的用法。但是本文推荐映射器注解用于一些简单的SQL上,相对复杂的SQL仍建议在XML中配置。因为最强大的 MyBatis 映射(例如复杂的关联SQL)并不能用注解来构建,接下来我们来看看究竟Mybatis有哪些注解。

注解

注解使用对象XML等价形式描述
@CacheNamespace<cache>为给定的命名空间(比如类)配置缓存。属性:implemetation、eviction、flushInterval、size、readWrite、blocking、properties。
@PropertyN/A<property>指定参数值或占位符(placeholder)(该占位符能被 mybatis-config.xml 内的配置属性替换)。属性:name、value。
@CacheNamespaceRef<cacheRef>引用另外一个命名空间的缓存以供使用。注意,即使共享相同的全限定类名,在 XML 映射文件中声明的缓存仍被识别为一个独立的命名空间。属性:value、name。如果你使用了这个注解,你应设置 value 或者 name 属性的其中一个。value 属性用于指定能够表示该命名空间的 Java 类型,name 属性则直接指定了命名空间的名字。
@ConstructorArgs方法<constructor>收集一组结果以传递给一个结果对象的构造方法。属性:value,它是一个 Arg 数组。
@ArgN/A<arg> <idArg>ConstructorArgs 集合的一部分,代表一个构造方法参数。属性:id、column、javaType、jdbcType、typeHandler、select、resultMap。id 属性和 XML 元素 <idArg> 相似,它是一个布尔值,表示该属性是否用于唯一标识和比较对象。
@TypeDiscriminator方法<discriminator>决定使用何种结果映射的一组取值(case)。属性:column、javaType、jdbcType、typeHandler、cases。cases 属性是一个 Case 的数组。
@CaseN/A<case>表示某个值的一个取值以及该取值对应的映射。属性:value、type、results。results 属性是一个 Results 的数组,因此这个注解实际上和 ResultMap 很相似,由下面的 Results 注解指定。
@Results方法<resultMap>一组结果映射,指定了对某个特定结果列,映射到某个属性或字段的方式。属性:value、id。value 属性是一个 Result 注解的数组。而 id 属性则是结果映射的名称。
@ResultN/A<result> <id>在列和属性或字段之间的单个结果映射。属性:id、column、javaType、jdbcType、typeHandler、one、many。id 属性和 XML 元素 <id> 相似,它是一个布尔值,表示该属性是否用于唯一标识和比较对象。one 属性是一个关联,和 <association> 类似,而 many 属性则是集合关联,和 <collection> 类似。这样命名是为了避免产生名称冲突。
@OneN/A<association>复杂类型的单个属性映射。属性:select,指定可加载合适类型实例的映射语句全限定名;fetchType,指定在该映射中覆盖全局配置参数 lazyLoadingEnabled。提示 注解 API 不支持联合映射。这是由于 Java 注解不允许产生循环引用。
@ManyN/A<collection>复杂类型的集合属性映射。属性:select,指定可加载合适类型实例集合的映射语句全限定名;fetchType,指定在该映射中覆盖全局配置参数 lazyLoadingEnabled。提示 注解 API 不支持联合映射。这是由于 Java 注解不允许产生循环引用。
@MapKey方法供返回值为 Map 的方法使用的注解。它使用对象的某个属性作为 key,将对象 List 转化为 Map。属性:value,指定作为 Map 的 key 值的对象属性名。
@Options方法映射语句的属性该注解允许你指定大部分开关和配置选项,它们通常在映射语句上作为属性出现。与在注解上提供大量的属性相比,Options 注解提供了一致、清晰的方式来指定选项。属性:useCache=true、flushCache=FlushCachePolicy.DEFAULT、resultSetType=DEFAULT、statementType=PREPARED、fetchSize=-1、timeout=-1、useGeneratedKeys=false、keyProperty=""、keyColumn=""、resultSets=""。注意,Java 注解无法指定 null 值。因此,一旦你使用了 Options 注解,你的语句就会被上述属性的默认值所影响。要注意避免默认值带来的非预期行为。
@Insert @Update @Delete @Select方法<insert> <update> <delete> <select>每个注解分别代表将会被执行的 SQL 语句。它们用字符串数组(或单个字符串)作为参数。如果传递的是字符串数组,字符串数组会被连接成单个完整的字符串,每个字符串之间加入一个空格。这有效地避免了用 Java 代码构建 SQL 语句时产生的“丢失空格”问题。当然,你也可以提前手动连接好字符串。属性:value,指定用来组成单个 SQL 语句的字符串数组。
@InsertProvider @UpdateProvider @DeleteProvider @SelectProvider方法<insert> <update> <delete> <select>允许构建动态 SQL。这些备选的 SQL 注解允许你指定返回 SQL 语句的类和方法,以供运行时执行。(从 MyBatis 3.4.6 开始,可以使用 CharSequence 代替 String 来作为返回类型)。当执行映射语句时,MyBatis 会实例化注解指定的类,并调用注解指定的方法。你可以通过 ProviderContext 传递映射方法接收到的参数、“Mapper interface type” 和 “Mapper method”(仅在 MyBatis 3.4.5 以上支持)作为参数。(MyBatis 3.4 以上支持传入多个参数)属性:type、method。type 属性用于指定类名。method 用于指定该类的方法名(从版本 3.5.1 开始,可以省略 method 属性,MyBatis 将会使用 ProviderMethodResolver 接口解析方法的具体实现。如果解析失败,MyBatis 将会使用名为 provideSql 的降级实现)。
@Param参数N/A如果你的映射方法接受多个参数,就可以使用这个注解自定义每个参数的名字。否则在默认情况下,除 RowBounds 以外的参数会以 “param” 加参数位置被命名。例如 #{param1}, #{param2}。如果使用了 @Param(“person”),参数就会被命名为 #{person}。
@SelectKey方法<selectKey>这个注解的功能与 <selectKey> 标签完全一致。该注解只能在 @Insert 或 @InsertProvider 或 @Update 或 @UpdateProvider 标注的方法上使用,否则将会被忽略。如果标注了 @SelectKey 注解,MyBatis 将会忽略掉由 @Options 注解所设置的生成主键或设置(configuration)属性。属性:statement 以字符串数组形式指定将会被执行的 SQL 语句,keyProperty 指定作为参数传入的对象对应属性的名称,该属性将会更新成新的值,before 可以指定为 true 或 false 以指明 SQL 语句应被在插入语句的之前还是之后执行。resultType 则指定 keyProperty 的 Java 类型。statementType 则用于选择语句类型,可以选择 STATEMENT、PREPARED 或 CALLABLE 之一,它们分别对应于 Statement、PreparedStatement 和 CallableStatement。默认值是 PREPARED。
@ResultMap方法N/A这个注解为 @Select 或者 @SelectProvider 注解指定 XML 映射中 <resultMap> 元素的 id。这使得注解的 select 可以复用已在 XML 中定义的 ResultMap。如果标注的 select 注解中存在 @Results 或者 @ConstructorArgs 注解,这两个注解将被此注解覆盖。
@ResultType方法N/A在使用了结果处理器的情况下,需要使用此注解。由于此时的返回类型为 void,所以 Mybatis 需要有一种方法来判断每一行返回的对象类型。如果在 XML 有对应的结果映射,请使用 @ResultMap注解。如果结果类型在 XML 的 <select> 元素中指定了,就不需要使用其它注解了。否则就需要使用此注解。比如,如果一个标注了 @Select 的方法想要使用结果处理器,那么它的返回类型必须是 void,并且必须使用这个注解(或者 @ResultMap)。这个注解仅在方法返回类型是 void 的情况下生效。
@Flush方法N/A如果使用了这个注解,定义在 Mapper 接口中的方法就能够调用 SqlSession#flushStatements() 方法。

实战演练

下面这些例子仅覆盖了部分注解,如果你想要了解的注解没有,不妨结合上面注解的解释,自己去试试。

@Insert、@SelectKey

插入一条学生数据,并返回插入id的值

@Insert(value = {"insert into student(name, age, sex, school_id, enter_score) value ",
        "(#{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}, #{sex,jdbcType=VARCHAR}, ",
        "#{schoolId,jdbcType=BIGINT}, #{enterScore,jdbcType=NUMERIC})"})
@SelectKey(before = false, keyProperty = "id", keyColumn = "id", resultType = Long.class, statement = "select " +
        "last_insert_id()")
int insertOneWithAnnotation(Student student);

@Select、@Results、@One

查询出学生信息以及所属学校的信息

@Select("select id, name, age, sex, enter_score, create_time, update_time, school_id from student")
@Results(value = {@Result(id = true, column = "id", property = "id"),
        @Result(column = "name", property = "name"), @Result(column = "school_id", property = "school", one =
@One(select = "com.nestor.mybatisdemo.mapper.SchoolMapper.selectById"))})
List<StudentDTO> selectStudentWithSchoolUseAnnotation();

@DeleteProvider

动态删除,type定义动态SQL存放类,method指定使用哪个方法返回的SQL。如果不使用@Param,就应该定义与 mapper 方法相同的参数,如果使用 @Param,就可以只定义需要使用的参数。

@DeleteProvider(type = DynamicSqlProvider.class, method = "deleteStudentSelective")
int deleteStudentSelective(@Param("name") String name1, @Param("age") Integer age1);
public class DynamicSqlProvider {
    public String deleteStudentSelective(String name, Integer age) {
        return new SQL() {
            {
                DELETE_FROM("student");
                if (!StringUtils.isEmpty(name)) {
                    WHERE("name = #{name,jdbcType=VARCHAR}");
                }
                if (!ObjectUtils.isEmpty(age)) {
                    WHERE("age = #{age,jdbcType=INTEGER}");
                }
            }
        }.toString();
    }
}

@UpdateProvider

动态更新,以下例子展示了ProviderMethodResolver(3.5.1 后可用)的默认实现使用方法:在你的 provider 类中实现 ProviderMethodResolver 接口,默认实现中,会将映射器方法的调用解析到实现的同名方法上

@UpdateProvider(SqlProviderMethodResolver.class)
int updateStduentSelective(Student student);
public class SqlProviderMethodResolver implements ProviderMethodResolver {
    public String updateStduentSelective(Student student) {
        return new SQL() {
            {
                UPDATE("student");
                if (!ObjectUtils.isEmpty(student.getName())) {
                    SET("name = #{name,jdbcType=VARCHAR}");
                }
                if (!ObjectUtils.isEmpty(student.getAge())) {
                    SET("age = #{age,jdbcType=INTEGER}");
                }
                if (!ObjectUtils.isEmpty(student.getSex())) {
                    SET("sex = #{sex,jdbcType=VARCHAR}");
                }
                if (!ObjectUtils.isEmpty(student.getEnterScore())) {
                    SET("enter_score = #{enterScore,jdbcType=NUMERIC}");
                }
                if (!ObjectUtils.isEmpty(student.getSchoolId())) {
                    SET("school_id = #{schoolId,jdbcType=BIGINT}");
                }
                WHERE("id = #{id,jdbcType=BIGINT}");
            }
        }.toString();
    }
}

github工程地址https://github.com/nestorbian/spring-boot-examples/tree/master/mybatis-demo

Mybatis系列文章
Mybatis之配置详解
Mybatis之XML 映射器详解
Mybatis之动态 SQL详解
Mybatis之缓存详解
Mybatis之映射器注解详解
Mybatis之Mybatis Generator vs IDEA插件 自动生成代码

参考:
Mybatis3官网 Java API
Mybatis3官网 SQL 语句构建器

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值