1 Star 0 Fork 165

shk / Java-Review

forked from icanci / Java-Review 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
SSM-Mybatis3-源码解读-第12篇-注解模块.md 21.26 KB
一键复制 编辑 原始数据 按行查看 历史
icanci 提交于 2020-09-07 10:22 . :zap:更新文件名称

SSM - Mybatis3 - 源码解读 - 第12篇 - 注解模块

概述

  • Mybatis的 注解模块。对应 annotations

1599397283198

  • 随着 Java 注解的慢慢流行,MyBatis 提供了注解的方式,使得我们方便的在 Mapper 接口上编写简单的数据库 SQL 操作代码,而无需像之前一样,必须编写 SQL 在 XML 格式的 Mapper 文件中。虽然说,实际场景下,大家还是喜欢在 XML 格式的 Mapper 文件中编写响应的 SQL 操作。
  • 增删改查: @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
  • 推荐阅读:

CRUD 常用操作注解

  • 示例如下
// 最基本的注解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);

}
@Select
  • org.apache.ibatis.annotations.@Select ,查询语句注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(Select.List.class)
public @interface Select {
    
    String[] value();

    String databaseId() default "";
    
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface List {
        Select[] value();
    }

}
@Insert
  • org.apache.ibatis.annotations.@Insert ,插入语句注解。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(Insert.List.class)
public @interface Insert {
    
    String[] value();

    String databaseId() default "";

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface List {
        Insert[] value();
    }

}
@Update
  • org.apache.ibatis.annotations.@Update ,更新语句注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(Update.List.class)
public @interface Update {

    String[] value();

    String databaseId() default "";

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface List {
        Update[] value();
    }

}
@Delete
  • org.apache.ibatis.annotations.@Delete ,删除语句注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(Delete.List.class)
public @interface Delete {
    
    String[] value();

    String databaseId() default "";

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface List {
        Delete[] value();
    }

}
@Param
  • org.apache.ibatis.annotations.@Param ,方法参数名的注解
  • 当映射器方法需多个参数,这个注解可以被应用于映射器方法参数来给每个参数一个名字。否则,多参数将会以它们的顺序位置来被命名。比如 #{1}#{2} 等,这是默认的。
  • 使用 @Param("person") ,SQL 中参数应该被命名为 #{person}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Param {
    /**
   * Returns the parameter name.
   *
   * @return the parameter name
   */
    String value();
}

CRUD 高级操作注解

  • 示例如下
  • IBlogDAO接口
@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 类
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();
    }
}
  • 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="cn.icanci.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>
@SelectProvider
  • org.apache.ibatis.annotations.@SelectProvider ,查询语句提供器
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(SelectProvider.List.class)
public @interface SelectProvider {

    Class<?> value() default void.class;

    // 提供的类
    Class<?> type() default void.class;

    // 提供的方法
    String method() default "";

    /**
   * @return A database id that correspond this provider
   * @since 3.5.5
   */
    String databaseId() default "";

    /**
   * The container annotation for {@link SelectProvider}.
   * @author Kazuki Shimizu
   * @since 3.5.5
   */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface List {
        SelectProvider[] value();
    }

}
  • 从上面的使用示例可知,XXXProvider 的用途是,指定一个类( type )的指定方法( method ),返回使用的 SQL 。并且,该方法可以使用 Map params 来作为方法参数,传递参数
@InsertProvider
  • org.apache.ibatis.annotations.@InsertProvider ,插入语句提供器
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(InsertProvider.List.class)
public @interface InsertProvider {

    /**
   * Specify a type that implements an SQL provider method.
   *
   * @return a type that implements an SQL provider method
   * @since 3.5.2
   * @see #type()
   */
    // 提供的类
    Class<?> value() default void.class;

    Class<?> type() default void.class;

    // 提供的方法
    String method() default "";

    /**
   * @return A database id that correspond this provider
   * @since 3.5.5
   */
    String databaseId() default "";

    /**
   * The container annotation for {@link InsertProvider}.
   * @author Kazuki Shimizu
   * @since 3.5.5
   */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface List {
        InsertProvider[] value();
    }

}
@UpdateProvider
  • org.apache.ibatis.annotations.@UpdateProvider ,更新语句提供器
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(UpdateProvider.List.class)
public @interface UpdateProvider {

    /**
   * Specify a type that implements an SQL provider method.
   *
   * @return a type that implements an SQL provider method
   * @since 3.5.2
   * @see #type()
   */
    Class<?> value() default void.class;

    // 类的类型
    Class<?> type() default void.class;

    // 方法的值
    String method() default "";

    /**
   * @return A database id that correspond this provider
   * @since 3.5.5
   */
    String databaseId() default "";

    /**
   * The container annotation for {@link UpdateProvider}.
   * @author Kazuki Shimizu
   * @since 3.5.5
   */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface List {
        UpdateProvider[] value();
    }

}
@DeleteProvider
  • org.apache.ibatis.annotations.@DeleteProvider ,删除语句提供器
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(DeleteProvider.List.class)
public @interface DeleteProvider {

    /**
   * Specify a type that implements an SQL provider method.
   *
   * @return a type that implements an SQL provider method
   * @since 3.5.2
   * @see #type()
   */
    Class<?> value() default void.class;

    // 类型
    Class<?> type() default void.class;

    // 方法
    String method() default "";

    /**
   * @return A database id that correspond this provider
   * @since 3.5.5
   */
    String databaseId() default "";

    /**
   * The container annotation for {@link DeleteProvider}.
   * @author Kazuki Shimizu
   * @since 3.5.5
   */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface List {
        DeleteProvider[] value();
    }

}
@Results
  • org.apache.ibatis.annotations.@Results ,结果的注解。
  • 对应 XML 标签为
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Results {
 
    // resultMap 的id
    String id() default "";

    // Result 数组
    Result[] value() default {};
}
@Result
  • org.apache.ibatis.annotations.@Results ,结果字段的注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(Results.class)
public @interface Result {
    // 是否是id字段
    boolean id() default false;

    // 列名
    String column() default "";

    // java类中的属性
    String property() default "";

    /**
   * Return the java type for this argument.
   *
   * @return the java type
   */
    Class<?> javaType() default void.class;

    /**
   * Return the jdbc type for column that map to this argument.
   *
   * @return the jdbc type
   */
    JdbcType jdbcType() default JdbcType.UNDEFINED;

    // TypeHandler 处理器
    Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;

    // 一对一注解
    One one() default @One;

    // 一对多注解
    Many many() default @Many;
}
@One
  • org.apache.ibatis.annotations.@One ,复杂类型的单独属性值的注解。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface One {
    
    //列前缀
    String columnPrefix() default "";

    // 结果集映射
    String resultMap() default "";

    // 已经映射的语句的全限定名
    String select() default "";

    // 加载类型
    FetchType fetchType() default FetchType.DEFAULT;

}
@many
  • org.apache.ibatis.annotations.@Many ,复杂类型的集合属性值的注解。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Many {
   
    // 列前缀
    String columnPrefix() default "";

    // 结果集
    String resultMap() default "";

    // select 语句
    String select() default "";

    // 加载类型
    FetchType fetchType() default FetchType.DEFAULT;

}
@ResultMap
  • org.apache.ibatis.annotations.@ResultMap ,使用的结果集的注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ResultMap {
    // 结果集
    String[] value();
}
  • 例如上述示例的 #getBlogByTitle(@Param("title")String title) 方法,使用的注解为 @ResultMap(value = "sqlBlogsMap"),而 "sqlBlogsMap" 中 Mapper XML 中有相关的定义
@ResultType
  • org.apache.ibatis.annotations.@ResultType ,结果类型
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ResultType {

    // 返回值类型
    Class<?> value();
}
@CacheNamespace
  • org.apache.ibatis.annotations.@CacheNamespace ,缓存空间配置的注解
  • 对应 XML 标签为
@Documented
@Retention(RetentionPolicy.RUNTIME)
// Mapper类上
@Target(ElementType.TYPE)
public @interface CacheNamespace {

    // 负责存储的 cache 实现类
    Class<? extends Cache> implementation() default PerpetualCache.class;

    // 负责过期的实现类
    Class<? extends Cache> eviction() default LruCache.class;

    // 清空缓存的频率 0  代表不清空
    long flushInterval() default 0;

    // 缓存容器大小
    int size() default 1024;

    // 是否序列化
    boolean readWrite() default true;

    // 是否阻塞
    boolean blocking() default false;

    // Property数组
    Property[] properties() default {};

}
@Property
  • org.apache.ibatis.annotations.@Property ,属性的注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Property {

    // 属性名
    String name();
    // 值
    String value();
}
@CacheNamespaceRef
  • org.apache.ibatis.annotations.@CacheNamespaceRef ,指向指定命名空间的注解
  • 对应 XML 标签为
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CacheNamespaceRef {

    /**
   * Returns the namespace type to reference a cache (the namespace name become a FQCN of specified type).
   *
   * @return the namespace type to reference a cache
   */
    Class<?> value() default void.class;

    /**
   * Returns the namespace name to reference a cache.
   *
   * @return the namespace name
   * @since 3.4.2
   */
    // 指向的命名空间
    String name() default "";
}
@Options
  • org.apache.ibatis.annotations.@Options ,操作可选项
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(Options.List.class)
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
    }

    // 是否使用缓存
    boolean useCache() default true;

    // 刷新缓存的策略
    FlushCachePolicy flushCache() default FlushCachePolicy.DEFAULT;

    // 结果类型
    ResultSetType resultSetType() default ResultSetType.DEFAULT;

    // 语句类型
    StatementType statementType() default StatementType.PREPARED;

    // 加载数量
    int fetchSize() default -1;

    // 超时时间
    int timeout() default -1;

    // 是否生成主键
    boolean useGeneratedKeys() default false;

    // 主键再 java类中的属性
    String keyProperty() default "";

    // 主键再数据库的字段
    String keyColumn() default "";

    // 结果集
    String resultSets() default "";

    /**
   * @return A database id that correspond this options
   * @since 3.5.5
   */
    // 数据库id
    String databaseId() default "";

    /**
   * The container annotation for {@link Options}.
   * @author Kazuki Shimizu
   * @since 3.5.5
   */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface List {
        Options[] value();
    }

}
  • 通过 useGeneratedKeys + keyProperty + keyColumn 属性,可实现返回自增 ID
@SelectKey
  • org.apache.ibatis.annotations.@SelectKey ,通过 SQL 语句获得主键的注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(SelectKey.List.class)
public @interface SelectKey {
    /**
   * Returns an SQL for retrieving a key value.
   *
   * @return an SQL for retrieving a key value
   */
    String[] statement();

    // java 对象的属性
    String keyProperty();

    // 列名
    String keyColumn() default "";

    // 在插入语句执行前,还是执行后
    boolean before();

    // 返回值类型
    Class<?> resultType();

    /**
   * Returns the statement type to use.
   *
   * @return the statement type
   */
    StatementType statementType() default StatementType.PREPARED;

    /**
   * @return A database id that correspond this select key
   * @since 3.5.5
   */
    String databaseId() default "";

    /**
   * The container annotation for {@link SelectKey}.
   * @author Kazuki Shimizu
   * @since 3.5.5
   */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface List {
        SelectKey[] value();
    }

}
@MapKey
  • org.apache.ibatis.annotations.@MapKey ,Map 结果的键的注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MapKey {

    // 键名
    String value();
}
@Flush
  • org.apache.ibatis.annotations.@Flush ,Flush 注解。
  • 如果使用了这个注解,定义在 Mapper 接口中的方法能够调用 SqlSession#flushStatements() 方法。(Mybatis 3.3及以上)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Flush {
}

其它注解

@Mapper
  • org.apache.ibatis.annotations.Mapper ,标记这是个 Mapper 的注解。
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
public @interface Mapper {
  // Interface Mapper
}
@Lang
  • org.apache.ibatis.annotations.@Lang ,语言驱动的注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Lang {

    // 驱动类
    Class<? extends LanguageDriver> value();
}
其他
  • @TypeDiscriminator + @Case
  • @ConstructorArgs + @Arg
  • @AutomapConstructor
1
https://gitee.com/shokaku/Java-Review.git
git@gitee.com:shokaku/Java-Review.git
shokaku
Java-Review
Java-Review
master

搜索帮助