zoukankan      html  css  js  c++  java
  • mybatis总结

    一、配置文件

    属性(properties)

      用来加载外部资源文件,这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。例如:

    <properties resource="org/mybatis/example/config.properties">
      <property name="username" value="dev_user"/>
      <property name="password" value="F2Fa3!33TYyg"/>
    </properties>

      定义外部资源文件的key时,key的格式:xxx.xxx.xxx…,以免产生覆盖。

    设置(settings)

    <settings>
        <!--全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认值为true -->
        <setting name="cacheEnabled" value="true" />
        <!-- 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。默认值false -->
        <setting name="lazyLoadingEnabled" value="true" />
        <!-- 是否开启自动驼峰命名规则(camel case)映射,默认值false-->
        <setting name="mapUnderscoreToCamelCase" value="false" />
        <!-- 指定 MyBatis 增加到日志名称的前缀,任何字符串。默认未设置 -->
        <setting name="logPrefix" value="mybatis" />
        <!-- 指定 MyBatis 所用日志的具体实现,未指定时将自动查找 -->
        <setting name="logImpl" value="SLF4J" />
    </settings>

    类型别名(typeAliases)

     为Java类的全限定名设置一个简短的名字,主要是减少冗余

    <typeAliases>
      <typeAlias alias="Student" type="com.raven.vo.Student"/>
    </typeAliases>

    也可以通过包进行设置,扫描整个包,

    <typeAliases>
      <package name="com.raven.vo"/>
    </typeAliases>

    每一个在包 com.raven.vo 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 com.raven.vo.Student 的别名为 student;若有注解,则别名为其注解值。见下面的例子:

    @Alias("student")
    public class Student {
        ...
    }

     常见的 Java 类型内建的相应的类型别名。它们都是不区分大小写的,注意对基本类型名称重复采取的特殊命名风格。

    别名映射的类型别名映射的类型
    _byte byte double Double
    _long long float Float
    _short short boolean Boolean
    _int int date Date
    _integer int decimal BigDecimal
    _double double bigdecimal BigDecimal
    _float float object Object
    _boolean boolean map Map
    string String hashmap HashMap
    byte Byte list List
    long Long arraylist ArrayList
    short Short collection Collection
    int Integer iterator Iterator
    integer Integer    

    类型处理器(typeHandlers)

      无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。下表描述了一些默认的类型处理器。mybatis默认给我们实现了需多typeHandlers,基本能满足开发。你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型,比如:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler。 

    BooleanTypeHandler

    java.lang.Boolean, boolean

    数据库兼容的 BOOLEAN

    ByteTypeHandler

    java.lang.Byte, byte

    数据库兼容的 NUMERIC 或 BYTE

    ShortTypeHandler

    java.lang.Short, short

    数据库兼容的 NUMERIC 或 SMALLINT

    IntegerTypeHandler

    java.lang.Integer, int

    数据库兼容的 NUMERIC 或 INTEGER

    LongTypeHandler

    java.lang.Long, long

    数据库兼容的 NUMERIC 或 BIGINT

    FloatTypeHandler

    java.lang.Float, float

    数据库兼容的 NUMERIC 或 FLOAT

    DoubleTypeHandler

    java.lang.Double, double

    数据库兼容的 NUMERIC 或 DOUBLE

    BigDecimalTypeHandler

    java.math.BigDecimal

    数据库兼容的 NUMERIC 或 DECIMAL

    StringTypeHandler

    java.lang.String

    CHAR, VARCHAR

    ClobReaderTypeHandler

    java.io.Reader

    -

    ClobTypeHandler

    java.lang.String

    CLOB, LONGVARCHAR

    NStringTypeHandler

    java.lang.String

    NVARCHAR, NCHAR

    NClobTypeHandler

    java.lang.String

    NCLOB

    BlobInputStreamTypeHandler

    java.io.InputStream

    -

    ByteArrayTypeHandler

    byte[]

    数据库兼容的字节流类型

    BlobTypeHandler

    byte[]

    BLOB, LONGVARBINARY

    DateTypeHandler

    java.util.Date

    TIMESTAMP

    DateOnlyTypeHandler

    java.util.Date

    DATE

    TimeOnlyTypeHandler

    java.util.Date

    TIME

    SqlTimestampTypeHandler

    java.sql.Timestamp

    TIMESTAMP

    SqlDateTypeHandler

    java.sql.Date

    DATE

    SqlTimeTypeHandler

    java.sql.Time

    TIME

    ObjectTypeHandler

    Any

    OTHER 或未指定类型

    EnumTypeHandler

    Enumeration Type

    VARCHAR 或任何兼容的字符串类型,用以存储枚举的名称(而不是索引值)

    EnumOrdinalTypeHandler

    Enumeration Type

    任何兼容的 NUMERIC 或 DOUBLE 类型,存储枚举的序数值(而不是名称)。

    SqlxmlTypeHandler

    java.lang.String

    SQLXML

    InstantTypeHandler

    java.time.Instant

    TIMESTAMP

    LocalDateTimeTypeHandler

    java.time.LocalDateTime

    TIMESTAMP

    LocalDateTypeHandler

    java.time.LocalDate

    DATE

    LocalTimeTypeHandler

    java.time.LocalTime

    TIME

    OffsetDateTimeTypeHandler

    java.time.OffsetDateTime

    TIMESTAMP

    OffsetTimeTypeHandler

    java.time.OffsetTime

    TIME

    ZonedDateTimeTypeHandler

    java.time.ZonedDateTime

    TIMESTAMP

    YearTypeHandler

    java.time.Year

    INTEGER

    MonthTypeHandler

    java.time.Month

    INTEGER

    YearMonthTypeHandler

    java.time.YearMonth

    VARCHAR 或 LONGVARCHAR

    JapaneseDateTypeHandler

    java.time.chrono.JapaneseDate

    DATE

    插件(plugins)

     通过 MyBatis 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定想要拦截的方法签名即可。

    @Intercepts({@Signature(
      type= Executor.class,
      method = "update",
      args = {MappedStatement.class,Object.class})})
    public class ExamplePlugin implements Interceptor {
      public Object intercept(Invocation invocation) throws Throwable {
        return invocation.proceed();
      }
      public Object plugin(Object target) {
        return Plugin.wrap(target, this);
      }
      public void setProperties(Properties properties) {
      }
    }

    在全局配置中增加:

    <plugins>
      <plugin interceptor="org.mybatis.example.ExamplePlugin">
        <property name="someProperty" value="100"/>
      </plugin>
    </plugins>

    上面的插件将会拦截在 Executor 实例中所有的 “update” 方法调用, 这里的 Executor 是负责执行低层映射语句的内部对象。

    映射器(mappers)

    直接映射xml配置

    <mappers>
      <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
      <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
      <mapper resource="org/mybatis/builder/PostMapper.xml"/>
    </mappers>

    或者类映射:

    <mappers>
      <mapper class="org.mybatis.builder.AuthorMapper"/>
      <mapper class="org.mybatis.builder.BlogMapper"/>
      <mapper class="org.mybatis.builder.PostMapper"/>
    </mappers>

    或者包扫描:

    <mappers>
      <package name="org.mybatis.builder"/>
    </mappers>

    二、结果映射

    resultType 

    mybatis会满足大部分的映射,将查询的列映射到实体上

    <select id="selectStudents" resultType="com.raven.vo.Student">
      select * from student where id = #{id}
    </select>

    注意:默认不支持驼峰映射,如果存在驼峰和下划线对应的话,比如stu_id和stuId,是无法自动映射的,除非开启驼峰映射。

    resultMap

    <select id="getStudentById" resultMap="BaseResultMap" parameterType="int">
        select * from student t where t.stu_id = #{stuId}
    </select>
    
    <resultMap id="BaseResultMap" type="com.zhi.prictice.vo.Student" >
        <constructor>
            <idArg column="stu_id" javaType="int" jdbcType="INTEGER"/>
            <arg column="name" javaType="string" jdbcType="VARCHAR"/>
        </constructor>
        <result column="age" property="age" jdbcType="INTEGER" />
        <result column="gender" property="gender" jdbcType="VARCHAR" />
        <result column="birthday" property="birthday" jdbcType="DATE" />
        <result column="addr" property="addr" jdbcType="VARCHAR" />
        <result column="reg_time" property="regTime" jdbcType="TIMESTAMP" />
        <result column="status" property="status" jdbcType="BOOLEAN" />
    </resultMap>

    resultmap下的节点

    • constructor - 用于在实例化类时,注入结果到构造方法中
    • idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能
    • arg - 将被注入到构造方法的一个普通结果
    • id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
    • result – 注入到字段或 JavaBean 属性的普通结果
    • association – 一个复杂类型的关联;许多结果将包装成这种类型
    • 嵌套结果映射 – 关联本身可以是一个 resultMap 元素,或者从别处引用一个
    • collection – 一个复杂类型的集合
    • 嵌套结果映射 – 集合本身可以是一个 resultMap 元素,或者从别处引用一个
    • discriminator – 使用结果值来决定使用哪个 resultMap
      • case – 基于某些值的结果映射
        • 嵌套结果映射 – case 本身可以是一个 resultMap 元素,因此可以具有相同的结构和元素,或者从别处引用一个

    关联(一对一映射)

    <association property="author" column="blog_author_id" javaType="Author">
      <id property="id" column="author_id"/>
      <result property="username" column="author_username"/>
    </association>

    集合(一对多映射)

    <collection property="posts" ofType="domain.blog.Post">
      <id property="id" column="post_id"/>
      <result property="subject" column="post_subject"/>
      <result property="body" column="post_body"/>
    </collection>

    三、动态sql

     if判断

    <if test="name != null">
          t.name=#{name,jdbcType=VARCHAR},
    </if>

    choose, when, otherwise

    相当于if...else if....else...

    <select id="findActiveBlogLike"
         resultType="Blog">
      SELECT * FROM BLOG WHERE state = ‘ACTIVE’
      <choose>
        <when test="title != null">
          AND title like #{title}
        </when>
        <when test="author != null and author.name != null">
          AND author_name like #{author.name}
        </when>
        <otherwise>
          AND featured = 1
        </otherwise>
      </choose>
    </select>

    trim, where, set

    where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除。

    <select id="findActiveBlogLike"  resultType="Blog">
      SELECT * FROM BLOG
      <where>
        <if test="state != null">
             state = #{state}
        </if>
      </where>
    </select>

     如果 where 元素没有按正常套路出牌,我们可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:

    <trim prefix="WHERE" prefixOverrides="AND |OR ">
      ...
    </trim>

    类似的用于动态更新语句的解决方案叫做 setset 元素可以用于动态包含需要更新的列,而舍去其它的。比如:

    类似的用于动态更新语句的解决方案叫做 set。set 元素可以用于动态包含需要更新的列,而舍去其它的。比如:

    这里,set 元素会动态前置 SET 关键字,同时也会删掉无关的逗号,因为用了条件语句之后很可能就会在生成的 SQL 语句的后面留下这些逗号。(译者注:因为用的是“if”元素,若最后一个“if”没有匹配上而前面的匹配上,SQL 语句的最后就会有一个逗号遗留)

    若你对 set 元素等价的自定义 trim 元素的代码感兴趣,那这就是它的真面目:

    <trim prefix="SET" suffixOverrides=",">
      ...
    </trim>

    foreach

    <select id="selectPostIn" resultType="domain.blog.Post">
      SELECT *
      FROM POST P
      WHERE ID in
      <foreach item="item" index="index" collection="list"
          open="(" separator="," close=")">
            #{item}
      </foreach>
    </select>

    foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及在迭代结果之间放置分隔符。这个元素是很智能的,因此它不会偶然地附加多余的分隔符。

    bind

    bind元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:

    <select id="selectBlogsLike" resultType="Blog">
      <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
      SELECT * FROM BLOG
      WHERE title LIKE #{pattern}
    </select>

    参考:http://www.mybatis.org/mybatis-3/zh/index.html

  • 相关阅读:
    1132: 零起点学算法39——多组测试数据(a+b)
    1131: 零起点学算法38——求阶乘和
    1130: 零起点学算法37——求阶乘
    1129: 零起点学算法36——3n+1问题
    1128: 零起点学算法35——再求多项式(含浮点)
    1127: 零起点学算法34——继续求多项式
    1126: 零起点学算法33——求多项式
    Netty源码分析第1章(Netty启动流程)---->第1节: 服务端初始化
    Netty源码分析(前言, 概述及目录)
    基于HTK语音工具包进行孤立词识别的使用教程
  • 原文地址:https://www.cnblogs.com/lpob/p/10888276.html
Copyright © 2011-2022 走看看