• mybatis配置进阶


    结果集的列比resultMap多会报错么?
    不会,只映射resultMap中有的列。

    结果集的列比resultMap少会报错么?
    不会,只映射结果集中有的列。

    高级结果映射

    Xml代码  
        <resultMap id="detailedBlogResultMap" type="Blog">  
            <constructor>  
                <idArg column="blog_id" javaType="int"/>  
            </constructor>  
            <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"/>  
                <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" column="post_author_id" javaType="Author"/>  
                <collection property="comments" column="post_id" ofType=" Comment">  
                    <id property="id" column="comment_id"/>  
                </collection>  
                <collection property="tags" column="post_id" 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 – ID参数;标记结果作为ID可以帮助提高整体效能
               arg – 注入到构造方法的一个普通结果
          id – 一个ID结果;标记结果作为ID可以帮助提高整体效能
          result – 注入到字段或JavaBean属性的普通结果
         association – 一个复杂的类型关联;许多结果将包成这种类型
               嵌入结果映射 – 结果映射自身的关联,或者参考一个
         collection – 复杂类型的集
               嵌入结果映射 – 结果映射自身的集,或者参考一个
        discriminator – 使用结果值来决定使用哪个结果映射
             case – 基于某些值的结果映射
                   嵌入结果映射 – 这种情形结果也映射它本身,因此可以包含很多相同的元素,或者它可以参照一个外部的结果映射。

    id 和result
       
    id和result都映射一个单独列的值到简单数据类型

    这两者之间的唯一不同是id表示的结果将是当比较对象实例时用到的标识属性。这帮助来改进整体表现,特别是缓存和嵌入结果映射(也就是联合映射)。

    它们共有的属性如下:

    property

    映射到列结果的字段或属性。如果匹配的是存在的,和给定名称相同的JavaBeans的属性,那么就会使用。否则MyBatis将会寻找给定名称的字段。这两种情形你可以使用通常点式的复杂属性导航。比如,你可以这样映射一些东西:“username”,或者映射到一些复杂的东西:“address.street.number”。

    column

    从数据库中得到的列名,或者是列名的重命名标签。这也是通常和会传递给resultSet.getString(columnName)方法参数中相同的字符串。

    javaType

    一个Java类的完全限定名,或一个类型别名(参加上面内建类型别名的列表)。如果你映射到一个JavaBean,MyBatis通常可以断定类型。然而,如果你映射到的是HashMap,那么你应该明确地指定javaType来保证所需的行为。

    jdbcType

    在这个表格之后的所支持的JDBC类型列表中的类型。JDBC类型是仅仅需要对插入,更新和删除操作可能为空的列进行处理。这是JDBC的需要,而不是MyBatis的。如果你直接使用JDBC编程,你需要指定这个类型-但仅仅对可能为空的值。

    typeHandler

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


    constructor

    。构造方法注入允许你在初始化时为类设置属性的值,而不用暴露出公有方法。MyBatis也支持私有属性和私有JavaBeans属性来达到这个目的,但是一些人更青睐构造方法注入。

    为了向这个构造方法中注入结果,MyBatis需要通过它的参数的类型来标识构造方法。Java没有自查(反射)参数名的方法。所以当创建一个构造方法元素时,保证参数是按顺序排列的,而且数据类型也是确定的。

    association

    association关联元素处理“有一个”类型的关系,即一对一关联。它有两种关联方式

    嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型。

    嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集。

    嵌套查询

    Xml代码 
        <resultMap  id="userResultMap" type="User">  
            <id property="id" column="ID" jdbcType="NUMERIC" javaType="java.lang.Long"/>  
            <result property="loginName" column="LOGIN_NAME" jdbcType="VARCHAR" javaType="java.lang.String"/>  
            <result property="password" column="password" jdbcType="VARCHAR" javaType="java.lang.String"/>  
            <result property="roleId" column="role_id" jdbcType="NUMERIC" javaType="java.lang.Long"/>  
            <association property="role" column="role_id" javaType="Role" select="selectRole"/>  
        </resultMap>  
          
        <select id="selectUser" parameterType="java.lang.Long" resultMap="userResultMap" >     
            select * from User where id =#{id}     
        </select>   
          
        <select id="selectRole" parameterType="java.lang.Long" resultType="Role" >     
            select * from Role where id =#{id}     
        </select>   

    这里有两个查询,一个查询加载User,一个查询加载Role.
    这里select为另外一个映射语句的ID,可以加载这个属性映射需要的复杂类型。获取的在列属性中指定的列的值将被传递给目标select语句作为参数。

    注意:
    而select 为selectRole的SQL输入参数可以随便给名称,只要是输入参数与压入进去的值类型相同就行了,可以写成:

    Xml代码  
    select * from Role where id = #{sfffs}   

    不管输入参数名称是什么,mybatis最终会执行:
    效果为:

    Sql代码  
    select * from role where id =resultSet.getLong("Role_id");  

    注意:要保证第二个查询查出来的结果只有一条记录。

    要处理复合主键,你可以指定多个列名通过column="{prop1=col1,prop2=col2}"这种语法来传递给嵌套查询语句。这会引起prop1和prop2以参数对象形式来设置给目标嵌套查询语句。

    Xml代码  
    <resultMap  id="userResultMap" type="User">  
        <id property="id" column="ID" jdbcType="NUMERIC" javaType="java.lang.Long"/>  
        <result property="loginName" column="LOGIN_NAME" jdbcType="VARCHAR" javaType="java.lang.String"/>  
        <result property="password" column="password" jdbcType="VARCHAR" javaType="java.lang.String"/>  
        <result property="roleId" column="role_id" jdbcType="NUMERIC" javaType="java.lang.Long"/>  
        <association property="role" column="{id=role_id,name=role_name}" javaType="Role" select="selectRole"/>  
    </resultMap>  
      
    <select id="selectRole" parameterType="HashMap"  resultType="Role" >     
        select * from Role where id =#{id} and name= #{name}     
    </select>

    这种方式很简单,但是对于大型数据集合和列表将不会表现很好。问题就是我们熟知的“N+1查询问题”。概括地讲,N+1查询问题可以是这样引起的:


       你执行了一个单独的SQL语句来获取结果列表(就是“+1”)。
       对返回的每条记录,你执行了一个查询语句来为每个加载细节(就是“N”)。


    这个问题会导致成百上千的SQL语句被执行。这通常不是期望的。


    比如一个查询用户列表的SQL,假如有2000个用户,那么就是一个查询用户的SQL和2000个查询角色的SQL,一共有2001个SQL被运行。


    MyBatis能延迟加载这样的查询就是一个好处,因此你可以分散这些语句同时运行的消耗。然而,如果你加载一个列表,之后迅速迭代来访问嵌套的数据,你会调用所有的延迟加载,这样的行为可能是很糟糕的。

    所以还有另外一种方法
    关联的嵌套结果

    嵌套结果

    Xml代码  
    <resultMap  id="userResultMap" type="User">  
        <id property="id" column="ID" jdbcType="NUMERIC" javaType="java.lang.Long"/>  
        <result property="loginName" column="LOGIN_NAME" jdbcType="VARCHAR" javaType="java.lang.String"/>  
        <result property="password" column="password" jdbcType="VARCHAR" javaType="java.lang.String"/>  
        <result property="roleId" column="role_id" jdbcType="NUMERIC" javaType="java.lang.Long"/>  
        <association property="role" column="role_id" javaType="Role" resultMap="roleResultMap"/>  
            <id property="id" column="role_id"/>  
            <result property="name" column="role_name"/>  
        </association>  
    </resultMap>  
      
    <resultMap id="roleResultMap" type="Role">  
        <id property="id" column="role_id"/>  
        <result property="name" column="role_name"/>  
    </resultMap>

    也可以这样配置

    Xml代码  
        <resultMap  id="userResultMap" type="User">  
            <id property="id" column="ID" jdbcType="NUMERIC" javaType="java.lang.Long"/>  
            <result property="loginName" column="LOGIN_NAME" jdbcType="VARCHAR" javaType="java.lang.String"/>  
            <result property="password" column="password" jdbcType="VARCHAR" javaType="java.lang.String"/>  
            <result property="roleId" column="role_id" jdbcType="NUMERIC" javaType="java.lang.Long"/>  
            <association property="role" column="role_id" javaType="Role" resultMap="roleResultMap"/>  
        </resultMap>  
          
        <resultMap id="roleResultMap" type="Role">  
            <id property="id" column="role_id"/>  
            <result property="name" column="role_name"/>  
        </resultMap>  

     resultMap这是结果映射的ID,可以映射关联的嵌套结果到一个合适的对象图中。这是一种替代方法来调用另外一个查询语句。这允许你联合多个表来合成到一个单独的结果集。这样的结果集可能包含重复,数据的重复组需要被分解,合理映射到一个嵌套的对象图。为了使它变得容易,MyBatis让你“链接”结果映射,来处理嵌套结果。一个例子会很容易来仿照,这个表格后面也有一个示例。

    注意这个联合查询,以及采取保护来确保所有结果被唯一而且清晰的名字来重命名。

    columnPrefix 属性

    Xml代码  
        <association property="role" column="role_id" javaType="Role" resultMap="roleResultMap" columnPrefix="role_"/>  
                <id property="id" column="id"/>  
                <result property="name" column="name"/>  
        </association>  

    非常重要:在嵌套据诶过映射中id元素扮演了非常重要的角色。应应该通常指定一个或多个属性,它们可以用来唯一标识结果。实际上就是如果你离开她了,但是有一个严重的性能问题时MyBatis仍然可以工作。选择的属性越少越好,它们可以唯一地标识结果。主键就是一个显而易见的选择(尽管是联合主键)。

    上面你已经看到了如何处理“有一个”类型关联。但是“有很多个”是怎样的?下面这个部分就是来讨论这个主题的。

    collection

    collection关联元素处理一对多关联。

    Xml代码 
        <resultMap  id="roleResultMap" type="Role">  
            <id property="id" column="ID" jdbcType="NUMERIC" javaType="java.lang.Long"/>  
            <result property="name" column="NAME" jdbcType="VARCHAR" javaType="java.lang.String"/>  
            <result property="userId" column="user_id" jdbcType="NUMERIC" javaType="java.lang.Long"/>  
            <collection property="user" column="user_id" javaType="ArrayList" ofType="Post" select="selectUser"/>  
          
        </resultMap>  
          
        <select id="selectUser" parameterType="java.lang.Long"   resultType="User" >     
            select * from uer where id =#{id}   
        </select>   

    同样,可以这样配置

    Xml代码  
        <resultMap  id="roleResultMap" type="Role">  
            <id property="id" column="ID" jdbcType="NUMERIC" javaType="java.lang.Long"/>  
            <result property="name" column="NAME" jdbcType="VARCHAR" javaType="java.lang.String"/>  
            <result property="userId" column="user_id" jdbcType="NUMERIC" javaType="java.lang.Long"/>  
            <collection property="user" column="user_id" javaType="ArrayList" ofType="Post">  
                <id property="id" column="user_id"/>  
                <result property="name" column="user_name"/>  
            </collection>  
        </resultMap>  
        <resultMap id="userResultMap" type="User">  
            <id property="id" column="user_id"/>  
            <result property="name" column="user_name"/>  
        </resultMap>  

    原文:http://zhuyuehua.iteye.com/blog/1721715

  • 相关阅读:
    jekins构建自动化项目的步骤
    CRT 和mysql 中文乱码解决方式
    Jenkins的配置(rpm red hat方式)
    MapReduce job.setNumReduceTasks(0)思考
    浏览器angent分析工具
    npm中的 --save-dev
    computed与methods的异同
    JS函数种类详解
    Vue.js和Nodejs的关系
    AJAX复习笔记
  • 原文地址:https://www.cnblogs.com/garfieldcgf/p/8324911.html
Copyright © 2020-2023  润新知