myBatis映射配置参考

<?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">


<!--
文档前置说明:
  以下对于mybatisXML映射器文件的解读参考mybatis官网文档:
    https://mybatis.org/mybatis-3/zh/
-->


<!--
mapper 映射器:
  mybatis映射器,关注点在POJO与SQL之间的映射关系,所以开发者关注的是sql,开发者自定义sql,
  框架使用mapper完成pojo到sql的映射(sql完成和数据库的交互,所以不是完成数据库字段到pojo)。
  mapper标签是根标签仅允许一个存在,代表和一个映射接口类的关联
属性:
  namespace:用于绑定Mapper接口,mybatis会使用mapper映射器实现Mapper接口(可以由注解完成)。
 -->
<mapper namespace="接口的全限定类名">
  <!--
  标签前置说明:
    cache:该命名空间的缓存配置。
    cache-ref:引用其它命名空间的缓存配置。
    resultMap:描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
    parameterMap:老式风格的参数映射。此元素已被废弃,并可能在将来被移除!请使用行内参数映射。文档中不会介绍此元素。
    sql:可被其它语句引用的可重用语句块。
    insert:映射插入语句。
    update:映射更新语句。
    delete:映射删除语句。
    select:映射查询语句。
   -->


  <!--
  select 查询语句:
    进行查询和结果映射
  属性:
    select元素允许配置很多属性来配置每条语句的行为细节。

    属性:id
    描述:在命名空间中唯一的标识符,可以被用来引用这条语句。
    备注:

    属性:parameterType
    描述:将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为MyBatis可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
    备注:

    属性:parameterMap
    描述:用于引用外部parameterMap的属性,目前已被废弃。请使用行内参数映射和parameterType属性。
    备注:

    属性:resultType
    描述:期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 resultType和resultMap之间只能同时使用一个。
    备注:

    属性:resultMap
    描述:对外部resultMap的命名引用。结果映射是MyBatis最强大的特性,如果你对其理解透彻,许多复杂的映射问题都能迎刃而解。resultType和resultMap之间只能同时使用一个。
    备注:

    属性:flushCache
    描述:将其设置为true后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false。
    备注:

    属性:useCache
    描述:将其设置为true后,将会导致本条语句的结果被二级缓存缓存起来,默认值:对select元素为true。
    备注:

    属性:timeout
    描述:这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。
    备注:

    属性:fetchSize
    描述:这是一个给驱动的建议值,尝试让驱动程序每次批量返回的结果行数等于这个设置值。 默认值为未设置(unset)(依赖驱动)。
    备注:

    属性:statementType
    描述:可选STATEMENT,PREPARED或CALLABLE。这会让MyBatis分别使用Statement,PreparedStatement或CallableStatement,默认值:PREPARED。
    备注:

    属性:resultSetType
    描述:FORWARD_ONLY,SCROLL_SENSITIVE,SCROLL_INSENSITIVE或DEFAULT(等价于unset)中的一个,默认值为unset(依赖数据库驱动)。
    备注:

    属性:databaseId
    描述:如果配置了数据库厂商标识(databaseIdProvider),MyBatis会加载所有不带databaseId或匹配当前databaseId的语句;如果带和不带的语句都有,则不带的会被忽略。
    备注:

    属性:resultOrdered
    描述:这个设置仅针对嵌套结果select语句:如果为true,则假设结果集以正确顺序(排序后)执行映射,当返回新的主结果行时,将不再发生对以前结果行的引用。 这样可以减少内存消耗。默认值:false。
    备注:

    属性:resultSets
    描述:这个设置仅适用于多结果集的情况。它将列出语句执行后返回的结果集并赋予每个结果集一个名称,多个名称之间以逗号分隔。
    备注:
   -->
  <select id="唯一标识" parameterType="参数类型(全限定类名或别名)" resultType="结果类型(全限定类名或别名)">
    <!-- sql语句 -->
    SELECT * FROM Test001 WHERE id = #{id}
  </select>


  <!--
  数据变更语句insert插入语句,update更新语句和delete删除语句的实现非常接近:
  属性:
    属性:id
    描述:在命名空间中唯一的标识符,可以被用来引用这条语句。
    备注:

    属性:parameterType
    描述:将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,
      因为MyBatis可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
    备注:

    属性:parameterMap
    描述:用于引用外部parameterMap的属性,目前已被废弃。请使用行内参数映射和parameterType属性。
    备注:

    属性:flushCache
    描述:将其设置为true后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:(对insert、update和delete 语句)true。
    备注:

    属性:timeout
    描述:这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。
    备注:

    属性:statementType
    描述:可选STATEMENT,PREPARED或CALLABLE。
      这会让MyBatis分别使用Statement,PreparedStatement或CallableStatement,默认值:PREPARED。
    备注:

    属性:useGeneratedKeys
    描述:(仅适用于insert和update)这会令MyBatis使用JDBC的getGeneratedKeys方法来取出由数据库内部生成的主键
      如果是不支持内部自增主键的数据库,可以使用selectKey标签进行平替(手动生产一个key)
      (比如:像MySQL和SQL Server这样的关系型数据库管理系统的自动递增字段),默认值:false。
    备注:

    属性:keyProperty
    描述:(仅适用于insert和update)指定能够唯一识别对象的属性,MyBatis会使用getGeneratedKeys的返回值或insert语句的selectKey子元素设置它的值,
      默认值:未设置(unset)。如果生成列不止一个,可以用逗号分隔多个属性名称。
    备注:

    属性:keyColumn
    描述:(仅适用于insert和update)设置生成键值在表中的列名,在某些数据库(像PostgreSQL)中,当主键列不是表中的第一列的时候,是必须设置的。
      如果生成列不止一个,可以用逗号分隔多个属性名称。
    备注:

    属性:databaseId
    描述:如果配置了数据库厂商标识(databaseIdProvider),MyBatis会加载所有不带databaseId或匹配当前databaseId的语句;
      如果带和不带的语句都有,则不带的会被忽略。
    备注:

  内部标签:
    selectKey 获取key:
      用于在insert和update标签中进行生成key
    属性:
      属性:keyProperty
      描述:selectKey语句结果应该被设置到的目标属性。如果生成列不止一个,可以用逗号分隔多个属性名称。
      备注:

      属性:keyColumn
      描述:返回结果集中生成列属性的列名。如果生成列不止一个,可以用逗号分隔多个属性名称。
      备注:

      属性:resultType
      描述:结果的类型。通常MyBatis可以推断出来,但是为了更加准确,写上也不会有什么问题。
        MyBatis允许将任何简单类型用作主键的类型,包括字符串。如果生成列不止一个,则可以使用包含期望属性的Object或Map。
      备注:

      属性:order
      描述:可以设置为BEFORE或AFTER。如果设置为BEFORE,那么它首先会生成主键,设置keyProperty再执行插入语句。
        如果设置为AFTER,那么先执行插入语句,然后是selectKey中的语句-这和Oracle数据库的行为相似,在插入语句内部可能有嵌入索引调用。
      备注:

      属性:statementType
      描述:和前面一样,MyBatis支持STATEMENT,PREPARED和CALLABLE类型的映射语句,
        分别代表Statement,PreparedStatement和CallableStatement类型。
      备注:

   -->
  <insert id="唯一标识">
    insert into Test001 (id,name,sex,age,college)
    values (#{id},#{name},#{sex},#{age},#{college})
  </insert>

  <update id="唯一标识">
    update Test001 set
        name = #{name},
        sex = #{sex},
        age = #{age},
        college = #{college}
    where id = #{id}
  </update>

  <delete id="唯一标识">
    delete from Test001 where id = #{id}
  </delete>

  <!--
  sql SQL代码片段:
    用来定义可重用的SQL代码片段,以便在其它语句中使用。 参数可以静态地(在加载的时候)确定下来,并且可以在不同的include元素中定义不同的参数值。
   -->
  <sql id="唯一标识"> ${属性名}.id,${属性名}.username,${属性名}.password </sql>
  <!--
  可重用的SQL代码片段使用案例:
   -->
  <sql id="user">
     ${userTable}.id,
     ${userTable}.name,
     ${userTable}.sex,
     ${userTable}.age,
     ${userTable}.college
  </sql>
  <!--
  使用时使用include标签导入,使用sql标签时可以${},导入可以自动配置属性,也可以使用include的子标签property进行手动配置属性
   -->
  <select id="selectUsers" resultType="list">
    SELECT
        <include refid="user"><property name="userTable" value="Test001"/></include>
    FROM Test001 WHERE id = #{id}
  </select>

  <!--
  字符串替换:
    在mybatis中sql中可以进行参数动态替换取值,传统分为两种方式(直接拼接和预编译),mybatis也是#{},${}
  ${}:
    会将其内容直接替换,可能存在sql注入
  #{}:
    会进行参数预编译处理,MyBatis会创建PreparedStatement参数占位符,并通过占位符安全地设置参数,相当于使用?进行占位,在进行预编译
   -->
  <!--
  参数映射:
    mybatis中参数映射非常强大,在大多数时候都可以使用简单的配置实现映射操作,当然也支持使用复杂的高级点的行为
    分为简单数据类型(包括原始类型,eg:Integer和String等),复杂的对象

  简单数据类型:
    原始类型或简单数据类型(比如Integer和String)因为没有其它属性,会用它们的值来作为参数。
    所以不用设置parameterType也可以,如果只有一个,这个参数可以随意命名

    eg:
        <select id="selectUsers" resultType="user">
          SELECT * FROM Test001 WHERE id = #{id}
        </select>

  复杂对象:
    如果参数对象传递到了语句中,会查找该对象属性,然后将它们的值传入语句的参数中。
    在这个过程中使用#{}还可以进行手动类型引到

    参数类型和类型处理器:
      #{age,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}
      备注:
        官方说如果参数对象是HashMap需要显式指定javaType来确保正确的TypeHandler类型处理被使用。
        但是目前使用map时好像未发现

        JDBC要求,如果一个列允许使用null值,并且会使用值为null的参数,就必须要指定JDBC类型(jdbcType)。

    数值类型小数精度:
    #{height,javaType=double,jdbcType=NUMERIC,numericScale=2}

    mode属性:
      目前未解析该属性

      原话附上,用于参考:
        最后,mode属性允许你指定IN,OUT或INOUT参数。如果参数的mode为OUT或INOUT,将会修改参数对象的属性值,以便作为输出参数返回。
        如果mode为OUT(或 INOUT),而且jdbcType为CURSOR(也就是Oracle的REFCURSOR),你必须指定一个resultMap引用来将结果集ResultSet映射到参数的类型上。
        要注意这里的javaType属性是可选的,如果留空并且jdbcType是CURSOR,它会被自动地被设为ResultSet。
          #{department, mode=OUT, jdbcType=CURSOR, javaType=ResultSet, resultMap=departmentResultMap}
        MyBatis也支持很多高级的数据类型,比如结构体(structs),但是当使用out参数时,你必须显式设置类型的名称。比如(再次提示,在实际中要像这样不能换行):
          #{middleInitial, mode=OUT, jdbcType=STRUCT, jdbcTypeName=MY_TYPE, resultMap=departmentResultMap}
   -->
  <!--
  mapper核心,结果集映射:
    mybatis被部分人称为半ROM框架,就是因为注重数据库和对象的映射关系,让用户处理sql语句

    resultMap 结果集映射:(简介来源官方)
      resultMap元素是MyBatis中最重要最强大的元素。
      它可以让你从90%的JDBC ResultSets数据提取代码中解放出来,并在一些情形下允许你进行一些JDBC不支持的操作。
      实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份resultMap能够代替实现同等功能的数千行代码。
      ResultMap的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

    简单结果集映射:
      在大多数时候,mybatis都只用简单的结果集映射即可完成数据库和对象的映射关系

      在结果集映射中mybatis会将ResultSets结果集对象中数据自动映射到java Pojo对象,
      通过对象的Getter/Setter方法进行数据拆/封装,自动映射需要列名和属性名匹配,
      因为MyBatis会在幕后自动创建一个ResultMap,再根据属性名来映射列到JavaBean的属性上,
      如果列名和属性名不能匹配上,可以对列设置列别名,进行映射,或者显示构建ResultMap

      别名方式:
        <select id="selectUsers" resultType="user">
          select
            user_id             as "id",
            user_name           as "name",
            user_sex            as "sex",
            user_age            as "age",
            user_college        as "college"
          from Test001
          where id = #{id}
        </select>

      显示构建ResultMap:
        <resultMap id="userResultMap" type="user">
          <id property="id" column="user_id" />
          <result property="name" column="user_name"/>
          <result property="sex" column="user_sex"/>
          <result property="age" column="user_age"/>
          <result property="college" column="user_college"/>
        </resultMap>

        调用时将resultType属性替换为resultMap="userResultMap"即可

    复杂结果集映射:
      在特定的较为复杂的情况,需要对数据库和对象的映射关系进行简单描述
      MyBatis创建时的一个思想是:数据库不可能永远是你所想或所需的那个样子。
      所以你可能经常会遇见些鬼迷日眼的需求,或者数据库,需要变态般的进行结果集映射。

    ResultMap属性:
      属性:id
      描述:当前命名空间中的一个唯一标识,用于标识一个结果映射。
      备注:

      属性:type
      描述:类的完全限定名, 或者一个类型别名。
      备注:

      属性:autoMapping
      描述:如果设置这个属性,MyBatis将会为本结果映射开启或者关闭自动映射。
        这个属性会覆盖全局的属性autoMappingBehavior。默认值:未设置(unset)。
      备注:



    ResultMap子标签:

      属性:constructor
      描述:用于在实例化类时,注入结果到构造方法中
      备注:

        属性:idArg
        描述:ID参数;标记出作为ID的结果可以帮助提高整体性能
        备注:

        属性:arg
        描述:将被注入到构造方法的一个普通结果
        备注:

      属性:id
      描述:一个ID结果;标记出作为ID的结果可以帮助提高整体性能
      备注:

      属性:result
      描述:注入到字段或JavaBean属性的普通结果
      备注:

      属性:association
      描述:一个复杂类型的关联;许多结果将包装成这种类型
      备注:

        属性:嵌套结果映射
        描述:关联可以是resultMap元素,或是对其它结果映射的引用
        备注:

      属性:collection
      描述:一个复杂类型的集合
      备注:

        属性:嵌套结果映射
        描述:集合可以是resultMap元素,或是对其它结果映射的引用
        备注:

      属性:discriminator
      描述:使用结果值来决定使用哪个resultMap
      备注:

        属性:case
        描述:基于某些值的结果映射
        备注:

        属性:嵌套结果映射
        描述:case也是一个结果映射,因此具有相同的结构和元素;或者引用其它的结果映射
        备注:

    ResultMap子标签详解:

      id & result 字段注入:通过getter/setter
        这些元素是结果映射的基础。id和result元素都将一个列的值映射到一个简单数据类型(String,int,double,Date等)的属性或字段。
        这两者之间的唯一不同是,id元素对应的属性会被标记为对象的标识符,在比较对象实例时使用。
        这样可以提高整体的性能,尤其是进行缓存和嵌套结果映射(也就是连接映射)的时候。

        <id property="id" column="user_id"/>
        <result property="name" column="user_name"/>

      共用属性:
        属性:property
        描述:映射到列结果的字段或属性。如果JavaBean有这个名字的属性(property),会先使用该属性。
        	否则MyBatis将会寻找给定名称的字段(field)。无论是哪一种情形,你都可以使用常见的点式分隔形式进行复杂属性导航。
        	比如,你可以这样映射一些简单的东西:“username”,或者映射到一些复杂的东西上:“address.street.number”。
        备注:

        属性:column
        描述:数据库中的列名,或者是列的别名。一般情况下,这和传递给resultSet.getString(columnName)方法的参数一样。
        备注:

        属性:javaType
        描述:一个Java类的全限定名,或一个类型别名(关于内置的类型别名,可以参考上面的表格)。
        	如果你映射到一个JavaBean,MyBatis通常可以推断类型。
        	然而,如果你映射到的是HashMap,那么你应该明确地指定javaType来保证行为与期望的相一致。
        备注:

        属性:jdbcType
        描述:JDBC类型,所支持的JDBC类型参见这个表格之后的“支持的JDBC类型”。
        	只需要在可能执行插入、更新和删除的且允许空值的列上指定JDBC类型。
        	这是JDBC的要求而非MyBatis的要求。如果你直接面向JDBC编程,你需要对可以为空值的列指定这个类型。
        备注:
        支持类型:mybatis存在一个内置的jdbcType枚举类型
          BIT	      FLOAT	  CHAR	        TIMESTAMP	    OTHER	  UNDEFINED
          TINYINT	  REAL	  VARCHAR	      BINARY	      BLOB	  NVARCHAR
          SMALLINT	DOUBLE	LONGVARCHAR	  VARBINARY	    CLOB	  NCHAR
          INTEGER	  NUMERIC	DATE	        LONGVARBINARY	BOOLEAN	NCLOB
          BIGINT	  DECIMAL	TIME	        NULL	        CURSOR	ARRAY

        属性:typeHandler
        描述:我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的类型处理器。
          这个属性值是一个类型处理器实现类的全限定名,或者是类型别名。
        备注:

      constructor 构造注入:通过构造器

        正常构造器参数类型和顺序进行注入:
          <constructor>
             <idArg column="id" javaType="int"/>
             <arg column="username" javaType="String"/>
             <arg column="age" javaType="_int"/>
          </constructor>

        通过构造器参数名称个数进行注入:
          <constructor>
             <idArg column="id" javaType="int" name="id" />
             <arg column="age" javaType="_int" name="age" />
             <arg column="username" javaType="String" name="username" />
          </constructor>

      属性:
        属性:column
        描述:数据库中的列名,或者是列的别名。一般情况下,这和传递给resultSet.getString(columnName)方法的参数一样。
        备注:

        属性:javaType
        描述:一个Java类的完全限定名,或一个类型别名(关于内置的类型别名,可以参考上面的表格)。
        	如果你映射到一个JavaBean,MyBatis通常可以推断类型。
        	然而,如果你映射到的是HashMap,那么你应该明确地指定javaType来保证行为与期望的相一致。
        备注:

        属性:jdbcType
        描述:JDBC类型,所支持的JDBC类型参见这个表格之前的“支持的JDBC类型”。
        	只需要在可能执行插入、更新和删除的且允许空值的列上指定JDBC类型。
        	这是JDBC的要求而非MyBatis的要求。如果你直接面向JDBC编程,你需要对可能存在空值的列指定这个类型。
        备注:

        属性:typeHandler
        描述:我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的类型处理器。
          这个属性值是一个类型处理器实现类的完全限定名,或者是类型别名。
        备注:

        属性:select
        描述:用于加载复杂类型属性的映射语句的ID,它会从column属性中指定的列检索数据,作为参数传递给此select语句。
          具体请参考关联元素。
        备注:

        属性:resultMap
        描述:结果映射的ID,可以将嵌套的结果集映射到一个合适的对象树中。
        	它可以作为使用额外select语句的替代方案。它可以将多表连接操作的结果映射成一个单一的ResultSet。
        	这样的ResultSet将会将包含重复或部分数据重复的结果集。
        	为了将结果集正确地映射到嵌套的对象树中,MyBatis允许你“串联”结果映射,以便解决嵌套结果集的问题。
        	想了解更多内容,请参考下面的关联元素。
        备注:

        属性:name
        描述:构造方法形参的名字。从3.4.3版本开始,通过指定具体的参数名,你可以以任意顺序写入arg元素。参看上面的解释。
        备注:

      association 关联:
        嵌套结果映射:使用嵌套的结果映射来处理连接结果的重复子集。

        结果集嵌套行为:
          <association property="author" column="blog_author_id" javaType="Author">
            <id property="id" column="author_id"/>
            <result property="username" column="author_username"/>
          </association>

          属性:
            属性:property
            描述:映射到列结果的字段或属性。如果用来匹配的 JavaBean 存在给定名字的属性,那么它将会被使用。
          	  否则 MyBatis 将会寻找给定名称的字段。 无论是哪一种情形,你都可以使用通常的点式分隔形式进行复杂属性导航。
          	  比如,你可以这样映射一些简单的东西:“username”,或者映射到一些复杂的东西上:“address.street.number”。
            备注:

            属性:javaType
            描述:一个 Java 类的完全限定名,或一个类型别名(关于内置的类型别名,可以参考上面的表格)。
          	  如果你映射到一个 JavaBean,MyBatis 通常可以推断类型。
          	  然而,如果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证行为与期望的相一致。
            备注:

            属性:jdbcType
            描述:JDBC 类型,所支持的 JDBC 类型参见这个表格之前的“支持的 JDBC 类型”。
          	  只需要在可能执行插入、更新和删除的且允许空值的列上指定 JDBC 类型。
          	  这是 JDBC 的要求而非 MyBatis 的要求。如果你直接面向 JDBC 编程,你需要对可能存在空值的列指定这个类型。
            备注:

            属性:typeHandler
            描述:我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的类型处理器。
          	  这个属性值是一个类型处理器实现类的完全限定名,或者是类型别名。
            备注:


        嵌套Select查询:通过执行另外一个SQL映射语句来加载期望的复杂类型。

          嵌套查询行为:
            <resultMap id="blogResult" type="Blog">
              <association property="author" column="author_id" javaType="Author" select="selectAuthor"/>
            </resultMap>

            <select id="selectBlog" resultMap="blogResult">
              SELECT * FROM BLOG WHERE ID = #{id}
            </select>

            <select id="selectAuthor" resultType="Author">
              SELECT * FROM AUTHOR WHERE ID = #{id}
            </select>

          属性:
            属性:column
            描述:数据库中的列名,或者是列的别名。一般情况下,这和传递给resultSet.getString(columnName)方法的参数一样。
          	  注意:在使用复合主键的时候,你可以使用column="{prop1=col1,prop2=col2}"这样的语法来指定多个传递给嵌套Select查询语句的列名。
          	  这会使得prop1和prop2作为参数对象,被设置为对应嵌套Select语句的参数。
            备注:

            属性:select
            描述:用于加载复杂类型属性的映射语句的ID,它会从column属性指定的列中检索数据,作为参数传递给目标select语句。
          	  具体请参考下面的例子。注意:在使用复合主键的时候,你可以使用column="{prop1=col1,prop2=col2}"这样的语法来指定多个传递给嵌套Select查询语句的列名。
          	  这会使得prop1和prop2作为参数对象,被设置为对应嵌套Select语句的参数。
            备注:

            属性:fetchType
            描述:可选的。有效值为lazy和eager。指定属性后,将在映射中忽略全局配置参数lazyLoadingEnabled,使用属性的值。
            备注:大型数据集情况下可能会产生"N+1查询问题",使用延迟加载能够缓解,但是极端情况下任然可能存在

        关联的嵌套结果映射:

          嵌套结果集:
            <resultMap id="blogResult" type="Blog">
              <id property="id" column="blog_id" />
              <result property="title" column="blog_title"/>
              <association property="author" column="blog_author_id" javaType="Author" resultMap="authorResult"/>
            </resultMap>

            <resultMap id="authorResult" type="Author">
              <id property="id" column="author_id"/>
              <result property="username" column="author_username"/>
              <result property="password" column="author_password"/>
              <result property="email" column="author_email"/>
              <result property="bio" column="author_bio"/>
            </resultMap>

          属性:
            属性:resultMap
            描述:结果映射的ID,可以将此关联的嵌套结果集映射到一个合适的对象树中。
          	  它可以作为使用额外select语句的替代方案。它可以将多表连接操作的结果映射成一个单一的ResultSet。
          	  这样的ResultSet有部分数据是重复的。 为了将结果集正确地映射到嵌套的对象树中,
          	  MyBatis允许你“串联”结果映射,以便解决嵌套结果集的问题。使用嵌套结果映射的一个例子在表格以后。
            备注:

            属性:columnPrefix
            描述:当连接多个表时,你可能会不得不使用列别名来避免在ResultSet中产生重复的列名。
          	  指定columnPrefix列名前缀允许你将带有这些前缀的列映射到一个外部的结果映射中。
          	  详细说明请参考后面的例子。
            备注:可以为每项设置别名,在复杂结果集处理时,防止名称冲突

            属性:notNullColumn
            描述:默认情况下,在至少一个被映射到属性的列不为空时,子对象才会被创建。
          	  你可以在这个属性上指定非空的列来改变默认行为,指定后,Mybatis将只在这些列中任意一列非空时才创建一个子对象。
          	  可以使用逗号分隔来指定多个列。默认值:未设置(unset)。
            备注:

            属性:autoMapping
            描述:如果设置这个属性,MyBatis将会为本结果映射开启或者关闭自动映射。
          	  这个属性会覆盖全局的属性autoMappingBehavior。注意,本属性对外部的结果映射无效,
          	  所以不能搭配select或resultMap元素使用。默认值:未设置(unset)。
            备注:

        ResultSet 关联的多结果集:
          属性:
            属性:column
            描述:当使用多个结果集时,该属性指定结果集中用于与foreignColumn匹配的列(多个列名以逗号隔开),以识别关系中的父类型与子类型。
            备注:

            属性:foreignColumn
            描述:指定外键对应的列名,指定的列将与父类型中column的给出的列进行匹配。
            备注:

            属性:resultSet
            描述:指定用于加载复杂类型的结果集名字。
            备注:

          目前该属性暂时未解析,现给出官网原文供以参考:

            在例子中,存储过程执行下面的查询并返回两个结果集。第一个结果集会返回博客(Blog)的结果,第二个则返回作者(Author)的结果。
              SELECT * FROM BLOG WHERE ID = #{id}
              SELECT * FROM AUTHOR WHERE ID = #{id}
            在映射语句中,必须通过resultSets属性为每个结果集指定一个名字,多个名字使用逗号隔开。
              <select id="selectBlog" resultSets="blogs,authors" resultMap="blogResult" statementType="CALLABLE">
                {call getBlogsAndAuthors(#{id,jdbcType=INTEGER,mode=IN})}
              </select>
            现在我们可以指定使用“authors”结果集的数据来填充“author”关联:
              <resultMap id="blogResult" type="Blog">
                <id property="id" column="id" />
                <result property="title" column="title"/>
                <association property="author" javaType="Author" resultSet="authors" column="author_id" foreignColumn="id">
                  <id property="id" column="id"/>
                  <result property="username" column="username"/>
                  <result property="password" column="password"/>
                  <result property="email" column="email"/>
                  <result property="bio" column="bio"/>
                </association>
              </resultMap>

      collection 集合:
        该子标签行为和association关联子标签行为相似,但是主要用于进行集合的操作(关联用于对象级联)
        下面做简单演示和区分,其他和关联基本一致。

          <resultMap id="blogResult" type="Blog">
            <collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPostsForBlog"/>
          </resultMap>

          <select id="selectBlog" resultMap="blogResult">
            SELECT * FROM BLOG WHERE ID = #{id}
          </select>

          <select id="selectPostsForBlog" resultType="Post">
            SELECT * FROM POST WHERE BLOG_ID = #{id}
          </select>

          ofType属性:
            是用来将JavaBean(或字段)属性的类型和集合存储的类型区分开来
            意思就是是用来手动引到集合的存储类型的属性

      discriminator 鉴别器:
        判断对于应的值进行加载映射,有点像switch语句,一个鉴别器的定义需要指定column和javaType属性。

        <resultMap id="vehicleResult" type="Vehicle">
          <id property="id" column="id" />
          <result property="vin" column="vin"/>
          <result property="year" column="year"/>
          <result property="make" column="make"/>
          <result property="model" column="model"/>
          <result property="color" column="color"/>
          <discriminator javaType="int" column="vehicle_type">
            <case value="1" resultMap="carResult"/>
            <case value="2" resultMap="truckResult"/>
            <case value="3" resultMap="vanResult"/>
            <case value="4" resultMap="suvResult"/>
          </discriminator>
        </resultMap>

    自动映射:
      mybatis自动映射分为三种等级:
        NONE:
         禁用自动映射。仅对手动映射的属性进行映射。
        PARTIAL:
         对除在内部定义了嵌套结果映射(也就是连接的属性)以外的属性进行映射
        FULL:
         自动映射所有属性。

      默认值是PARTIAL,这是有原因的。当对连接查询的结果使用FULL时,连接查询会在同一行中获取多个不同实体的数据,因此可能导致非预期的映射。
      无论设置的自动映射等级是哪种,你都可以通过在结果映射上设置autoMapping属性来为指定的结果映射设置启用/禁用自动映射。
   -->

  <!--
  动态sql:
    if 条件判断:
   -->
    <select id="selectUsers" resultType="user">
        SELECT * FROM Test001
        WHERE sex = #{sex}
        <if test="name != null">
          AND name like #{name}
        </if>
      </select>

  <!--
    choose、when、otherwise 条件选择:
   -->
    <select id="selectUsers" resultType="user">
        SELECT * FROM Test001 WHERE sex = #{sex}
        <choose>
          <when test="name != null">
            AND name like #{name}
          </when>
          <when test="age != null">
            AND age like #{age}
          </when>
          <otherwise>
            AND college like 'test'
          </otherwise>
        </choose>
      </select>

  <!--
    trim、where、set 添加元素:

      //使用trim标签,达到where标签效果
      <trim prefix="WHERE" prefixOverrides="AND |OR ">
            ...
      </trim>

      //使用trim标签,达到set标签效果
      <trim prefix="SET" suffixOverrides=",">
            ...
      </trim>
   -->
    <select id="selectUsers" resultType="user">
      SELECT * FROM Test001
      <where>
        <if test="name != null">
          name like #{name}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
        <if test="college != null">
            AND college like #{college}
        </if>
      </where>
    </select>

    <update id="updateUser">
      update Test001
        <set>
          <if test="name != null">name=#{name},</if>
          <if test="sex != null">sex=#{sex},</if>
          <if test="age != null">age=#{age},</if>
          <if test="college != null">college=#{college}</if>
        </set>
      where id=#{id}
    </update>

  <!--
    foreach 条件循环:
   -->
    <select id="selectUsers" resultType="user">
      SELECT *
      FROM Test001 T
      <where>
        <foreach item="item" index="index" collection="list"
            open="id in (" separator="," close=")" nullable="true">
              #{item}
        </foreach>
      </where>
    </select>

  <!--
    script 脚本:
      @Update({"<script>",
        "update Test001",
          "<set>",
            "<if test="name != null">name=#{name},</if>",
            "<if test="sex != null">sex=#{sex},</if>",
            "<if test="age != null">age=#{age},</if>",
            "<if test="college != null">college=#{college}</if>",
          "</set>",
        "where id=#{id}",
      "</script>"})
      void updateUser(User user);
   -->

  <!--
    bind 变量绑定:
   -->
    <select id="selectUsers" resultType="user">
      <bind name="name" value="'%' + user.getName() + '%'" />
      SELECT * FROM Test001
      WHERE name LIKE #{name}
    </select>

  <!--
    多数据库支持:
      多数据库的支持可以直接在语句标签上配置databaseId属性进行,下面只是官方的演示例子
   -->
    <insert id="insertUser">
      <selectKey keyProperty="id" resultType="int" order="BEFORE">
        <if test="_databaseId == 'oracle'">
          select seq_users.nextval from dual
        </if>
        <if test="_databaseId == 'db2'">
          select nextval for seq_users from sysibm.sysdummy1
        </if>
      </selectKey>
      insert into Test001 values (#{id}, #{name},  #{sex},  #{age},  #{college})
    </insert>

  <!--
    动态SQL中的插入脚本语言:
      仅用于了解,mybatis支持该功能

    MyBatis从3.2版本开始支持插入脚本语言,这允许你插入一种语言驱动,并基于这种语言来编写动态SQL查询语句。
    可以通过实现以下接口来插入一种语言:

      public interface LanguageDriver {
        ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql);
        SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType);
        SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType);
      }
    实现自定义语言驱动后,你就可以在mybatis-config.xml文件中将它设置为默认语言:

      <typeAliases>
        <typeAlias type="org.sample.MyLanguageDriver" alias="myLanguage"/>
      </typeAliases>
      <settings>
        <setting name="defaultScriptingLanguage" value="myLanguage"/>
      </settings>
    或者,你也可以使用lang属性为特定的语句指定语言:

      <select id="selectUsers" lang="myLanguage">
        SELECT * FROM Test001
      </select>
    或者,在你的mapper接口上添加@Lang注解:

      public interface Mapper {
        @Lang(MyLanguageDriver.class)
        @Select("SELECT * FROM Test001")
        List<User> selectUsers();
      }
    提示:可以使用Apache Velocity作为动态语言,更多细节请参考MyBatis-Velocity项目。

    前面看到的所有xml标签都由默认MyBatis语言提供,而它由语言驱动org.apache.ibatis.scripting.xmltags.XmlLanguageDriver(别名为xml)所提供。
   -->

  <!--
  mybatis缓存机制:
    默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:
    <cache/>

    二级缓存效果如下:
      映射语句文件中的所有select语句的结果将会被缓存。
      映射语句文件中的所有insert、update和delete语句会刷新缓存。
      缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
      缓存不会定时进行刷新(也就是说,没有刷新间隔)。
      缓存会保存列表或对象(无论查询方法返回哪种)的1024个引用。
      缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

    提示:
      缓存只作用于cache标签所在的映射文件中的语句。如果混合使用Java API和XML映射文件,
      在共用接口中的语句将不会被默认缓存。需要使用@CacheNamespaceRef注解指定缓存作用域。


    cache元素的属性:
      <cache
        eviction="FIFO"
        flushInterval="60000"
        size="512"
        readOnly="true"/>
    eviction 可用的清除策略有:
      LRU:
        最近最少使用:移除最长时间不被使用的对象。
      FIFO:
        先进先出:按对象进入缓存的顺序来移除它们。
      SOFT:
        软引用:基于垃圾回收器状态和软引用规则移除对象。
      WEAK:
        弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。

    flushInterval 刷新间隔属性:
      可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。
      默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。

    size 引用数目属性:
      可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是1024。

    readOnly 只读属性:
      可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。
      而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是false。

    提示:
      二级缓存是事务性的。这意味着,当SqlSession完成并提交时,或是完成并回滚,
      但没有执行flushCache=true的insert/delete/update语句时,缓存会获得更新。

    自定义缓存:
      可以通过实现自己的缓存,或为其他第三方缓存方案创建适配器,来完全覆盖缓存行为。

        <cache type="com.domain.something.MyCustomCache">
          <property name="cacheFile" value="${cache.file}"/>
        </cache>

      实现自定义缓存需要实现org.apache.ibatis.cache.Cache接口:
        public interface Cache {
          String getId();
          int getSize();
          void putObject(Object key, Object value);
          Object getObject(Object key);
          boolean hasKey(Object key);
          Object removeObject(Object key);
          void clear();
        }
      如果需要所有属性设置完毕之后,调用一个初始化方法,可以在自定义缓存类里实现org.apache.ibatis.builder.InitializingObject接口。
        public interface InitializingObject {
          void initialize() throws Exception;
        }

    配置语句缓存行为:

      缓存的配置和缓存实例会被绑定到SQL映射文件的命名空间中。 同一命名空间中的所有语句和缓存将通过命名空间绑定在一起。
      每条语句可以自定义与缓存交互的方式,或将它们完全排除于缓存之外,可以通过设置flushCache和useCache属性:

        <select ... flushCache="false" useCache="true"/>
        <insert ... flushCache="true"/>
        <update ... flushCache="true"/>
        <delete ... flushCache="true"/>


    cache-ref 缓存引用:
      对某一命名空间的语句,只会使用该命名空间的缓存进行缓存或刷新。
      但可能会想要在多个命名空间中共享相同的缓存配置和实例。
      要实现这种需求,可以使用cache-ref元素来引用另一个缓存。
        <cache-ref namespace="com.someone.application.data.SomeMapper"/>
   -->

</mapper>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值