Mybatis使用之查询详解

Mybatis使用之查询详解

 

一:简介

 

        此篇主要知识点:

       1、sql语句块

       2、select标签属性

       3、ResultMap 标签配置

       4、一对一关联

       5、一对多关联

       6、多对多关联

       7、嵌套查询

 

二:SQL语句块

 

       2.1 作用

 

              SQL元素可以被用来定义可重用的SQL 代码段,可以包含在其他语句中。比如在项目中常常做的分页查询、分别需要两条SQL语句、一条是查询所有具体记录信息、另一条需要查询记录数、而两条语句的where条件是一样的。这种类似情况就可以使用SQL语句块来简化配置信息。

 

       2.2 实例


              2.2.1 SQL语句定义:

      

    <sql id="queryColumns"> id, username, password </sql>

              2.2.2 使用:

 

    <select id="queryAuthor" parameterType="int" resultType="author">
        SELECT
        <include refid="queryColumns"/>
        FROM author
        WHERE id = #{id}
    </select>

三:select标签属性

 

       3.1 标签属性集合:

<select

 id="selectPerson"

 parameterType="int"

 parameterMap="deprecated"

 resultType="hashmap"

 resultMap="personResultMap"

 flushCache="false"

 useCache="true"

 timeout="10000"

 fetchSize="256"

 statementType="PREPARED"

 resultSetType="FORWARD_ONLY">

       3.2具体意义:

 

              参见补充部分。

 

四:ResultMap 标签配置

 

       4.1 介绍

 

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

 

       4.2 ResultMap 与ResultType的区别

 

              MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap。resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用但是resultType跟resultMap不能同时存在。

在MyBatis进行查询映射的时候,其实查询出来的每一个属性都是放在一个对应的Map里面的,其中键是属性名,值则是其对应的值。当提供的返回类型属性是resultType的时候,MyBatis会将Map里面的键值对取出赋给resultType所指定的对象对应的属性。

所以其实MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候,MyBatis对自动的给我们把对应的值赋给resultType所指定对象的属性,而当我们提供的返回类型是resultMap的时候,Mybatis就会根据我们配置的信息做映射

 

       4.3 标签属性

   <resultMap id="resultMapId"

               type="JavaBean"

               autoMapping="false"

               extends=""/>

       4.4 标签体

 

              ResultMap的主要组成部分、并且标签体之间可以相互嵌套、来表示更复杂的JavaBean。具体的使用到对应的标签体再说明其作用与标签属性的配置及意义。

              下面是其标签体签名:

        <constructor>
            <idArg/>
            <arg/>
        </constructor>
        <id property="" column="" javaType="" jdbcType="" typeHandler=""/>
        <result typeHandler="" jdbcType="" javaType="" column="" property=""/>
        <association property=""/>
        <collection property=""/>
        <discriminator javaType="">
            <case value=""/>
        </discriminator>


五:简单对象select映射

 

        5.1 ResultType类型返回值的表示方式:

            

             因为在前面提到过、加载Mybatis总配置文件的时候会自动扫描指定包下面的类、并且用类名首字母小写作为名称作为其别名(TypeAliases)、这样我们就不必在select的resultType指定JavaBean的全限定名称了。select语句如下即可:

    <select id="getAllAuthors" resultType="author">
        SELECT
            t.id,
            t.username,
            t.password,
            t.email,
            t.bio,
            t.favourite_section favouriteSection
        FROM author t
    </select>


        5.2 ResultMap类型返回值的表示方式:

             

              5.2.1 配置ResultMap

    <resultMap id="author" type="author">
        <id property="id" column="author_id"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <result property="email" column="email"/>
        <result property="bio" column="bio"/>
        <result property="favouriteSection" column="favouriteSection"/>
    </resultMap>

              5.2.2 将select标签的ResultMap属性值设置为上面ResultMap标签的id、达到映射效果

    <select id="getAllAuthors" resultMap="author">
        SELECT
            t.id,
            t.username,
            t.password,
            t.email,
            t.bio,
            t.favourite_section favouriteSection
        FROM author t
    </select>

              5.2.3 当前ResultMap中 id result子表签作用及属性意义


             


六:一对一关联

      

      6.1 一对一场景

 

       以Blog为例、从《Mybatis使用之环境搭建》中知道Blog与Author是一对一关系、这里是在Blog中关联了Author信息。其他的先不管。如何查询Blog信息、要求是除基本信息外还包含作者完整信息

 

       6.1.1 ResultMap配置一:

 

    <resultMap id="oneToOneBlog" type="blog">
        <id property="id" column="blog_id"/>
        <result property="title" column="title"/>
        <!-- 可以使用resultMap属性指向其他映射文件已经定义好的resultMap -->
        <association property="author" resultMap="org.alien.mybatis.samples.mapper.AuthorMapper.author"/>
    </resultMap>

       6.1.2 ResultMap配置二:

 

    <resultMap id="oneToOneBlog" type="blog">
        <id property="id" column="blog_id"/>
        <result property="title" column="title"/>
        <!-- 也可以在此内部定义指向Author类的映射、此种定义不能重用 -->
        <association property="author" javaType="author">
            <id property="id" column="author_id"/>
            <result property="username" column="username"/>
            <result property="password" column="password"/>
            <result property="email" column="email"/>
            <result property="bio" column="bio"/>
            <result property="favouriteSection" column="favouriteSection"/>
        </association>
    </resultMap>

       6.1.3查询语句:

 

    <select id="getBlogOneToOne" resultMap="oneToOneBlog">
        SELECT
            t1.id                blog_id,
            t1.title,
            t2.id                author_id,
            t2.username,
            t2.password,
            t2.email,
            t2.bio,
            t2.favourite_section favouriteSection
        FROM blog t1, author t2
        WHERE t1.author_id = t2.id
    </select>

       6.1.4 association标签属性以及标签体

            属性:

      


七:一对多关联

      

      7.1 一对多场景

 

       以Blog为例、从《Mybatis使用之环境搭建》中知道Blog与Post是一对多关系、这里是在Blog中有一个集合存放类型为Post的List。


       7.1.1 ResultMap配置一:

    <resultMap id="oneToMany" type="blog">
        <id property="id" column="blog_id" javaType="int"/>
        <result property="title" column="title" javaType="string"/>
        <collection property="posts" ofType="post">
            <id property="id" column="post_id"/>
            <result property="section" column="section"/>
        </collection>
    </resultMap>

       7.1.2 ResultMap配置二:

    <resultMap id="oneToManyResultMap" type="blog">
        <id property="id" column="blog_id" javaType="int"/>
        <result property="title" column="title" javaType="string"/>
        <collection property="posts" ofType="post" resultMap="org.alien.mybatis.samples.mapper.PostMapper.post"/>
    </resultMap>

       7.1.3查询语句:

    <!--<select id="getBlogWithPosts" resultMap="oneToMany">-->
    <select id="getBlogWithPosts" resultMap="oneToManyResultMap">
        SELECT
            t1.id blog_id,
            t1.title,
            t2.id post_id,
            t2.section
        FROM blog t1 LEFT OUTER JOIN post t2 ON t1.id = t2.blog_id WHERE t1.id = 1
    </select>
      
      7.1.4 collection标签属性:

       “ofType”属性。这个属性用来区分JavaBean(或字段)属性类型和集合包含的类型(类型明确下也可以省略)。比如:


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

读作: “在 Post 类型的 ArrayList 中的 posts 的集合。”

javaType 属性是不需要的,因为 MyBatis 在很多情况下会为你算出来。所以你可以缩短 写法:

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

八:多对多关联


        多对多关联可以简化为单方面一对多关联。可以参见一对多关联的方式实现。


九:嵌套关联

      9.1 一对多场景

 

       以Blog为例、从《Mybatis使用之环境搭建》中知道Blog与Post是一对多关系、Post与PostComment(文章评论)Tag(文章标签)是一对多、当在查询Blog属性时、关联的Post属性一并查出来、同时PostComment和Tag属性关联出来。



       9.1.1 ResultMap配置:

    <resultMap id="oneToManyNested" type="blog">
        <id property="id" column="blog_id" javaType="int"/>
        <result property="title" column="title" javaType="string"/>
        <collection property="posts" ofType="post">
            <id property="id" column="post_id"/>
            <result property="section" column="section"/>
            <collection property="comments" resultMap="org.alien.mybatis.samples.mapper.PostCommentMapper.postComment"/>
            <collection property="tags" ofType="tag">
                <id property="id" column="tag_id"/>
                <result property="name" column="tag_name"/>
            </collection>
        </collection>
    </resultMap>

       9.1.2 查询语句:

    <select id="getBlogWithPostsNested" resultMap="oneToManyNested">
        SELECT
            t1.id           blog_id,
            t1.title,
            t2.id           post_id,
            t2.section,
            t3.id           post_comment_id,
            t3.name         post_comment_name,
            t3.comment_text post_comment_text,
            t5.id           tag_id,
            t5.name         tag_name
        FROM blog t1 LEFT OUTER JOIN post t2 ON t1.id = t2.blog_id
            LEFT OUTER JOIN post_comment t3 ON t2.id = t3.post_id
            LEFT OUTER JOIN post_tag t4 ON t2.id = t4.post_id
            LEFT OUTER JOIN tag t5 ON t4.tag_id = t5.id WHERE t1.id = 1
    </select>

十:缓存


       MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis 3中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。

默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环依赖也是必须的。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:

<cache/>

字面上看就是这样。这个简单语句的效果如下:

  • 映射语句文件中的所有 select 语句将会被缓存。
  • 映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。
  • 缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。
  • 根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序 来刷新。
  • 缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
  • 缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

所有的这些属性都可以通过缓存元素的属性来修改。比如:

<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>

这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会导致冲突。

可用的收回策略有:

  • LRU – 最近最少使用的:移除最长时间不被使用的对象。
  • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
  • SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
  • WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

默认的是 LRU。

flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。

size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是 1024。

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

这里暂时没有自定义缓存、后面会有专门关于缓存的记录。




补充:

 

        更多内容:Mybatis 目录

        github地址:https://github.com/andyChenHuaYing/scattered-items/tree/master/items-mybatis

        源码下载地址:http://download.csdn.net/detail/chenghuaying/8713311


       select标签属性对应意义:

      

 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis 分页插件可以帮助我们在使用 MyBatis 进行分页查询时,更加方便地编写分页查询语句。下面是 MyBatis 分页插件的详细介绍以及使用方法。 ## 什么是 MyBatis 分页插件? MyBatis 分页插件是一个用于简化 MyBatis 分页查询的工具,它可以自动拦截分页查询语句,并根据传入的分页参数进行分页处理,最终返回分页结果。 MyBatis 分页插件支持多种数据库,包括 MySQL、Oracle、SQL Server 等。同时,它还提供了丰富的配置选项,可以让我们根据实际需求进行灵活配置。 ## 如何使用 MyBatis 分页插件? 使用 MyBatis 分页插件需要进行以下几个步骤: 1. 引入 MyBatis 分页插件的依赖 可以使用 Maven 或 Gradle 等工具,将 MyBatis 分页插件的依赖添加到项目中。以 Maven 为例,需要添加以下依赖: ```xml <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.11</version> </dependency> ``` 2. 配置 MyBatis 分页插件 在 MyBatis 的配置文件中,需要配置 MyBatis 分页插件。以下是一个示例配置: ```xml <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <property name="helperDialect" value="mysql"/> <property name="reasonable" value="true"/> <property name="supportMethodsArguments" value="true"/> <property name="params" value="count=countSql"/> </plugin> </plugins> ``` 其中,`interceptor` 指定了使用的插件类,`helperDialect` 指定了数据库类型,`reasonable` 指定了是否开启合理化查询,`supportMethodsArguments` 指定了是否支持方法参数作为分页参数,`params` 指定了参数映射规则。 3. 在 Mapper 中编写分页查询语句 在 Mapper 中编写分页查询语句时,需要使用 MyBatis 分页插件提供的分页参数。以下是一个示例: ```xml <select id="getUsers" resultMap="userResultMap"> select * from users <where> <if test="name != null and name != ''"> and name like concat('%', #{name}, '%') </if> </where> order by id <if test="pageSize != null and pageNum != null"> limit #{pageSize} offset #{pageSize * (pageNum - 1)} </if> </select> ``` 其中,`pageSize` 和 `pageNum` 分别表示每页大小和当前页码。 4. 调用分页查询方法 最后,在 Service 中调用分页查询方法时,需要传入分页参数。以下是一个示例: ```java PageHelper.startPage(pageNum, pageSize); List<User> userList = userMapper.getUsers(name); PageInfo<User> pageInfo = new PageInfo<>(userList); ``` 其中,`PageHelper.startPage()` 方法用于启动分页查询,`PageInfo` 用于封装分页结果。 ## 总结 MyBatis 分页插件是一个非常实用的工具,可以大大简化 MyBatis 分页查询的编写和调用过程。在使用 MyBatis 进行分页查询时,推荐使用 MyBatis 分页插件。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值