zoukankan      html  css  js  c++  java
  • MyBatis ResultMap

    MyBatis 真正强大之处就在这些映射语句,也就是它的魔力所在。对于它的强大功能,SQL 映射文件的配置却非常简单。

    如果您比较SQL 映射文件配置与JDBC 代码,您很快可以发现,使用SQL 映射文件配置可以节省95%的代码量。MyBatis 被创建来专注于SQL,但又给您自己的实现极大的空间。


    需要配置的基本元素


    1. cache – 配置给定模式的缓存

    2. cache-ref – 从别的模式中引用一个缓存

    3. resultMap – 这是最复杂而却强大的一个元素了,它描述如何从结果集中加载对象

    4. sql – 一个可以被其他语句复用的SQL 块

    5. insert – 映射INSERT 语句

    6. update – 映射UPDATE 语句

    7. delete – 映射DELEETE 语句

    8. select - 映射SELECT语句



    配置注意


    SQL 映射XML 文件只有一些基本的元素需要配置,并且要按照下面的顺序来定义
    写好SQL语句映射文件后,需要在MyBAtis主配置文件mappers标签中引用!
    例如:

    1. <!--mappers是告诉MyBatis 去哪寻找映射SQL 的语句。可以使用类路径中的资源引用,或者使用字符,输入确切的URL 引用。-->  
    2. <mappers>  
    3.     <mapper resource="com/accp/mybatis/data/BlogMapper.xml" />  
    4. </mappers>  


    当Java接口与XML文件在一个相对路径下时,可以不在myBatis配置文件的mappers中声明。



    SQL 


    这个元素可以被用来定义可重用的SQL代码段,可以包含在其他语句中。

    例子请看下面select中例子



    SELECT

    mybatis select是mybatis 中最常用的元素之一。

    对简单的查询,select 元素的配置是相当简单的:

    1. <?xml version="1.0" encoding="UTF-8" ?>  
    2. <!DOCTYPE mapper  
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
    5. <mapper namespace="com.accp.mybatis.model.Blog">  
    6.       
    7.     <!--可重用的SQL代码段-->  
    8.     <sql id="blog_column">id,title,author_id as authorId</sql>  
    9.       
    10.     <select id="selectBlog_as_map" parameterType="int" resultType="hashmap">  
    11.         select <include refid="blog_column"/> from Blog where id = #{id}  
    12.     </select>  
    13.       
    14. </mapper>  

     这个语句被称作selectBlog_as_map,使用一个int (或Integer)类型的参数,并返回一个HashMap类型的对象

    #{id}告诉mybatis创建了一个PreparedStatement(预处理语句)参数。

    在JDBC中,类似的代码如下:

    1. String selectBlog_as_map = “select * from Blog where id =?”;   
    2. PreparedStatement ps = conn.prepareStatement(selectBlog_as_map);   
    3. ps.setInt(1,id);   

    测试代码:
    1. public static void selectBlogAsMap(int id) {  
    2.     SqlSession session = sqlMapper.openSession();  
    3.     Map<String, Object> map = session.selectOne("selectBlog_as_map",id);  
    4.     System.out.println(map);  
    5.     session.close();  
    6. }  


    SELECT的属性还有很多的属性可以配置,具体的如下:
    属性描述取值默认
    id 在这个模式下唯一的标识符,可被其它语句引用    
    parameterType 传给此语句的参数的完整类名或别名    
    resultType 语句返回值类型的整类名或别名。注意,如果是集合,
    那么这里填写的是集合的项的整类名或别名,而不是集合本身的类名。
    (resultType 与resultMap 不能并用)
       
    resultMap 引用的外部resultMap 名。结果集映射是MyBatis 中最强大的特性。
    许多复杂的映射都可以轻松解决。(resultType 与resultMap 不能并用)
       
    flushCache 如果设为true,则会在每次语句调用的时候就会清空缓存。select 语句默认设为false true|false false
    useCache 如果设为true,则语句的结果集将被缓存。select 语句默认设为false true|false false
    timeout 设置驱动器在抛出异常前等待回应的最长时间,默认为不设值,由驱动器自己决定
    true|false false
    timeout 设置驱动器在抛出异常前等待回应的最长时间,默认为不设值,由驱动器自己决定 正整数 未设置
    fetchSize 设置一个值后,驱动器会在结果集数目达到此数值后,
    激发返回,默认为不设值,由驱动器自己决定
    正整数 驱动器决定
    statementType statement,preparedstatement,callablestatement。
    预准备语句、可调用语句
    STATEMENT
    PREPARED
    CALLABLE
    PREPARED
    resultSetType forward_only,scroll_sensitive,scroll_insensitive
    只转发,滚动敏感,不区分大小写的滚动
    FORWARD_ONLY
    SCROLL_SENSITIVE
    SCROLL_INSENSITIVE
    驱动器决定



























    INSERT

    简单的insert语句:

    1. <?xml version="1.0" encoding="UTF-8" ?>  
    2. <!DOCTYPE mapper  
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
    5. <mapper namespace="com.accp.mybatis.model.Blog">  
    6.   
    7.     <insert id="insertBlog" parameterType="Blog">  
    8.         insert into Blog  
    9.             (id,title,author_id)  
    10.         values  
    11.             (#{id},#{title},#{authorId})  
    12.     </insert>  
    13.   
    14. </mapper>  

    对于insert如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后把keyProperty 设成对应的列,就搞定了。

    例如Blog表已经对 id 使用了自动生成的列类型,那么语句如下:

    1. <?xml version="1.0" encoding="UTF-8" ?>  
    2. <!DOCTYPE mapper  
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
    5. <mapper namespace="com.accp.mybatis.model.Blog">  
    6.   
    7.     <insert id="insertBlog" parameterType="Blog" useGeneratedKeys=”true” keyProperty=”id”>  
    8.         insert into Blog  
    9.             (title,author_id)  
    10.         values  
    11.             (#{title},#{authorId})  
    12.     </insert>  
    13.       
    14. </mapper>  

    还可以使用selectKey元素。下面例子,使用mysql数据库nextval('student')为自定义函数,用来生成一个key。

    例如:

    1. <?xml version="1.0" encoding="UTF-8" ?>  
    2. <!DOCTYPE mapper  
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
    5. <mapper namespace="com.accp.mybatis.model.Blog">  
    6.     <insert id="insertBlog" parameterType="Blog" >  
    7.         <selectKey keyProperty="studentID" resultType="String" order="BEFORE">    
    8.            select nextval('id')    
    9.         </selectKey>    
    10.         insert into Blog  
    11.             (id,title,author_id)  
    12.         values  
    13.             (#{id},#{title},#{authorId})  
    14.     </insert>   
    15. </mapper>  


    insert语句属性配置细节:

    属性 描述 取值 默认
    id 在这个模式下唯一的标识符,可被其它语句引用    
    parameterType 传给此语句的参数的完整类名或别名    
    flushCache 如果设为true,则会在每次语句调用的时候就会清空缓存。select 语句默认设为false true|false false
    useCache 如果设为true,则语句的结果集将被缓存。select 语句默认设为false true|false false
    timeout 设置驱动器在抛出异常前等待回应的最长时间,默认为不设值,由驱动器自己决定
    true|false false
    timeout 设置驱动器在抛出异常前等待回应的最长时间,默认为不设值,由驱动器自己决定 正整数 未设置
    fetchSize 设置一个值后,驱动器会在结果集数目达到此数值后,激发返回,默认为不设值,由驱动器自己决定 正整数 驱动器决定
    statementType statement,preparedstatement,callablestatement。
    预准备语句、可调用语句
    STATEMENT
    PREPARED
    CALLABLE
    PREPARED
    useGeneratedKeys

    告诉MyBatis 使用JDBC 的getGeneratedKeys 方法来获取数据库自己生成的主键(MySQL、SQLSERVER 等

    关系型数据库会有自动生成的字段)。默认:false

    true|false false
    keyProperty

    标识一个将要被MyBatis 设置进getGeneratedKeys 的key 所返回的值,或者为insert 语句使用一个selectKey

    子元素。

       

    selectKey语句属性配置细节:

    属性 描述 取值
    keyProperty selectKey 语句生成结果需要设置的属性。  
    resultType 生成结果类型,MyBatis 允许使用基本的数据类型,包括String 、int类型。  
    order 可以设成BEFORE 或者AFTER,如果设为BEFORE,那它会先选择主键,
    然后设置keyProperty,再执行insert语句;如果设为AFTER,它就先运行insert 语句再运行selectKey 语句,
    通常是insert 语句中内部调用数据库(像Oracle)内嵌的序列机制。
    BEFORE
    AFTER
    statementType 像上面的那样, MyBatis 支持STATEMENT,PREPARED和CALLABLE 的语句形式,
     对应Statement ,PreparedStatement 和CallableStatement 响应
    STATEMENT
    PREPARED
    CALLABLE

    UPDATE,DELETE

    update 简单例子:
    1. <?xml version="1.0" encoding="UTF-8" ?>  
    2. <!DOCTYPE mapper  
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
    5. <mapper namespace="com.accp.mybatis.model.Blog">  
    6.     <update id="updateBlog" parameterType="Blog">    
    7.        UPDATE Blog    
    8.             SET title = #{title},     
    9.                 author_id = #{author.id},    
    10.          WHERE id = #{id};  
    11.     </update>    
    12. </mapper>  

    delete 简单例子:
    1. <delete id="deleteBlog" parameterType="Blog">    
    2.       DELETE FROM BLOG WHERE ID = #{id}    
    3. </delete>  

    update、delete语句属性配置细节:

    属性 描述 取值 默认
    id 在这个模式下唯一的标识符,可被其它语句引用    
    parameterType 传给此语句的参数的完整类名或别名    
    flushCache 如果设为true,则会在每次语句调用的时候就会清空缓存。select 语句默认设为false true|false false
    useCache 如果设为true,则语句的结果集将被缓存。select 语句默认设为false true|false false
    timeout 设置驱动器在抛出异常前等待回应的最长时间,默认为不设值,由驱动器自己决定
    true|false false
    timeout 设置驱动器在抛出异常前等待回应的最长时间,默认为不设值,由驱动器自己决定 正整数 未设置
    fetchSize 设置一个值后,驱动器会在结果集数目达到此数值后,激发返回,默认为不设值,由驱动器自己决定 正整数 驱动器决定
    statementType statement,preparedstatement,callablestatement。
    预准备语句、可调用语句
    STATEMENT
    PREPARED
    CALLABLE
    PREPARED

    Parameters

    这个元素说的直白点就是定义参数。注意一个语句中只能有一个参数。
    所以参数类型在以后的使用中,可能需要复杂的类型,比如hashmap,一个复杂的对象等。例如:

    1. <?xml version="1.0" encoding="UTF-8" ?>  
    2. <!DOCTYPE mapper  
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
    5. <mapper namespace="com.accp.mybatis.model.Blog">  
    6.       
    7.     <insert id="insertBlog" parameterType="Blog">  
    8.         insert into Blog  
    9.             (id,title,author_id)  
    10.         values  
    11.             (#{id},#{title},#{author.id})  
    12.     </insert>  
    13. </mapper>  


    如果blog类型的参数对象传递到了语句中,id、title和author属性将会被查找,然后它们的值就被传递到预处理语句的参数中。
    这点对于传递参数到语句中非常好。但是对于参数映射也有一些其他的特性。
    首先,像MyBatis的其他部分,参数可以指定一个确定的数据类型。
    1. #{property,javaType=int,jdbcType=NUMERIC}  
    像MyBatis的剩余部分,javaType通常可以从参数对象中来确定,除非对象是一个HashMap。那么javaType应该被确定来保证使用正确类型处理器。
    注意:如果null被当作值来传递,对于所有可能为空的列,JDBC Type是需要的。也可以通过阅读PreparedStatement. setNull()方法的JavaDocs文档来研究它。
    为了以后自定义类型处理器,你可以指定一个确定的类型处理器类(或别名),比如:
    1. #{age,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}  
    尽管它看起来繁琐,但是实际上是你很少设置它们其中之一。
    对于数值类型,对于决定有多少数字是相关的,有一个数值范围。
    1. #{height,javaType=double,jdbcType=NUMERIC,numericScale=2}  
    mode 属性允许你指定IN,OUT或INOUT参数。如果参数为OUT或INOUT,参数对象属性的真实值将会被改变,就像你期望你需要你个输出参数。如果 mode为OUT(或INOUT),而且jdbcType为CURSOR(也就是Oracle的REFCURSOR),你必须指定一个resultMap 来映射结果集到参数类型。要注意这里的javaType属性是可选的,如果左边的空白是jdbcType的CURSOR类型,它会自动地被设置为结果集。
    1. #{department,  
    2.     mode=OUT,  
    3.     jdbcType=CURSOR,  
    4.     javaType=ResultSet,  
    5.     resultMap=departmentResultMap}  
    字符串替换
    默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速,也是首选的做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:
    ORDER BY ${columnName}
    这里MyBatis不会修改或转义字符串。

    重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。

    resultMap

    resultMap 元素是MyBatis中最重要最强大的元素。它就是让你远离90%的需要从结果集中取出数据的JDBC代码的那东西,而且在一些情形下允许你做一些 JDBC不支持的事情。事实上,编写相似于对复杂语句联合映射这些等同的代码,也许可以跨过上千行的代码。ResultMap的设计就是简单语句不需要明 确的结果映射,而很多复杂语句确实需要描述它们的关系。

    1. package com.accp.mybatis.model;  
    2.   
    3. public class Blog {  
    4.     private Integer id;  
    5.     private String title;  
    6.     private Integer authorId;  
    7.   
    8. //省略get和set方法  
    9. }  

    基于JavaBean的规范,上面这个类有3个属性:id,title和authorId。这些在select语句中会精确匹配到列名。
    这样的一个JavaBean可以被映射到结果集,就像映射到HashMap一样简单。
    1. <?xml version="1.0" encoding="UTF-8" ?>  
    2. <!DOCTYPE mapper  
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
    5. <mapper namespace="com.accp.mybatis.model.Blog">    
    6.       
    7.     <select id="selectBlog_by_id" parameterType="int" resultType="Blog">  
    8.         select * from Blog where id = #{id}  
    9.     </select>  
    10.   
    11. </mapper>  

    这些情况下,MyBatis会在幕后自动创建一个ResultMap,基于属性名来映射列到JavaBean的属性上。如果列名没有精确匹配,你可以在列名上使用select字句的别名(一个标准的SQL特性)来匹配标签。
    ResultMap最优秀的地方你已经了解了很多了,但是你还没有真正的看到一个。只是出于示例的原因,让我们来看看最后一个示例中外部的resultMap是什么样子的,这也是解决列名不匹配的另外一种方式。

    1. <resultMap id="Blog_result" type="Blog" >  
    2.     <id column="id" property="id" />  
    3.     <result column="title" property="title"/>  
    4.     <result column="author_id" property="authorId"/>  
    5. </resultMap>  



    引用它的语句使用resultMap属性就行了(注意我们去掉了resultType属性)。比如:
      1. <?xml version="1.0" encoding="UTF-8" ?>  
      2. <!DOCTYPE mapper  
      3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
      4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
      5. <mapper namespace="com.accp.mybatis.model.Blog">  
      6.   
      7.   
      8.     <resultMap id="Blog_result" type="Blog" >  
      9.         <id column="id" property="id" />  
      10.         <result column="title" property="title"/>  
      11.         <result column="author_id" property="authorId"/>  
      12.     </resultMap>    
      13.   
      14.     <!-- resultType与resultMap不能同时使用 -->     
      15.     <select id="selectBlog_by_id" parameterType="int" resultMap="Blog_result">  
      16.         select * from Blog where id = #{id}  
      17.     </select>  
      18.   
      19. </mapper> 
  • 相关阅读:
    docker 安装mysql
    Java web项目搭建系列之二 Jetty下运行项目
    Java web项目搭建系列之一 Eclipse中新建Maven项目
    Maven 添加其他Maven组件配置问题
    C# 中定义扩展方法
    Oracle 函数
    【Webservice】2 counts of IllegalAnnotationExceptions Two classes have the same XML type name
    Linux精简版系统安装网络配置问题解决
    Rsync 故障排查整理
    Failed to set session cookie. Maybe you are using HTTP instead of HTTPS to access phpMyAdmin.
  • 原文地址:https://www.cnblogs.com/charlexu/p/2961116.html
Copyright © 2011-2022 走看看