zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    linux 下高精度时间
    pstack
    linux 调试常用命令
    定位 UNIX 上常见问题的经验总结
    在 POSIX 线程编程中避免内存泄漏
    ulimit
    设计模式之迭代器模式(PHP实现)
    设计模式之责任链模式(php实现)
    设计模式之代理模式(php实现)
    设计模式之享元模式(PHP实现)
  • 原文地址:https://www.cnblogs.com/siye1989/p/11621712.html
Copyright © 2011-2022 走看看