精华内容
参与话题
问答
  • ResultType和ResultMap的用法和区别

    千次阅读 2019-04-07 22:06:39
    ResultType 返回常见类型:(类似于int或者Integer) 返回Map 返回一个对象 ResultMap 基本使用 id和result 高级使用 Constructor元素 Association Collection discriminator 综述 MyBatis中在查询...

    目录

    综述

    ResultType

    返回常见类型:(类似于int或者Integer)

    返回Map

    返回一个对象

    ResultMap

    基本使用

    id和result

    高级使用

    Constructor元素

    Association

    Collection

    discriminator


     


    综述

    MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用,但是resultType跟resultMap不能同时存在。
    在MyBatis进行查询映射时,其实查询出来的每一个属性都是放在一个对应的Map里面的,其中键是属性名,值则是其对应的值。
    ①当提供的返回类型属性是resultType时,MyBatis会将Map里面的键值对取出赋给resultType所指定的对象对应的属性。所以其实MyBatis的每一个查询映射的返回类型都是ResultMap,只是当提供的返回类型属性是resultType的时候,MyBatis对自动的给把对应的值赋给resultType所指定对象的属性。
    ②当提供的返回类型是resultMap时,因为Map不能很好表示领域模型,就需要自己再进一步的把它转化为对应的对象,这常常在复杂查询中很有作用。

    ResultType

    resultType可以直接返回给出的返回值类型,比如String、int、Map,等等,其中返回List也是将返回类型定义为Map,然后mybatis会自动将这些map放在一个List中,resultType还可以是一个对象,举例如下:

    返回常见类型:(类似于int或者Integer)

      <select id="getLogCount" resultType="int">
        select COUNT(*) from AttLog where attTime = #{attTime} and userId = #{userId};
      </select>

    返回Map

    <select id="getDeviceInfoByDeviceId" resultType="Map">
      select userCount as usercount,
      fingerCount as fingercount,
      faceCount as facecount,
      attRecordCount as recordcount,
      lastOnline,
      state as status
      from DeviceInfo where deviceId = #{deviceId} and tb_isDelete = 0;
    </select>

    返回一个对象或者一个list(list里面是resultType的类型)

    <select id="queryAllDeviceInfo" resultType="com.cachee.ilabor.att.clientmodel.DeviceInfo">
    select * from deviceInfo where tb_isDelete = 0;
    </select>

    返回一个对象

    对于SQL语句查询出的字段在相应的pojo中必须有和它相同的字段对应。

    但是,如果列名没有精确匹配,你可以在列名上使用 select 字句的别名(一个 基本的 SQL 特性)来匹配标签。

    <select id="selectUsers" parameterType="int" resultType="User">
      select
        user_id             as "id",
        user_name           as "userName",
        hashed_password     as "hashedPassword"
      from some_table
      where id = #{id}
    </select>
    

    resultType对应的是java对象中的属性,大小写不敏感,
    resultType如果放的是java.lang.Map,key是查询语句的列名,value是查询的值,大小写敏感
    resultMap:指的是定义好了的id的,是定义好的resyltType的引用
    注意:用resultType的时候,要保证结果集的列名与java对象的属性相同,而resultMap则不用,而且resultMap可以用typeHander转换
    parameterType:参数类型,只能传一个参数,如果有多个参数要封装,如封装成一个类,要写包名加类名,基本数据类型则可以省略
    一对1、一对多时,若有表的字段相同必须写别名,不然查询结果无法正常映射,出现某属性为空或者返回的结果与想象中的不同,而这往往是没有报错的。

    ResultMap

    基本使用

    适合使用返回值是自定义实体类的情况

    映射实体类的数据类型

    id:resultMap的唯一标识

    column: 库表的字段名

    property: 实体类里的属性名

    配置映射文件:

    <?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">
    <!-- namespace:当前库表映射文件的命名空间,唯一的不能重复 -->
    <mapper namespace="com.hao947.sql.mapper.PersonMapper">
      <!-- type:映射实体类的数据类型 id:resultMap的唯一标识 -->
      <resultMap type="person" id="BaseResultMap">
        <!-- column:库表的字段名 property:实体类里的属性名 -->
        <id column="person_id" property="personId" />
        <result column="name" property="name" />
        <result column="gender" property="gender" />
        <result column="person_addr" property="personAddr" />
        <result column="birthday" property="birthday" />
      </resultMap>
      <!--id:当前sql的唯一标识
         parameterType:输入参数的数据类型 
         resultType:返回值的数据类型 
         #{}:用来接受参数的,如果是传递一个参数#{id}内容任意,如果是多个参数就有一定的规则,采用的是预编译的形式select 
        * from person p where p.id = ? ,安全性很高 -->
    
      <!-- sql语句返回值类型使用resultMap -->
      <select id="selectPersonById" parameterType="java.lang.Integer"
        resultMap="BaseResultMap">
        select * from person p where p.person_id = #{id}
      </select>
      <!-- resultMap:适合使用返回值是自定义实体类的情况 
      resultType:适合使用返回值的数据类型是非自定义的,即jdk的提供的类型 -->
      <select id="selectPersonCount" resultType="java.lang.Integer">
        select count(*) from
        person
      </select>
    
      <select id="selectPersonByIdWithMap" parameterType="java.lang.Integer"
        resultType="java.util.Map">
        select * from person p where p.person_id= #{id}
        </select>
    
    </mapper>

    id和result

    <id property="id" column="post_id"/>

    <result property="subject" column="post_subject"/>

    这是最基本的结果集映射。id 和result 将列映射到属性或简单的数据类型字段(String, int, double, Date等)。

    这两者唯一不同的是,在比较对象实例时id 作为结果集的标识属性。这有助于提高总体性能,特别是应用缓存和嵌套结果映射的时候。

    Id、result属性如下:

    Attribute

    Description

    property

    映射数据库列的字段或属性。如果JavaBean 的属性与给定的名称匹配,就会使用匹配的名字。否则,MyBatis 将搜索给定名称的字段。两种情况下您都可以使用逗点的属性形式。比如,您可以映射到“username”,也可以映射到“address.street.number”。

    column

    数据库的列名或者列标签别名。与传递给resultSet.getString(columnName)的参数名称相同。

    javaType

    完整java类名或别名(参考上面的内置别名列表)。如果映射到一个JavaBean,那MyBatis 通常会自行检测到。然而,如果映射到一个HashMap,那您应该明确指定javaType 来确保所需行为。

    jdbcType

    这张表下面支持的JDBC类型列表列出的JDBC类型。这个属性只在insert,update或delete 的时候针对允许空的列有用。JDBC 需要这项,但MyBatis 不需要。如果您直接编写JDBC代码,在允许为空值的情况下需要指定这个类型。

    typeHandler

    我们已经在文档中讨论过默认类型处理器。使用这个属性可以重写默认类型处理器。它的值可以是一个TypeHandler实现的完整类名,也可以是一个类型别名。

    高级使用

    MyBatis的创建基于这样一个思想:数据库并不是您想怎样就怎样的。虽然我们希望所有的数据库遵守第三范式或BCNF(修正的第三范式),但它们不是。如果有一个数据库能够完美映射到所有应用程序,也将是非常棒的,但也没有。结果集映射就是MyBatis为解决这些问题而提供的解决方案。

    示例

    <!-- 超复杂的 Result Map -->
    <resultMap id="detailedBlogResultMap" type="Blog">
      <constructor>
        <idArg column="blog_id" javaType="int"/>
      </constructor>
      <result property="title" column="blog_title"/>
      <association property="author" javaType="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"/>
        <result property="favouriteSection" column="author_favourite_section"/>
      </association>
      <collection property="posts" ofType="Post">
        <id property="id" column="post_id"/>
        <result property="subject" column="post_subject"/>
        <association property="author" javaType="Author"/>
        <collection property="comments" ofType="Comment">
          <id property="id" column="comment_id"/>
        </collection>
        <collection property="tags" ofType="Tag" >
          <id property="id" column="tag_id"/>
        </collection>
        <discriminator javaType="int" column="draft">
          <case value="1" resultType="DraftPost"/>
        </discriminator>
      </collection>
    </resultMap>

    resultMap

    ·constructor–实例化的时候通过构造器将结果集注入到类中

    idArg,arg–注入构造器的结果集

    ·id–结果集ID,将结果集标记为ID,以方便全局调用

    ·result–注入一个字段或者javabean属性的结果

    ·association–复杂类型联合;许多查询结果合成这个类型

    嵌套结果映射– associations能引用自身,或者从其它地方引用,

    ·collection–复杂类型集合

    嵌套结果映射– collections能引用自身,或者从其它地方引用

    ·discriminator–使用一个结果值以决定使用哪个resultMap

    case–基于不同值的结果映射

    嵌套结果映射–case也能引用它自身, 所以也能包含这些同样的元素。它也可以从外部引用resultMap

    注意:

    public class A{
        private B b1;
        private List<B> b2;
    }
    在映射b1属性时用association标签, 映射b2时用collection标签,分别是一对一,一对多的关系

    Constructor元素

    通常情况下, java实体类的属性都有get和set方法,但是在有的不变类中,没有get和set方法,只能在构造器中注入属性,这个时候就要constructor元素

    <constructor>
    
    <idArg column="id" javaType="int"/>
    
    <arg column=”username” javaType=”String”/>
    
    </constructor>

    当属性与DTO,或者与您自己的域模型一起工作的时候,许多场合要用到不变类。通常,包含引用,或者查找的数据很少或者数据不会改变的的表,适合映射到不变类中。构造器注入允许您在类实例化后给类设值,这不需要通过public方法。MyBatis同样也支持private属性和JavaBeans的私有属性达到这一点,但是一些用户可能更喜欢使用构造器注入。构造器元素可以做到这点。

    public class User {
       //...
       public User(Integer id, String username, int age) {
         //...
      }
    //...
    }


    为了将结果注入构造方法,MyBatis需要通过某种方式定位相应的构造方法。 
    在下面的例子中,MyBatis搜索一个声明了三个形参的的构造方法,以 java.lang.Integer, java.lang.String and int 的顺序排列。

    <constructor>
       <idArg column="id" javaType="int"/>
       <arg column="username" javaType="String"/>
       <arg column="age" javaType="_int"/>
    </constructor>
    


    当你在处理一个带有多个形参的构造方法时,很容易在保证 arg 元素的正确顺序上出错。 从版本 3.4.3 开始,可以在指定参数名称的前提下,以任意顺序编写 arg 元素。 为了通过名称来引用构造方法参数,你可以添加 @Param 注解,或者使用 ‘-parameters’ 编译选项并启用 useActualParamName 选项(默认开启)来编译项目。 下面的例子对于同一个构造方法依然是有效的,尽管第二和第三个形参顺序与构造方法中声明的顺序不匹配。

    <constructor>
       <idArg column="id" javaType="int" name="id" />
       <arg column="age" javaType="_int" name="age" />
       <arg column="username" javaType="String" name="username" />
    </constructor>


    如果类中存在名称和类型相同的属性,那么可以省略 javaType 。 
    剩余的属性和规则和普通的 id 和 result 元素是一样的。

    constructor - 用于在实例化类时,注入结果到构造方法中 
    idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能 
    arg - 将被注入到构造方法的一个普通结果 

    <constructor>
    
    <idArg column="id" javaType="int"/>
    
    <arg column=”username” javaType=”String”/>
    
    </constructor>

    其它的属性与规则与id、result元素的一样。

    Attribute

    Description

    column

    数据库的列名或者列标签别名。与传递给resultSet.getString(columnName)的参数名称相同。

    javaType

    完整java类名或别名(参考上面的内置别名列表)。如果映射到一个JavaBean,那MyBatis 通常会自行检测到。然而,如果映射到一个HashMap,那您应该明确指定javaType 来确保所需行为。

    jdbcType

    支持的JDBC类型列表中列出的JDBC类型。这个属性只在insert,update 或delete 的时候针对允许空的列有用。JDBC 需要这项,但MyBatis 不需要。如果您直接编写JDBC代码,在允许为空值的情况下需要指定这个类型。

    typeHandler

    我们已经在文档中讨论过默认类型处理器。使用这个属性可以重写默认类型处理器。它的值可以是一个TypeHandler实现的完整类名,也可以是一个类型别名。

     

    Association

    关联

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


    关联元素处理“有一个”类型的关系。比如,在我们的示例中,一个博客有一个用户。 
    关联映射就工作于这种结果之上。你指定了目标属性,来获取值的列,属性的 java 类型(很多情况下 MyBatis 可以自己算出来),如果需要的话还有 jdbc 类型,如果你想覆盖或获取的结果值还需要类型控制器。 
    关联中不同的是你需要告诉 MyBatis 如何加载关联。MyBatis 在这方面会有两种不同的 
    方式: 

    ·Nested Select:通过执行另一个返回预期复杂类型的映射SQL语句(即引用外部定义好的SQL语句块)。

    ·Nested Results:通过嵌套结果映射(nested result mappings)来处理联接结果集(joined results)的重复子集。

     

    它不同于普通只有select和resultMap属性的结果映射。

    Attribute

    Description

    property

    映射数据库列的字段或属性。如果JavaBean 的属性与给定的名称匹配,就会使用匹配的名字。否则,MyBatis 将搜索给定名称的字段。两种情况下您都可以使用逗点的属性形式。比如,您可以映射到”username”,也可以映射到更复杂点的”address.street.number”。

    column

    数据库的列名或者列标签别名。与传递给resultSet.getString(columnName)的参数名称相同。

    注意: 在处理组合键时,您可以使用column= “{prop1=col1,prop2=col2}”这样的语法,设置多个列名传入到嵌套查询语句。这就会把prop1和prop2设置到目标嵌套选择语句的参数对象中。

    javaType

    完整java类名或别名(参考上面的内置别名列表)。如果映射到一个JavaBean,那MyBatis 通常会自行检测到。然而,如果映射到一个HashMap,那您应该明确指定javaType 来确保所需行为。

    jdbcType

    支持的JDBC类型列表中列出的JDBC类型。这个属性只在insert,update 或delete 的时候针对允许空的列有用。JDBC 需要这项,但MyBatis 不需要。如果您直接编写JDBC代码,在允许为空值的情况下需要指定这个类型。

    typeHandler

    我们已经在文档中讨论过默认类型处理器。使用这个属性可以重写默认类型处理器。它的值可以是一个TypeHandler实现的完整类名,也可以是一个类型别名。

    联合嵌套选择(Nested Select for Association)

    select

    通过这个属性,通过ID引用另一个加载复杂类型的映射语句。从指定列属性中返回的值,将作为参数设置给目标select 语句。表格下方将有一个例子。注意:在处理组合键时,您可以使用column=”{prop1=col1,prop2=col2}”这样的语法,设置多个列名传入到嵌套语句。这就会把prop1和prop2设置到目标嵌套语句的参数对象中。

    <resultMap id=”blogResult” type=”Blog”>  
    <association property="author" column="blog_author_id" javaType="Author"  
    select=”selectAuthor”/>  
    </resultMap>  
       
    <select id=”selectBlog” parameterType=”int” resultMap=”blogResult”>  
    SELECT * FROM BLOG WHERE ID = #{id}  
    </select>  
       
    <select id=”selectAuthor” parameterType=”int” resultType="Author">  
    SELECT * FROM AUTHOR WHERE ID = #{id}  
    </select>  
    <wbr>  

    我们使用两个select语句:一个用来加载Blog,另一个用来加载Author。Blog的resultMap 描述了使用“selectAuthor”语句来加载author的属性。

    如果列名和属性名称相匹配的话,所有匹配的属性都会自动加载。

    上面的例子,首先执行<select id=“selectBlog”>,执行结果存放到<resultMap id=“blogResult”>结果映射中。“blogResult”是一个Blog类型,从<select id=“selectBlog”>查出的数据都会自动赋值给”blogResult”的与列名匹配的属性,这时blog_id,title等就被赋值了。同时“blogResult”还有一个关联属性"Author",执行嵌套查询select=”selectAuthor”后,Author对象的属性id,username,password,email,bio也被赋于数据库匹配的值。

    Blog
    
    {
    
    blog_id;
    
    title;
    
    Author author
    
    {
    
    id;
    
    username;
    
    password;
    
    email;
    
    bio;
    
    }
    
    }

    虽然这个方法简单,但是对于大数据集或列表查询,就不尽如人意了。这个问题被称为“N+1 选择问题”(N+1 Selects Problem)。概括地说,N+1选择问题是这样产生的:

    ·您执行单条SQL语句去获取一个列表的记录( “+1”)。

    ·对列表中的每一条记录,再执行一个联合select 语句来加载每条记录更加详细的信息(“N”)。

    这个问题会导致成千上万的SQL语句的执行,因此并非总是可取的。

    上面的例子,MyBatis可以使用延迟加载这些查询,因此这些查询立马可节省开销。然而,如果您加载一个列表后立即迭代访问嵌套的数据,这将会调用所有的延迟加载,因此性能会变得非常糟糕。

    鉴于此,这有另外一种方式。

    联合嵌套结果集(Nested Results for Association) 

    resultMap

    一个可以映射联合嵌套结果集到一个适合的对象视图上的ResultMap 。这是一个替代的方式去调用另一个select 语句。它允许您去联合多个表到一个结果集里。这样的结果集可能包括冗余的、重复的需要分解和正确映射到一个嵌套对象视图的数据组。简言之,MyBatis 让您把结果映射‘链接’到一起,用来处理嵌套结果。举个例子会更好理解,例子在表格下方。

    您已经在上面看到了一个非常复杂的嵌套联合的例子,接下的演示的例子会更简单一些。我们把Blog和Author表联接起来查询,而不是执行分开的查询语句:

    <select id="selectBlog" parameterType="int" resultMap="blogResult">  
    select  
    B.id as blog_id,  
    B.title as blog_title,  
    B.author_id as blog_author_id,  
    A.id as author_id,  
    A.username as author_username,  
    A.password as author_password,  
    A.email as author_email,  
    A.bio as author_bio  
    from Blog B left outer join Author A on B.author_id = A.id  
    where B.id = #{id}  
    </select>  


    注意到这个连接(join),要确保所有的别名都是唯一且无歧义的。(为什么用别名呢?用别名的目的就是确保唯一无歧义。今天写了一段代码,没有返回List类型的结果集,检查了很久也没报错,最后加上别名,唯一区别开来就好了。估计是两个表中有个别字段歧义)这使映射容易多了,现在我们来映射结果集:

    <resultMap id="blogResult" type="Blog">  
    <id property=”blog_id” column="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>  

    在上面的例子中,您会看到Blog的作者(“author”)联合一个“authorResult”结果映射来加载Author实例。

    重点提示:id元素在嵌套结果映射中扮演了非常重要的角色,您应该总是指定一个或多个属性来唯一标识这个结果集。事实上,如果您没有那样做,MyBatis也会工作,但是会导致严重性能开销。选择尽量少的属性来唯一标识结果,而使用主键是最明显的选择(即使是复合主键)。

    上面的例子使用一个扩展的resultMap 元素来联合映射。这可使Author结果映射可重复使用。然后,如果您不需要重用它,您可以直接嵌套这个联合结果映射。下面例子就是使用这样的方式: 

    <resultMap id="blogResult" type="Blog">  
    <id property=”blog_id” column="id" />  
    <result property="title" column="blog_title"/>  
    <association property="author" column="blog_author_id" javaType="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"/>  
    </association>  
    </resultMap> 

    在上面的例子中您已经看到如果处理“一对一”(“has one”)类型的联合查询。

    Collection

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

    collection元素的作用差不多和association元素的作用一样。事实上,它们非常相似,以至于再对相似点进行描述会显得冗余,因此我们只关注它们的不同点。

    继续我们上面的例子,一个Blog只有一个Author。但一个Blog有许多帖子(文章)。在Blog类中,会像下面这样定义相应属性: 

    private List<Post> posts;

    映射一个嵌套结果集到一个列表,我们使用collection元素。就像association 元素那样,我们使用嵌套查询,或者从连接中嵌套结果集。 

    集合嵌套选择(Nested Select for Collection)

    首先我们使用嵌套选择来加载Blog的文章。 

    <resultMap id=”blogResult” type=”Blog”>  
    <collection property="posts" javaType=”ArrayList” column="blog_id"  
    ofType="Post" select=”selectPostsForBlog”/>  
    </resultMap>  
       
    <select id=”selectBlog” parameterType=”int” resultMap=”blogResult”>  
    SELECT * FROM BLOG WHERE ID = #{id}  
    </select>  
       
    <select id=”selectPostsForBlog” parameterType=”int” resultType="Author">  
    SELECT * FROM POST WHERE BLOG_ID = #{id}  
    </select>  

    一看上去这有许多东西需要注意,但大部分看起与我们在association元素中学过的相似。首先,您会注意到我们使用了collection元素,然后会注意到一个新的属性“ofType”。这个元素是用来区别JavaBean属性(或者字段)类型和集合所包括的类型。因此您会读到下面这段代码。

    <collection property="posts" javaType=”ArrayList” column="blog_id"
    
    ofType="Post" select=”selectPostsForBlog”/>

    理解为:“一个名为posts,类型为Post的ArrayList集合(A collection of posts in an ArrayList of type Post)” 。

    javaType属性不是必须的,通常MyBatis 会自动识别,所以您通常可以简略地写成:

    <collection property="posts" column="blog_id" ofType="Post"
    
    select=”selectPostsForBlog”/>

     

    集合的嵌套结果集(Nested Results for Collection)

    这时候,您可能已经猜出嵌套结果集是怎样工作的了,因为它与association非常相似,只不过多了一个属性“ofType”

    <select id="selectBlog" parameterType="int" resultMap="blogResult">  
    select  
    B.id as blog_id,  
    B.title as blog_title,  
    B.author_id as blog_author_id,  
    P.id as post_id,  
    P.subject as post_subject,  
    P.body as post_body,  
    from Blog B  
    left outer join Post P on B.id = P.blog_id  
    where B.id = #{id}  
    </select>

      
    同样,我们把Blog和Post两张表连接在一起,并且也保证列标签名在映射的时候是唯一且无歧义的。现在将Blog和Post的集合映射在一起是多么简单:

    <resultMap id="blogResult" type="Blog">  
    <id property=”id” column="blog_id" />  
    <result property="title" column="blog_title"/>  
    <collection property="posts" ofType="Post">  
    <id property="id" column="post_id"/>  
    <result property="subject" column="post_subject"/>  
    <result property="body" column="post_body"/>  
    </collection>  
    </resultMap>  

    再次强调一下,id 元素是非常重要的。如果您忘了或者不知道id 元素的作用,请先读一下上面association一节。

    如果希望结果映射有更好的可重用性,您可以使用下面的方式:

    <resultMap id="blogResult" type="Blog">  
    <id property=”id” column="blog_id" />  
    <result property="title" column="blog_title"/>  
    <collection property="posts" ofType="Post" resultMap=”blogPostResult”/>  
    </resultMap>  
       
    <resultMap id="blogPostResult" type="Post">  
    <id property="id" column="post_id"/>  
    <result property="subject" column="post_subject"/>  
    <result property="body" column="post_body"/>  
    </resultMap>  

    在您的映射中没有深度、宽度、联合和集合数目的限制。但应该谨记,在进行映射的时候也要考虑性能的因素。应用程序的单元测试和性能测试帮助您发现最好的方式可能要花很长时间。但幸运的是,MyBatis允许您以后可以修改您的想法,这时只需要修改少量代码就行了。

    discriminator

    <discriminator javaType="int" column="draft">
      <case value="1" resultType="DraftPost"/>
    </discriminator>


    有时一个单独的数据库查询也许返回很多不同(但是希望有些关联)数据类型的结果集。 
    鉴别器元素就是被设计来处理这个情况的,还有包括类的继承层次结构。鉴别器非常容易理解,因为它的表现很像 Java 语言中的 switch 语句。 

    定义鉴别器指定了 column 和 javaType 属性。 
    (1)column 是 MyBatis 查找比较值的地方。 
    (2)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 会从结果集中得到每条记录,然后比较它的 vehicle 类型的值。 
    如果它匹配任何一个鉴别器的实例,那么就使用这个实例指定的结果映射。换句话说,这样做完全是剩余的结果映射被忽略(除非它被扩展,这在第二个示例中讨论)。如果没有任何一个实例相匹配,那么 MyBatis 仅仅使用鉴别器块外定义的结果映射。所以,如果 carResult按如下声明:

    <resultMap id="carResult" type="Car">
      <result property="doorCount" column="door_count" />
    </resultMap>


    那么只有 doorCount 属性会被加载。这步完成后完整地允许鉴别器实例的独立组,尽管 
    和父结果映射可能没有什么关系。这种情况下,我们当然知道 cars 和 vehicles 之间有关系,如 Car 是一个 Vehicle 实例。因此,我们想要剩余的属性也被加载。我们设置的结果映射的简单改变如下。

    <resultMap id="carResult" type="Car" extends="vehicleResult">
      <result property="doorCount" column="door_count" />
    </resultMap>


    现在 vehicleResult 和 carResult 的属性都会被加载了。 
    尽管曾经有些人会发现这个外部映射定义会多少有一些令人厌烦之处。 
    因此还有另外一种语法来做简洁的映射风格。比如:

    <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" resultType="carResult">
          <result property="doorCount" column="door_count" />
        </case>
        <case value="2" resultType="truckResult">
          <result property="boxSize" column="box_size" />
          <result property="extendedCab" column="extended_cab" />
        </case>
        <case value="3" resultType="vanResult">
          <result property="powerSlidingDoor" column="power_sliding_door" />
        </case>
        <case value="4" resultType="suvResult">
          <result property="allWheelDrive" column="all_wheel_drive" />
        </case>
      </discriminator>
    </resultMap>


    要记得这些都是结果映射,如果你不指定任何结果,那么 MyBatis 将会为你自动匹配列 
    和属性。所以这些例子中的大部分是很冗长的,而其实是不需要的。也就是说,很多数据库是很复杂的,我们不太可能对所有示例都能依靠它。
     

    展开全文
  • mybatis resultType返回类型汇总。

    万次阅读 2016-01-13 10:02:40
    1.返回List> 1 2 selectid="getMyCredit"parameterClass="java.util.Map"resultClass="java.util.HashMap"> select> 这样设置返回类型为resultClass="java.util.Ha
     
    1.返回List<Map<String,Object>>
     
    1
    2
    <select id="getMyCredit"  parameterType="java.util.Map" resultType="java.util.HashMap">
    </select>

    这样设置返回类型为resultClass="java.util.HashMap",查询时执行queryForList
    Java code
     
    ?
    1
    List<Map<String,Object>> list = fspDao.queryForList("XX.xx",params);
    即可
     
    2.返回List<String>
    如果要想返回为List<String>只需要设置resultClass="java.lang.String"
    展开全文
  • MyBatis查询结果resultType返回值类型详细介绍

    万次阅读 多人点赞 2018-03-12 08:56:41
    一、返回一般数据类型 比如要根据id 属性获得数据库中的某个字段值。 mapper 接口: // 根据id 获得数据库中的username 字段的值 String getEmpNameById... 指定resultType 返回值类型时String 类型的, str...

    一、返回一般数据类型

    比如要根据 id 属性获得数据库中的某个字段值。

    mapper 接口:

        // 根据 id 获得数据库中的 username 字段的值
        String getEmpNameById(Integer id);

    SQL 映射文件:

        <!-- 
            指定 resultType 返回值类型时 String 类型的,
            string 在这里是一个别名,代表的是 java.lang.String 
    
            对于引用数据类型,都是将大写字母转小写,比如 HashMap 对应的别名是 'hashmap'
            基本数据类型考虑到重复的问题,会在其前面加上 '_',比如 byte 对应的别名是 '_byte'
        -->
        <select id="getEmpNameById" resultType="string">
            select username from t_employee where id = #{id}
        </select>

    二、返回 JavaBean 类型

    比如根据某个字段获得数据库中的信息,把查询的结果信息封装成某个 JavaBean 类型的数据。

    mapper 接口:

        // 根据 id 查询信息,并把信息封装成 Employee 对象
        Employee getEmpById(Integer id);

    SQL 映射文件:

        <!-- 
            通过 resultType 指定查询的结果是 Employee 类型的数据  
            只需要指定 resultType 的类型,MyBatis 会自动将查询的结果映射成 JavaBean 中的属性
        -->
        <select id="getEmpById" resultType="employee">
            select * from t_employee where id = #{id}
        </select>

    三、返回List类型

    有时候我们要查询的数据不止一条,比如:模糊查询,全表查询等,这时候返回的数据可能不止是一条数据,对于多数据的处理可以存放在List集合中。

    mapper 接口:

        // 假如是全表查询数据,将查询的数据封装成 Employee 类型的集合
        List<Employee> getAllEmps();

    SQL 映射文件:

        <!--
            注意这里的 resultType 返回值类型是集合内存储数据的类型,不是 'list'
        -->
        <select id="getAllEmps" resultType="employee">
            select * from t_employee
        </select>

    四、返回Map类型

    MyBatis 还支持将查询的数据封装成Map

    1. 如果查询的结果是一条,我们可以把查询的数据以{表字段名, 对应的值}方式存入到Map中。

    mapper 接口:

        //  根据 id 查询信息,并把结果信息封装成 Map 
        Map<String, Object> getEmpAsMapById(Integer id);

    SQL 映射文件:

        <!-- 
            注意这里的 resultType 返回值类型是 'map'
         -->
        <select id="getEmpAsMapById" resultType="map">
            select * from t_employee where id = #{id}
        </select>

    下面把查询的结果数据贴出来供大家参考:
    这里写图片描述
    2. 如果查询的结果是多条数据,我们也可以把查询的数据以{表中某一字段名, JavaBean}方式来封装成Map

    mapper 接口:

        // 查询所有员工的信息,把数据库中的 'id' 字段作为 key,对应的 value 封装成 Employee 对象
        // @MapKey 中的值表示用数据库中的哪个字段名作 key
        @MapKey("id")
        Map<Integer, Employee> getAllEmpsAsMap();

    SQL 映射文件:

        <!--
            注意 resultType 返回值类型,不再是 'map',而是 Map 的 value 对应的 JavaBean 类型
        -->
        <select id="getAllEmpsAsMap" resultType="employee">
            select * from t_employee
        </select>

    下面是查询的结果 (只截取了一部分):
    这里写图片描述

    MyBatis 允许查询的结果封装成Map,这种机制是极好的。

    五、扩展

    扩展. 上面返回结果的形式都是基于查询 (select) 的,其实对于增删改的操作也可以返回一定类型的数据,比如BooleanInteger等。

    总结. 这篇博文主要介绍了在开发中常用的几种数据返回值类型,希望能够为你提供帮助。

    展开全文
  • Mybatis之resultType详解

    千次阅读 2018-07-29 00:09:41
    resultType是sql映射文件中定义返回值类型,返回值有基本类型,对象类型,List类型,Map类型等。 resultType: 基本类型 :resultType=基本类型 List类型: resultType=List中元素的类型 Map类型 单条记录:...

           resultType是sql映射文件中定义返回值类型,返回值有基本类型,对象类型,List类型,Map类型等。

    resultType:

    基本类型  :resultType=基本类型

    List类型:   resultType=List中元素的类型

    Map类型    单条记录:resultType =map

                       多条记录:resultType =Map中value的类型

    对象类型:对于对象类型resultType直接写对象的全类名就可以了


    1、基本数据类型,例如int

       studentMapper接口

    package com.bj58.mybatis.dao;

    import com.bj58.mybatis.po.Student;

    public interface StudentMapper {

    //返回值类型为int

    public int countStudent(long userid);

    }

       studentMapper.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.bj58.mybatis.dao.StudentMapper"> <!--resultType直接写对象的全类名 --> <select id="countStudent" resultType="int"> select COUNT(*) from user where attTime = #{attTime} and userId = #{userId}; </select> </mapper>


    2、List类型,返回值为List类型,resultType为List中对象的类型,如List<Student>,resultType为Student

    studentMapper接口

    package com.bj58.mybatis.dao;

    import java.util.List;

    import com.bj58.mybatis.po.Student;

    public interface StudentMapper{

    // 返回值为List

    public List<Student> getStudent(Integer i);

    }

    studentMapper.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.bj58.mybatis.dao.StudentMapper">

    <!-- 返回值为List,resultType为List中元素的全类名 -->

    <select id="getStudent" resultType="com.bj58.mybatis.po.Student">

    select * from user

    where

    age>#{age}

    </select>

    </mapper>


    3、Map类型,

    a、返回单条记录的map,key为属性,值为属性值。resultType为map

       studentMapper接口

    package com.bj8.mybatis.dao;

    import java.util.Map;

    import com.bj58.mybatis.po.Student;

    public interface StudentMapper {

    // 返回值为Map,key为属性名,value为属性值

    public Map<String, Object> getStudent(Integer i);

    }

       studentMapper.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.bj58.mybatis.dao.StudentMapper">

    <!-- 返回值为map,resultType为map -->

    <select id="getStudentl" resultType="map">

    select * from user

    where

    age=#{age}

    </select>

    </mapper>

    b、返回多条记录的map,key为任意一属性,值为对象类型。如Map<String,Student>,resultType为Student。返回多条记录的map时,key为任意一属性,值为对象类型,不过key需要通过@MapKey("studentName")指定对象中一个属性名为key

    studentMapper接口

    package com.bj8.mybatis.dao;

    import java.util.Map;

    import org.apache.ibatis.annotations.MapKey;

    import com.bj58.mybatis.po.Student;

    public interface StudentMapper {

    // 返回值为Map,key需要通过@MapKey("属性名")来指定javaBean中的一个属性名为key,value为对象

    @MapKey("studentName")

    public Map<String, Student> getStudent(Integer i);

    }

       studentMapper.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.bj58.mybatis.dao.StudentMapper">

    <!-- 返回值为map,resultType为map -->

    <select id="getStudentl" resultType="com.bj58.mybatis.po.Student">

    select * from user

    where

    age=#{age}

    </select>

    </mapper>


    4、对象类型,对于对象类型resultType直接写对象的全类名就可以了

           studentMapper接口

    package com.bj58.mybatis.dao;

    import com.bj58.mybatis.po.Student;

    public interface StudentMapper {

    //返回值类型为Student

    public Student getStudent (Integer i);

    }

        studentMapper.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.bj58.mybatis.dao.StudentMapper">

    <!--resultType直接写对象的全类名 -->

    <select id="getStudent" resultType="com.bj58.mybatis.po.Student">

    select * from user

    where

    age=#{age}

    </select>

    </mapper>

     

    展开全文
  • mybaties中resultMap和resultType的区别

    万次阅读 2019-06-17 22:01:06
    基本映射 :(resultType)使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。(数据库,实体,查询字段,这些全部都得一一对应)高级映射 :(resultMap) 如果查询出来的...
  • resultType和resultMap区别

    2019-06-05 22:43:37
    MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用,但是resultType跟resultMap不能同时存在。...
  • mybatis的resultType

    千次阅读 2019-02-16 17:25:25
    在官方文档中对resultType做了如下介绍:从这条语句中返回的期望类型的类的完全限定名或别名。注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。使用 resultType 或 resultMap,但不能同时使用。...
  • 2、自定义resulttype 学习过程:  Result功能是封装Action层到View层的跳转逻辑。Struts2的Action是一个与Web容器无关的POJO。所以,在Action执行完毕之后,框架需要把代码的执行权重新交还给Web容器,并转向View...
  • mybatis中resultType和resultMap使用时的区别

    万次阅读 多人点赞 2017-09-08 22:10:15
    mybatis中select元素有两个属性resultType和resultMap,工作中总是使用到他们,但是他们有什么区别呢? 就我的使用经验来说,对于单表查询映射或多表联合查询映射来说,他们都能达到要求,例如 package ...
  • ResultType和ResultMap的区别

    千次阅读 2019-03-06 11:07:59
    ResultType和ResultMap都是执行查询语句时返回的结果集 ResultType ResultType相对与ResultMap而言更简单一点。只有满足ORM(Object Relational Mapping,对象关系映射)时,即数据库表中的字段名和实体类中的...
  • Mybatis中的resultType和resultMap

    万次阅读 多人点赞 2014-05-29 13:11:39
    MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用,但是resultType跟resultMap不能同时存在。...
  • resultType输出简单类型

    千次阅读 2018-01-12 20:17:20
    resultType 需求: 用户综合查询功能,要分页显示需要获取符合查询条件的记录总数 实现mybatis查询结果映射成int型。 当查询结果集只有一条记录且一列时可以将结果集映射为一个java简单基本类型。 mapper.xml ...
  • resultMap与resultType、parameterMap与 parameterType的区别

    万次阅读 多人点赞 2017-03-07 21:24:47
     resultMap 与 resultType、parameterMap 与 parameterType的区别在面试的时候被问到的几率非常高,出现的次数到了令人发指的地步,笔者认为有必要单独列一章郑重声明,共勉 resultMap &amp; resultType   ...
  • resultType

    2017-09-25 09:11:00
    ResultType 将查询出来的结果,封装成实体类时。找实体类中,名字一致的属性,如果找不到,就设置为"" 转载于:https://www.cnblogs.com/liuqu/p/7590354.html...
  • mybatis resultType解析

    2019-02-19 20:33:04
    resultType是sql映射文件中定义返回值类型,返回值有基本类型,对象类型,List类型,Map类型等。现总结一下再解释 总结: resultType: 1、基本类型 :resultType=基本类型 2、List类型: resultType=List中元素...
  • MyBatis select标签, 常用元素有:id、parameterType、resultType、resultMap, id:配合Mapper的全限定名,联合成为一个唯一的标识,用户标识这条SQL。 parameterType:表示这条SQL接受的参数类型,可以是...
  • ResultMap和ResultType在使用中的区别

    万次阅读 2019-03-10 10:21:51
    在使用mybatis进行数据库连接操作时对于SQL语句返回结果的处理通常有两种方式,一种就是resultType另一种就是resultMap,下面说下我对这两者的认识和理解 resultType:当使用resultType做SQL语句返回结果类型处理时...
  • resultType跟resultMap不能同时存在

    千次阅读 2016-02-01 01:58:03
    resultType跟resultMap不能同时存在
  • 主要介绍了MyBatis中resultMap和resultType的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 我们知道:MyBatis通过resultType对sql的输出参数进行定义,参数的类型可以是:基本类型、HashMap、pojo。在此分别介绍为resultType传入三种类型的不同处理方式。

空空如也

1 2 3 4 5 ... 20
收藏数 89,829
精华内容 35,931
关键字:

resulttype