MyBatis3-基于注解的示例

Posted Jim

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis3-基于注解的示例相关的知识,希望对你有一定的参考价值。

在基于注解的示例中,可以简化编写XML的过程,全部采用注解方式进行编写,并在注解上写SQL语句,语句和XML的语句保持一致,并且可以省略掉XML文件不用引入的好处。但还有一点,基于注解的方式还没有百分百覆盖所有XML标签,所有还是有一点缺陷。

在org.apache.ibatis.annotations包下包含了所有注解。

下面引用官方文档的说明http://www.mybatis.org/mybatis-3/zh/java-api.html

映射器注解

因为最初设计时,MyBatis是一个XML驱动的框架。配置信息是基于XML的,而且映射语句也是定义在XML中的。而到了MyBatis3,有新的可用的选择了。MyBatis3构建在基于全面而且强大的Java配置API之上。这个配置API是基于XML的MyBatis配置的基础,也是新的基于注解配置的基础。注解提供了一种简单的方式来实现简单映射语句,而不会引入大量的开销。

注意:不幸的是,Java注解限制了它们的表现和灵活。尽管很多时间都花在调查,设计和实验上,最强大的MyBatis映射不能用注解来构建,那并不可笑。C#属性(做示例)就没有这些限制,因此MyBatis.NET将会比XML有更丰富的选择。也就是说,基于Java注解的配置离不开它的特性。

注解有下面这些:

注解目标相对应的XML描述

@CacheNamespace

<cache>

为给定的命名空间(比如类)配置缓存。属性:implemetation,eviction,flushInterval,size,readWrite,blocking和properties。

@Property

N/A

<property>

指定属性值或占位符(可以由mybatis-config.xml中定义的配置属性替换)。属性:name,value。(在MyBatis3.4.2+上可用)

@CacheNamespaceRef

<cacheRef>

参照另外一个命名空间的缓存来使用。属性:value,name。如果使用此注释,则应指定value或name属性。value属性指定指定命名空间的java类型(命名空间名称成为指定的java类型的FQCN),对于name属性(此属性自3.4.2起可用)指定命名空间的名称。

@ConstructorArgs

方法

<constructor>

收集一组结果传递给一个劫夺对象的构造方法。属性:value,是形式参数的数组。

@Arg

N/A

  • <arg>

  • <idArg>

单独的构造方法参数,是ConstructorArgs集合的一部分。属性:id,column,javaType,typeHandler。id属性是布尔值,来标识用于比较的属性,和<idArg>XML元素相似。

@TypeDiscriminator

方法

<discriminator>

一组实例值被用来决定结果映射的表现。属性:column,javaType,jdbcType,typeHandler,cases。cases属性就是实例的数组。

@Case

N/A

<case>

单独实例的值和它对应的映射。属性:value,type,results。Results属性是结果数组,因此这个注解和实际的ResultMap很相似,由下面的Results注解指定。

@Results

方法

<resultMap>

结果映射的列表,包含了一个特别结果列如何被映射到属性或字段的详情。属性:value,id。value属性是Result注解的数组。这个id的属性是结果映射的名称。

@Result

N/A

  • <result>

  • <id>

在列和属性或字段之间的单独结果映射。属性:id,column,property,javaType,jdbcType,typeHandler,one,many。id属性是一个布尔值,表示了应该被用于比较(和在XML映射中的<id>相似)的属性。one属性是单独的联系,和<association>相似,而many属性是对集合而言的,和<collection>相似。它们这样命名是为了避免名称冲突。

@One

N/A

<association>

复杂类型的单独属性值映射。属性:select,已映射语句(也就是映射器方法)的完全限定名,它可以加载合适类型的实例。注意:联合映射在注解API中是不支持的。这是因为Java注解的限制,不允许循环引用。fetchType会覆盖全局的配置参数lazyLoadingEnabled

@Many

N/A

<collection>

映射到复杂类型的集合属性。属性:select,已映射语句(也就是映射器方法)的全限定名,它可以加载合适类型的实例的集合,fetchType会覆盖全局的配置参数lazyLoadingEnabled。注意联合映射在注解API中是不支持的。这是因为Java注解的限制,不允许循环引用

@MapKey

方法

 

复杂类型的集合属性映射。属性:select,是映射语句(也就是映射器方法)的完全限定名,它可以加载合适类型的一组实例。注意:联合映射在Java注解中是不支持的。这是因为Java注解的限制,不允许循环引用。

@Options

方法

映射语句的属性

这个注解提供访问交换和配置选项的宽广范围,它们通常在映射语句上作为属性出现。而不是将每条语句注解变复杂,Options注解提供连贯清晰的方式来访问它们。属性:useCache=true,flushCache=FlushCachePolicy.DEFAULT,resultSetType=FORWARD_ONLY,statementType=PREPARED,fetchSize=-1,timeout=-1useGeneratedKeys=false,keyProperty=”id”,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。基于执行的映射语句,MyBatis会实例化这个类,然后执行由provider指定的方法.该方法可以有选择地接受参数对象.(InMyBatis3.4orlater,it‘sallowmultipleparameters)属性:type,method。type属性是类。method属性是方法名。注意:这节之后是对类的讨论,它可以帮助你以干净,容于阅读的方式来构建动态SQL。

@Param

Parameter

N/A

如果你的映射器的方法需要多个参数,这个注解可以被应用于映射器的方法参数来给每个参数一个名字。否则,多参数将会以它们的顺序位置来被命名(不包括任何RowBounds参数)比如。#{param1},#{param2}等,这是默认的。使用@Param(“person”),参数应该被命名为#{person}。

@SelectKey

方法

<selectKey>

该注解复制了<selectKey>的功能,用在注解了@Insert@InsertProvider@Updateor@UpdateProvider的方法上。在其他方法上将被忽略。如果你指定了一个@SelectKey注解,然后Mybatis将忽略任何生成的key属性通过设置@Options,或者配置属性。属性:statement是要执行的sql语句的字符串数组,keyProperty是需要更新为新值的参数对象属性,before可以是true或者false分别代表sql语句应该在执行insert之前或者之后,resultTypekeyProperty的Java类型,statementType是语句的类型,取StatementPreparedStatementCallableStatement对应的STATEMENTPREPARED或者CALLABLE其中一个,默认是PREPARED

@ResultMap

方法

N/A

这个注解给@Select或者@SelectProvider提供在XML映射中的<resultMap>的id。这使得注解的select可以复用那些定义在XML中的ResultMap。如果同一select注解中还存在@Results或者@ConstructorArgs,那么这两个注解将被此注解覆盖。

@ResultType

Method

N/A

当使用结果处理器时启用此注解。这种情况下,返回类型为void,所以Mybatis必须有一种方式决定对象的类型,用于构造每行数据。如果有XML的结果映射,使用@ResultMap注解。如果结果类型在XML的<select>节点中指定了,就不需要其他的注解了。其他情况下则使用此注解。比如,如果@Select注解在一个方法上将使用结果处理器,返回类型必须是void并且这个注解(或者@ResultMap)是必须的。这个注解将被忽略除非返回类型是void。

@Flush

方法

N/A

如果这个注解使用了,它将调用定义在Mapper接口中的SqlSession#flushStatements方法。(Mybatis3.3或者以上)

映射申明样例

这个例子展示了如何使用@SelectKey注解来在插入前读取数据库序列的值:

@Insert("insert into table3 (id, name) values(#{nameId}, #{name})")
@SelectKey(statement="call next value for TestSequence", keyProperty="nameId", before=true, resultType=int.class)
int insertTable3(Name name);

这个例子展示了如何使用@SelectKey注解来在插入后读取数据库识别列的值:

@Insert("insert into table2 (name) values(#{name})")
@SelectKey(statement="call identity()", keyProperty="nameId", before=false, resultType=int.class)
int insertTable2(Name name);

这个例子展示了如何使用@Flush注解去调用SqlSession#flushStatements():

@Flush
List<BatchResult> flush();

这些例子展示了如何通过指定@Result的id属性来命名结果集:

@Results(id = "userResult", value = {
  @Result(property = "id", column = "uid", id = true),
  @Result(property = "firstName", column = "first_name"),
  @Result(property = "lastName", column = "last_name")
})
@Select("select * from users where id = #{id}")
User getUserById(Integer id);

@Results(id = "companyResults")
@ConstructorArgs({
  @Arg(property = "id", column = "cid", id = true),
  @Arg(property = "name", column = "name")
})
@Select("select * from company where id = #{id}")
Company getCompanyById(Integer id);

这个例子展示了单一参数使用@SqlProvider:

@SelectProvider(type = UserSqlBuilder.class, method = "buildGetUsersByName")
List<User> getUsersByName(String name);

class UserSqlBuilder {
  public String buildGetUsersByName(final String name) {
    return new SQL(){{
      SELECT("*");
      FROM("users");
      if (name != null) {
        WHERE("name like #{value} || ‘%‘");
      }
      ORDER_BY("id");
    }}.toString();
  }
}

这个列子展示了多参数使用@SqlProvider:

@SelectProvider(type = UserSqlBuilder.class, method = "buildGetUsersByName")
List<User> getUsersByName(
    @Param("name") String name, @Param("orderByColumn") String orderByColumn);

class UserSqlBuilder {

  // If not use @Param, you should be define same arguments with mapper method
  public String buildGetUsersByName(
      final String name, final String orderByColumn) {
    return new SQL(){{
      SELECT("*");
      FROM("users");
      WHERE("name like #{name} || ‘%‘");
      ORDER_BY(orderByColumn);
    }}.toString();
  }

  // If use @Param, you can define only arguments to be used
  public String buildGetUsersByName(@Param("orderByColumn") final String orderByColumn) {
    return new SQL(){{
      SELECT("*");
      FROM("users");
      WHERE("name like #{name} || ‘%‘");
      ORDER_BY(orderByColumn);
    }}.toString();
  }
}

示例:

 

 

以上是关于MyBatis3-基于注解的示例的主要内容,如果未能解决你的问题,请参考以下文章

mybatis3如何使用@Insert注解插入日期类型的字段

MyBatis3系列__04CRUD以及参数处理

mybatis3 如何使用@Insert注解插入数据到数据库里为bit类型的字段

Struts2+Spring3+MyBatis3整合以及Spring注解开发

Mybatis 教程之Mybatis注解开发

mybatis3中几个@Provider的使用方式