Mybatis嵌套查询

注:文中字段默认驼峰命名法,例如 authorId --> author_id

List嵌套 :collection

例如,查询文章信息,包含文章tag信息

//Article-Entity结构
@TableName("tb_article")
public class ArticleDTO{
    //id
    private int id;
    //标题
    private String title;
}

//Article-DTO结构
public class ArticleDTO{
    //id
    private int id;
    //标题
    private String title;
    //标签list
    private List<TagDTO> tagList;
}

//Tag-Entity结构
@TableName("tb_tag")
public class Tag{
    //id
    private int id;
    //article id
    private int articleId;
    //标签名
    private String name;
}

//Tag-DTO结构
public class TagDTO{
    //id
    private int id;
    //article id
    private int articleId;
    //标签名
    private String name;
}

Java

我们查询Article的时候,需要返回的ArticleDTO中包含tagList信息,即嵌套List

  • ArticleDao.java
//ArticleDao.java
@Repository
public interface ArticleDao extends BaseMapper<Article> {
    /**
     * 查询文章
     *
     * @param articleId id
     * @return 查询文章
     */
    ArticleDTO getArticleDTO(@Param("articleId") String articleId);

    /**
     * 获取文章列表
     *
     * @param current 当前页
     * @param size    页面尺寸
     * @return 获取文章列表
     */
    List<ArticleDTO> listArticlesDTO(@Param("current") Long current, @Param("size")Long size);
}
java
  • ArticleDao.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.xyjiayi.dto.ArticleDao">

    <resultMap id="ArticleDTO" type="com.xyjiayi.dto.ArticleDTO">
       <result property="id" column="id"/>
       <collection property="tagList" ofType="com.xyjiayi.dto.TagDTO" select="selectTag" column="id"/>
    </resultMap>

    <select id="selectTag" resultType="com.xyjiayi.dto.TagDTO">
        SELECT * FROM tb_tag WHERE `article_id` = #{id}
    </select>

    <select id="getArticleDTO" resultType="com.xyjiayi.dto.ArticleDTO">
        SELECT * FROM tb_article WHERE `id` = #{articleId}
    </select>

    <select id="listArticlesDTO" resultMap="ArticleDTO">
        SELECT * FROM tb_article LIMIT #{current},#{size}
    </select>

</mapper>

xml

查询结果:

{
  "id":"150",
  "title":"Mybatis嵌套查询",
  "tagList":[
    {
      "id":"1",
      "name":"Mybatis",
      "articleId":"150"
    },{
      "id":"3",
      "name":"SQL",
      "articleId":"150"
    },{
      "id":"5",
      "name":"Java",
      "articleId":"150"
    },{
      "id":"6",
      "name":"查询",
      "articleId":"150"
    }
  ]
}
json

注意:实践中,xml中的<result property="id" column="id"/>行如果缺少,猜测是由于字段冲突,会导致返回的Article.id为null,因此需要保留。

对象嵌套 :association

例如:查询文章信息,包含文章作者信息

//Article-Entity结构(数据库中结构)
@TableName("tb_article")
public class Article{
    //id
    private int id;
    //标题
    private String title;
    //标题
    private String authorId;
}

//Article-DTO结构
public class ArticleDTO{
    //id
    private int id;
    //标题
    private String title;
    //Author id
    private String authorId;
    //作者Author
    private AuthorDTO authorInfo;
}

//Author-Entity结构
@TableName("tb_author")
public class Author{
    //id
    private int id;
    //Author姓名
    private String name;
    //Author昵称
    private String nickName;
    //Author头像
    private String avatar;
}

//Author-DTO结构
public class AuthorDTO{
    //id
    private int id;
    //Author姓名
    private String name;
    //Author昵称
    private String nickName;
    //Author头像
    private String avatar;
}

Java

我们查询Article的时候,需要返回的ArticleDTO中包含Author信息,即嵌套对象。

  • ArticleDao.java
//ArticleDao.java
@Repository
public interface ArticleDao extends BaseMapper<Article> {
    /**
     * 查询文章
     *
     * @param articleId id
     * @return 查询文章
     */
    ArticleDTO getArticleDTO(@Param("articleId") String articleId);

    /**
     * 获取文章列表
     *
     * @param current 当前页
     * @param size    页面尺寸
     * @return 获取文章列表
     */
    List<ArticleDTO> listArticlesDTO(@Param("current") Long current, @Param("size")Long size);
}
java
  • ArticleDao.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.xyjiayi.dto.ArticleDao">

    <resultMap id="ArticleDTO" type="com.xyjiayi.dto.ArticleDTO">
       <result property="id" column="id"/>
       <result property="authorId" column="author_id"/>
       <association property="authorInfo" javaType="com.xyjiayi.dto.AuthorDTO" column="author_id" select="selectAuthor"/>
    </resultMap>

    <select id="selectAuthor" resultType="com.xyjiayi.dto.AuthorDTO">
        SELECT * FROM tb_author WHERE `id` = #{author_id}
    </select>

    <select id="getArticleDTO" resultType="com.xyjiayi.dto.ArticleDTO">
        SELECT * FROM tb_article WHERE `id` = #{articleId}
    </select>

    <select id="listArticlesDTO" resultMap="ArticleDTO">
        SELECT * FROM tb_article LIMIT #{current},#{size}
    </select>

</mapper>
xml

查询结果:

{
  "id":"150",
  "title":"Mybatis嵌套查询",
  "authorId":"1",
  "authorInfo":{
    "id":"1",
    "name":"续加仪",
    "age":"18",
    "avatar":"https://files.hyz.cool/files/config/a3723d1857b94601751d31489978efd1.jpg"
  }
}
json

注意:实践中,xml中的<result property="id" column="id"/><result property="authorId" column="author_id"/>行如果缺少,猜测是由于字段冲突,会导致返回的Article.id、authorId为null,因此需要保留。

多层对象嵌套

比如 association 嵌套 association

尝试了直接使用 association 嵌套 association,即:

<association property="authorInfo" javaType="com.xyjiayi.dto.AuthorDTO" column="author_id" select="selectAuthor">
     <association property="categoryInfo" javaType="com.xyjiayi.dto.CategoryDTO" column="category_id" select="selectCategory"/>
 </association>
xml

但是失败了,内部Category始终为null,因此更换了思路,采用’隐藏式’嵌套:

例如:查询文章信息,包含文章作者信息,作者包含用户分类信息

//Article-Entity结构(数据库中结构)
@TableName("tb_article")
public class Article{
    //id
    private int id;
    //标题
    private String title;
    //标题
    private String authorId;
}

//Article-DTO结构
public class ArticleDTO{
    //id
    private int id;
    //标题
    private String title;
    //Author id
    private String authorId;
    //作者Author
    private AuthorDTO authorInfo;
}


//Author-Entity结构
@TableName("tb_author")
public class Author{
    //id
    private int id;
    //Author姓名
    private String name;
    //Author昵称
    private String nickName;
    //Author头像
    private String avatar;
    //用户CategoryId
    private String categoryId;
}

//Author-DTO结构
public class AuthorDTO{
    //id
    private int id;
    //Author姓名
    private String name;
    //Author昵称
    private String nickName;
    //Author头像
    private String avatar;
    //用户CategoryId
    private String categoryId;
    //用户CategoryInfo
    private CategoryDTO categoryInfo;
}

//Category-Entity结构
@TableName("tb_category")
public class Category{
    //id
    private int id;
    //Category名称
    private String name;
    //Category简介
    private String description;
}

//Category-DTO结构
public class CategoryDTO{
    //id
    private int id;
    //Category名称
    private String name;
    //Category简介
    private String description;
}
Java

我们查询Article的时候,需要返回的ArticleDTO中包含Author信息,Author又包含Category信息,即多层嵌套对象。

  • ArticleDao.java
//ArticleDao.java
@Repository
public interface ArticleDao extends BaseMapper<Article> {
    /**
     * 查询文章
     *
     * @param articleId id
     * @return 查询文章
     */
    ArticleDTO getArticleDTO(@Param("articleId") String articleId);

    /**
     * 获取文章列表
     *
     * @param current 当前页
     * @param size    页面尺寸
     * @return 获取文章列表
     */
    List<ArticleDTO> listArticlesDTO(@Param("current") Long current, @Param("size")Long size);
}
java
  • ArticleDao.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.xyjiayi.dto.ArticleDao">

    <resultMap id="AuthorDTO" type="com.xyjiayi.dto.AuthorDTO">
       <result property="id" column="id"/>
       <result property="categoryId" column="category_id"/>
       <association property="categoryInfo" javaType="com.xyjiayi.dto.CategoryDTO" column="category_id" select="selectCategory"/>
    </resultMap>

    <resultMap id="ArticleDTO" type="com.xyjiayi.dto.ArticleDTO">
       <result property="id" column="id"/>
       <result property="authorId" column="author_id"/>
       <association property="authorInfo" javaType="com.xyjiayi.dto.AuthorDTO" column="author_id" select="selectAuthor"/>
    </resultMap>

    <select id="selectCategory" resultType="com.xyjiayi.dto.CategoryDTO">
        SELECT * FROM tb_category WHERE `id` = #{category_id}
    </select>

    <select id="selectAuthor" resultMap="AuthorDTO">
        SELECT * FROM tb_author WHERE `id` = #{author_id}
    </select>

    <select id="getArticleDTO" resultType="com.xyjiayi.dto.ArticleDTO">
        SELECT * FROM tb_article WHERE `id` = #{articleId}
    </select>

    <select id="listArticlesDTO" resultMap="ArticleDTO">
        SELECT * FROM tb_article LIMIT #{current},#{size}
    </select>

</mapper>
xml

查询结果:

{
  "id":"150",
  "title":"Mybatis嵌套查询",
  "authorId":"1",
  "authorInfo":{
    "id":"1",
    "name":"续加仪",
    "age":"18",
    "avatar":"https://files.hyz.cool/files/config/a3723d1857b94601751d31489978efd1.jpg",
    "categoryId":"2",
    "categoryInfo":{
      "id":"2",
      "name":"Super Man",
      "description":"A World Of Super Men."
    }
  }
}
json

注意:如果select标签返回的是Java类,属性用resultType,值为类包名+类名,如果是本地定义的resultMap,属性用resultMap,值为resultMapid

更多信息可以参考【mybatis教程】

微信原创文章

2022-09.29 ​Arduino控制oled屏幕显示自定义字体文字

2022-09.26 ​661. 图片平滑器

2022-08-13 ​Arduino使用红外遥控控制8×8点阵显示

2022-08-12 Arduino使用蓝牙控制8×8点阵显示

打赏
  • 微信
  • 支付宝
评论
来发评论吧~
···

歌手: