mybatis-annotations model


1. 概述

本文,我們來分享 MyBatis 的注解模塊,對應 annotations 包。如下圖所示:`annotations` 包

在 《精盡 MyBatis 源碼解析 —— 項目結構一覽》 中,簡單介紹了這個模塊如下:

隨着 Java 注解的慢慢流行,MyBatis 提供了注解的方式,使得我們方便的在 Mapper 接口上編寫簡單的數據庫 SQL 操作代碼,而無需像之前一樣,必須編寫 SQL 在 XML 格式的 Mapper 文件中。雖然說,實際場景下,大家還是喜歡在 XML 格式的 Mapper 文件中編寫響應的 SQL 操作。

注解比較多,艿艿盡量對它們的用途,進行規整。

另外,想要看 MyBatis 注解文檔的胖友,可以看看 《MyBatis 文檔 —— Java API》 。

艿艿的補充:在寫完本文后,發現田守枝對注解的整理更好,引用如下:

FROM 《mybatis 注解配置詳解》

  • 增刪改查: @Insert、@Update、@Delete、@Select、@MapKey、@Options、@SelelctKey、@Param、@InsertProvider、@UpdateProvider、@DeleteProvider、@SelectProvider
  • 結果集映射: @Results、@Result、@ResultMap、@ResultType、@ConstructorArgs、@Arg、@One、@Many、@TypeDiscriminator、@Case
  • 緩存: @CacheNamespace、@Property、@CacheNamespaceRef、@Flush

2. CRUD 常用操作注解

示例如下:

package com.whut.inter;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.whut.model.User;

// 最基本的注解CRUD
public interface IUserDAO {

@Select("select *from User")
public List<User> retrieveAllUsers();

//注意這里只有一個參數,則#{}中的標識符可以任意取
@Select("select *from User where id=#{idss}")
public User retrieveUserById(int id);

@Select("select *from User where id=#{id} and userName like #{name}")
public User retrieveUserByIdAndName(@Param("id")int id,@Param("name")String names);

@Insert("INSERT INTO user(userName,userAge,userAddress) VALUES(#{userName},"
+ "#{userAge},#{userAddress})")
public void addNewUser(User user);

@Delete("delete from user where id=#{id}")
public void deleteUser(int id);

@Update("update user set userName=#{userName},userAddress=#{userAddress}"
+ " where id=#{id}")
public void updateUser(User user);

}

2.1 @Select

org.apache.ibatis.annotations.@Select ,查詢語句注解。代碼如下:

// Select.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 方法
public @interface Select {

/**
* @return 查詢語句
*/
String[] value();

}

2.2 @Insert

org.apache.ibatis.annotations.@Insert ,插入語句注解。代碼如下:

// Insert.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 方法
public @interface Insert {

/**
* @return 插入語句
*/
String[] value();

}

2.3 @Update

org.apache.ibatis.annotations.@Update ,更新語句注解。代碼如下:

// Update.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Update {

/**
* @return 更新語句
*/
String[] value();

}

2.4 @Delete

org.apache.ibatis.annotations.@Delete ,刪除語句注解。代碼如下:

// Delete.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 方法
public @interface Delete {

/**
* @return 刪除語句
*/
String[] value();

}

2.5 @Param

org.apache.ibatis.annotations.@Param ,方法參數名的注解。代碼如下:

當映射器方法需多個參數,這個注解可以被應用於映射器方法參數來給每個參數一個名字。否則,多參數將會以它們的順序位置來被命名。比如 #{1}#{2} 等,這是默認的。

使用 @Param("person") ,SQL 中參數應該被命名為 #{person} 。

// Param.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER) // 參數
public @interface Param {

/**
* @return 參數名
*/
String value();

}

3. CRUD 高級操作注解

示例如下:

  • IBlogDAO 接口:

    package com.whut.inter;
    import java.util.List;
    import org.apache.ibatis.annotations.CacheNamespace;
    import org.apache.ibatis.annotations.DeleteProvider;
    import org.apache.ibatis.annotations.InsertProvider;
    import org.apache.ibatis.annotations.Options;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Result;
    import org.apache.ibatis.annotations.ResultMap;
    import org.apache.ibatis.annotations.Results;
    import org.apache.ibatis.annotations.SelectProvider;
    import org.apache.ibatis.annotations.UpdateProvider;
    import org.apache.ibatis.type.JdbcType;
    import com.whut.model.Blog;
    import com.whut.sqlTool.BlogSqlProvider;

    @CacheNamespace(size=100)
    public interface IBlogDAO {

    @SelectProvider(type = BlogSqlProvider.class, method = "getSql")
    @Results(value ={
    @Result(id=true, property="id",column="id",javaType=Integer.class,jdbcType=JdbcType.INTEGER),
    @Result(property="title",column="title",javaType=String.class,jdbcType=JdbcType.VARCHAR),
    @Result(property="date",column="date",javaType=String.class,jdbcType=JdbcType.VARCHAR),
    @Result(property="authername",column="authername",javaType=String.class,jdbcType=JdbcType.VARCHAR),
    @Result(property="content",column="content",javaType=String.class,jdbcType=JdbcType.VARCHAR),
    })
    public Blog getBlog(@Param("id") int id);

    @SelectProvider(type = BlogSqlProvider.class, method = "getAllSql")
    @Results(value ={
    @Result(id=true, property="id",column="id",javaType=Integer.class,jdbcType=JdbcType.INTEGER),
    @Result(property="title",column="title",javaType=String.class,jdbcType=JdbcType.VARCHAR),
    @Result(property="date",column="date",javaType=String.class,jdbcType=JdbcType.VARCHAR),
    @Result(property="authername",column="authername",javaType=String.class,jdbcType=JdbcType.VARCHAR),
    @Result(property="content",column="content",javaType=String.class,jdbcType=JdbcType.VARCHAR),
    })
    public List<Blog> getAllBlog();

    @SelectProvider(type = BlogSqlProvider.class, method = "getSqlByTitle")
    @ResultMap(value = "sqlBlogsMap")
    // 這里調用resultMap,這個是SQL配置文件中的,必須該SQL配置文件與本接口有相同的全限定名
    // 注意文件中的namespace路徑必須是使用@resultMap的類路徑
    public List<Blog> getBlogByTitle(@Param("title")String title);

    @InsertProvider(type = BlogSqlProvider.class, method = "insertSql")
    public void insertBlog(Blog blog);

    @UpdateProvider(type = BlogSqlProvider.class, method = "updateSql")
    public void updateBlog(Blog blog);

    @DeleteProvider(type = BlogSqlProvider.class, method = "deleteSql")
    @Options(useCache = true, flushCache = false, timeout = 10000)
    public void deleteBlog(int ids);

    }
  • BlogSqlProvider 類:

    package com.whut.sqlTool;
    import java.util.Map;
    import static org.apache.ibatis.jdbc.SqlBuilder.*;
    package com.whut.sqlTool;
    import java.util.Map;
    import static org.apache.ibatis.jdbc.SqlBuilder.*;

    public class BlogSqlProvider {

    private final static String TABLE_NAME = "blog";

    public String getSql(Map<Integer, Object> parameter) {
    BEGIN();
    //SELECT("id,title,authername,date,content");
    SELECT("*");
    FROM(TABLE_NAME);
    //注意這里這種傳遞參數方式,#{}與map中的key對應,而map中的key又是注解param設置的
    WHERE("id = #{id}");
    return SQL();
    }

    public String getAllSql() {
    BEGIN();
    SELECT("*");
    FROM(TABLE_NAME);
    return SQL();
    }

    public String getSqlByTitle(Map<String, Object> parameter) {
    String title = (String) parameter.get("title");
    BEGIN();
    SELECT("*");
    FROM(TABLE_NAME);
    if (title != null)
    WHERE(" title like #{title}");
    return SQL();
    }

    public String insertSql() {
    BEGIN();
    INSERT_INTO(TABLE_NAME);
    VALUES("title", "#{title}");
    // VALUES("title", "#{tt.title}");
    //這里是傳遞一個Blog對象的,如果是利用上面tt.方式,則必須利用Param來設置別名
    VALUES("date", "#{date}");
    VALUES("authername", "#{authername}");
    VALUES("content", "#{content}");
    return SQL();
    }

    public String deleteSql() {
    BEGIN();
    DELETE_FROM(TABLE_NAME);
    WHERE("id = #{id}");
    return SQL();
    }

    public String updateSql() {
    BEGIN();
    UPDATE(TABLE_NAME);
    SET("content = #{content}");
    WHERE("id = #{id}");
    return SQL();
    }
    }
    • 該示例使用 org.apache.ibatis.jdbc.SqlBuilder 來實現 SQL 的拼接與生成。實際上,目前該類已經廢棄,推薦使用個的是 org.apache.ibatis.jdbc.SQL 類。
    • 具體的 SQL 使用示例,可參見 org.apache.ibatis.jdbc.SQLTest 單元測試類。
  • Mapper XML 配置:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.whut.inter.IBlogDAO">
    <resultMap type="Blog" id="sqlBlogsMap">
    <id property="id" column="id"/>
    <result property="title" column="title"/>
    <result property="authername" column="authername"/>
    <result property="date" column="date"/>
    <result property="content" column="content"/>
    </resultMap>
    </mapper>

3.1 @SelectProvider

org.apache.ibatis.annotations.@SelectProvider ,查詢語句提供器。代碼如下:

// SelectProvider.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 方法
public @interface SelectProvider {

/**
* @return 提供的類
*/
Class<?> type();

/**
* @return 提供的方法
*/
String method();

}
  • 從上面的使用示例可知,XXXProvider 的用途是,指定一個類( type )的指定方法( method ),返回使用的 SQL 。並且,該方法可以使用 Map<String,Object> params 來作為方法參數,傳遞參數。

3.2 @InsertProvider

org.apache.ibatis.annotations.@InsertProvider ,插入語句提供器。代碼如下:

// InsertProvider.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 方法
public @interface InsertProvider {

/**
* @return 提供的類
*/
Class<?> type();

/**
* @return 提供的方法
*/
String method();

}

3.3 @UpdateProvider

org.apache.ibatis.annotations.@UpdateProvider ,更新語句提供器。代碼如下:

// UpdateProvider.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 方法
public @interface UpdateProvider {

/**
* @return 提供的類
*/
Class<?> type();

/**
* @return 提供的方法
*/
String method();

}

3.4 @DeleteProvider

org.apache.ibatis.annotations.@DeleteProvider ,刪除語句提供器。代碼如下:

// DeleteProvider.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 方法
public @interface DeleteProvider {

/**
* @return 提供的類
*/
Class<?> type();

/**
* @return 提供的方法
*/
String method();

}

3.5 @Results

org.apache.ibatis.annotations.@Results ,結果的注解。代碼如下:

對應 XML 標簽為 <resultMap />

// Results.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Results {

/**
* The name of the result map.
*/
String id() default "";

/**
* @return {@link Result} 數組
*/
Result[] value() default {};

}

3.6 @Result

org.apache.ibatis.annotations.@Results ,結果字段的注解。代碼如下:

// Result.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Result {

/**
* @return 是否是 ID 字段
*/
boolean id() default false;

/**
* @return Java 類中的屬性
*/
String property() default "";

/**
* @return 數據庫的字段
*/
String column() default "";

/**
* @return Java Type
*/
Class<?> javaType() default void.class;

/**
* @return JDBC Type
*/
JdbcType jdbcType() default JdbcType.UNDEFINED;

/**
* @return 使用的 TypeHandler 處理器
*/
Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;

/**
* @return {@link One} 注解
*/
One one() default @One;

/**
* @return {@link Many} 注解
*/
Many many() default @Many;

}

3.6.1 @One

org.apache.ibatis.annotations.@One ,復雜類型的單獨屬性值的注解。代碼如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface One {

/**
* @return 已映射語句(也就是映射器方法)的全限定名
*/
String select() default "";

/**
* @return 加載類型
*/
FetchType fetchType() default FetchType.DEFAULT;

}

3.6.2 @Many

org.apache.ibatis.annotations.@Many ,復雜類型的集合屬性值的注解。代碼如下:

// Many.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Many {

/**
* @return 已映射語句(也就是映射器方法)的全限定名
*/
String select() default "";

/**
* @return 加載類型
*/
FetchType fetchType() default FetchType.DEFAULT;

}

3.7 @ResultMap

org.apache.ibatis.annotations.@ResultMap ,使用的結果集的注解。代碼如下:

// ResultMap.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 方法
public @interface ResultMap {

/**
* @return 結果集
*/
String[] value();

}
  • 例如上述示例的 #getBlogByTitle(@Param("title")String title) 方法,使用的注解為 @ResultMap(value = "sqlBlogsMap"),而 "sqlBlogsMap" 中 Mapper XML 中有相關的定義。

3.8 @ResultType

org.apache.ibatis.annotations.@ResultType ,結果類型。代碼如下:

// ResultType.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ResultType {

/**
* @return 類型
*/
Class<?> value();

}

3.9 @CacheNamespace

org.apache.ibatis.annotations.@CacheNamespace ,緩存空間配置的注解。代碼如下:

對應 XML 標簽為 <cache />

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) // Mapper 類上
public @interface CacheNamespace {

/**
* @return 負責存儲的 Cache 實現類
*/
Class<? extends org.apache.ibatis.cache.Cache> implementation() default PerpetualCache.class;

/**
* @return 負責過期的 Cache 實現類
*/
Class<? extends org.apache.ibatis.cache.Cache> eviction() default LruCache.class;

/**
* @return 清空緩存的頻率。0 代表不清空
*/
long flushInterval() default 0;

/**
* @return 緩存容器大小
*/
int size() default 1024;

/**
* @return 是否序列化。{@link org.apache.ibatis.cache.decorators.SerializedCache}
*/
boolean readWrite() default true;

/**
* @return 是否阻塞。{@link org.apache.ibatis.cache.decorators.BlockingCache}
*/
boolean blocking() default false;

/**
* Property values for a implementation object.
* @since 3.4.2
*
* {@link Property} 數組
*/
Property[] properties() default {};

}

3.9.1 @Property

org.apache.ibatis.annotations.@Property ,屬性的注解。代碼如下:

// Property.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Property {

/**
* 屬性名
*
* A target property name
*/
String name();

/**
* 屬性值
*
* A property value or placeholder
*/
String value();

}

3.10 @CacheNamespaceRef

org.apache.ibatis.annotations.@CacheNamespaceRef ,指向指定命名空間的注解。代碼如下:

對應 XML 標簽為 <cache-ref />

// CacheNamespaceRef.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) // 類型
public @interface CacheNamespaceRef {

/**
* 見 {@link MapperAnnotationBuilder#parseCacheRef()} 方法
*
* A namespace type to reference a cache (the namespace name become a FQCN of specified type)
*/
Class<?> value() default void.class;

/**
* 指向的命名空間
*
* A namespace name to reference a cache
* @since 3.4.2
*/
String name() default "";

}

3.11 @Options

org.apache.ibatis.annotations.@Options ,操作可選項。代碼如下:

// Options.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Options {

/**
* The options for the {@link Options#flushCache()}.
* The default is {@link FlushCachePolicy#DEFAULT}
*/
enum FlushCachePolicy {
/** <code>false</code> for select statement; <code>true</code> for insert/update/delete statement. */
DEFAULT,
/** Flushes cache regardless of the statement type. */
TRUE,
/** Does not flush cache regardless of the statement type. */
FALSE
}

/**
* @return 是否使用緩存
*/
boolean useCache() default true;

/**
* @return 刷新緩存的策略
*/
FlushCachePolicy flushCache() default FlushCachePolicy.DEFAULT;

/**
* @return 結果類型
*/
ResultSetType resultSetType() default ResultSetType.DEFAULT;

/**
* @return 語句類型
*/
StatementType statementType() default StatementType.PREPARED;

/**
* @return 加載數量
*/
int fetchSize() default -1;

/**
* @return 超時時間
*/
int timeout() default -1;

/**
* @return 是否生成主鍵
*/
boolean useGeneratedKeys() default false;

/**
* @return 主鍵在 Java 類中的屬性
*/
String keyProperty() default "";

/**
* @return 主鍵在數據庫中的字段
*/
String keyColumn() default "";

/**
* @return 結果集
*/
String resultSets() default "";

}

3.12 @SelectKey

org.apache.ibatis.annotations.@SelectKey ,通過 SQL 語句獲得主鍵的注解。代碼如下:

// SelectKey.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SelectKey {

/**
* @return 語句
*/
String[] statement();

/**
* @return {@link #statement()} 的類型
*/
StatementType statementType() default StatementType.PREPARED;

/**
* @return Java 對象的屬性
*/
String keyProperty();

/**
* @return 數據庫的字段
*/
String keyColumn() default "";

/**
* @return 在插入語句執行前,還是執行后
*/
boolean before();

/**
* @return 返回類型
*/
Class<?> resultType();

}

3.13 @MapKey

org.apache.ibatis.annotations.@MapKey ,Map 結果的鍵的注解。代碼如下:

// MapKey.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 方法上
public @interface MapKey {

/**
* @return 鍵名
*/
String value();

}

3.14 @Flush

org.apache.ibatis.annotations.@Flush ,Flush 注解。代碼如下:

如果使用了這個注解,定義在 Mapper 接口中的方法能夠調用 SqlSession#flushStatements() 方法。(Mybatis 3.3及以上)

// Flush.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 方法上
public @interface Flush {
}

4. 其它注解

4.1 @Mapper

org.apache.ibatis.annotations.Mapper ,標記這是個 Mapper 的注解。代碼如下:

// Mapper.java

@Documented
@Inherited
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Mapper {

// Interface Mapper

}

4.2 @Lang

org.apache.ibatis.annotations.@Lang ,語言驅動的注解。代碼如下:

// Lang.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 方法
public @interface Lang {

/**
* @return 驅動類
*/
Class<? extends LanguageDriver> value();

}

4.3 暫時省略

如下幾個注解,暫時省略,使用較少。

  • @TypeDiscriminator + @Case
  • @ConstructorArgs + @Arg
  • @AutomapConstructor


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM