Mybatis关联查询

来源:互联网 发布:杭州软件外包公司 编辑:程序博客网 时间:2024/05/16 11:44

三张表:user article blog

配置文件Configuration.xml
复制代码
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>    <!-- mybatis别名定义 -->    <typeAliases>         <typeAlias alias="User" type="com.mybatis.test.User"/>         <typeAlias alias="Article" type="com.mybatis.test.Article"/>         <typeAlias alias="Blog" type="com.mybatis.test.Blog"/>    </typeAliases>     <environments default="development">        <environment id="development">        <transactionManager type="JDBC"/>            <dataSource type="POOLED">            <property name="driver" value="com.mysql.jdbc.Driver"/>            <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis" />            <property name="username" value="root"/>            <property name="password" value="admin"/>            </dataSource>        </environment>    </environments>        <!-- mybatis的mapper文件,每个xml配置文件对应一个接口 -->    <mappers>        <mapper resource="com/mybatis/test/User.xml"/>        <mapper resource="com/mybatis/test/Article.xml"/>        <mapper resource="com/mybatis/test/Blog.xml"/>    </mappers></configuration>
复制代码


Article.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.mybatis.test.IArticleOperation">    <resultMap type="User" id="userResultMap">        <!-- 属性名和数据库列名映射 -->        <id property="id" column="user_id"  />        <result property="userName" column="user_userName"  />        <result property="userAge" column="user_userAge"  />        <result property="userAddress" column="user_userAddress"  />    </resultMap>        <!-- User join Article进行联合查询  (一对一)-->        <resultMap id="articleResultMap" type="Article">        <id property="id" column="article_id" />        <result property="title" column="article_title" />        <result property="content" column="article_content" />        <!-- 将article的user属性映射到userResultMap -->        <association property="user" javaType="User" resultMap="userResultMap"/>      </resultMap>        <!-- 使用别名来映射匹配 -->    <select id="getUserArticles" parameterType="int" resultMap="articleResultMap">       select user.id user_id,user.userName user_userName,user.userAddress user_userAddress,       article.id article_id,article.title article_title,article.content article_content        from user,article        where user.id=article.userid and user.id=#{id}    </select>        <!-- 另一种联合查询  (一对一)的实现,但是这种方式有“N+1”的问题 -->   <!--  <resultMap id="articleResultMap" type="Article">        <id property="id" column="article_id" />        <result property="title" column="article_title" />        <result property="content" column="article_content" />        <association property="user" javaType="User" column="userid" select="selectUser"/>      </resultMap>        <select id="selectUser" parameterType="int" resultType="User">        select * from user where id = #{id}    </select> -->    </mapper>
复制代码

Blog类中有一个List<Article>。

Blog.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.mybatis.test.IBlogOperation">    <resultMap id="userResultMap" type="User">        <id property="id" column="user_id"  />        <result property="userName" column="user_userName"  />        <result property="userAge" column="user_userAge"  />        <result property="userAddress" column="user_userAddress"  />    </resultMap>        <resultMap id="articleResultMap" type="Article">        <id property="id" column="article_id" />        <result property="title" column="article_title" />        <result property="content" column="article_content" />        <association property="user" javaType="User" resultMap="userResultMap"/>      </resultMap>        <resultMap id="blogResultMap" type="Blog">        <id property="id" column="blog_id" />        <result property="title" column="blog_title" />        <!-- 将article list属性映射到collection -->        <collection property="articles" ofType="Article" resultMap="articleResultMap"/>    </resultMap>        <!-- select语句 -->    <select id="getBlogByID" parameterType="int" resultMap="blogResultMap">       select user.id user_id,user.userName user_userName,user.userAddress user_userAddress,       article.id article_id,article.title article_title,article.content article_content,        blog.id blog_id, blog.title blog_title       from user,article,blog        where user.id=article.userid and blog.id=article.blogid and blog.id=#{id}    </select>    </mapper>
复制代码

IArticleOperation定义:

复制代码
package com.mybatis.test;import java.util.List;public interface IArticleOperation {    public List<Article> getUserArticles(int userID);}
复制代码

IBlogOperation定义:

复制代码
package com.mybatis.test;public interface IBlogOperation {        Blog getBlogByID(int id);    }
复制代码

Mybatis的“N+1查询问题”

示例:

复制代码
    <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>
复制代码

有两个查询语句:一个来加载博客,另外一个来加载作者,而且博客的结果映射描述了“selectAuthor”语句应该被用来加载它的 author 属性。

其他所有的属性将会被自动加载,假设它们的列和属性名相匹配。

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

你执行了一个单独的 SQL 语句来获取结果列表(就是“+1”)。

对返回的每条记录,你执行了一个查询语句来为每个加载细节(就是“N”)。

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

可以采用关联的嵌套结果来解决这个问题:

复制代码
    <resultMap id="blogResult" type="Blog">        <id property=”id” column="blog_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>
复制代码

resultMap 这是结果映射的 ID,可以映射关联的嵌套结果到一个合适的对象图中。这是一种替代方法来调用另外一个查询语句。

1 0