一对多

  查询category中的某一条数据,同时查询该分类下的所有Product。

Category.java

public class Category {
private Integer id;
private String name;
private List<Product> product;
....

product.java

public class Product {
private Integer id;
private String name;
private String price;
private Integer categoryId;
...

dao层

@Mapper
public interface MyBatisDao { @Select("select * from product where categoryId = #{categoryId}")
List<Product> findProductByCategoryId(Integer categoryId); @Results({
@Result(property = "id" , column = "id"),
//products映射<List> Product,many=@Many是调用关联的方法,"id"是关联的条件, FetchType.LAZY是延迟加载
@Result(property = "products", column = "id", many=@Many(select = "com.david.dao.MyBatisDao.findProductByCategoryId",fetchType = FetchType.LAZY))
})
@Select("select * from category where id = #{id}")
Category findCategoryById(Integer id); }

service层

@Service
@Transactional
public class MyBatisService { @Resource
private MyBatisDao myBatisDao; public Category findCategoryById(){
Category category = myBatisDao.findCategoryById(1);return category;
} }

测试:

一对一:把上面的@many=@Many换成one=@One即可

  修改Product.java 增加属性

public class Product {
private Integer id;
private String name;
private String price;
private Integer categoryId;
private Category category;

  dao

    @Results({
@Result(property = "id", column = "id"),
@Result(property = "category", column = "categoryId",one=@One(select = "com.david.dao.MyBatisDao.findCategoryById",fetchType = FetchType.LAZY))
})
@Select("select * from Product where id = #{id}")
Product findProductCategoryById(Integer id);

多对多:把多个字段映射成many=@Many即可

多对一:把上面dao方法的返回值从Category改成List<Category>

JAVA注解的局限性

返回多条Category

    @Results({
@Result(property = "id" , column = "id"),
//products映射<List> Product,many=@Many是调用关联的方法,"id"是关联的条件, FetchType.LAZY是延迟加载
@Result(property = "products", column = "id", many=@Many(select = "com.david.dao.MyBatisDao.findProductByCategoryId",fetchType = FetchType.LAZY))
})
@Select("select * from category")
List<Category> findAllCategory();

  category现在有三条记录,我要查出所有category及其对应的product,最终得到一个List<Category> 查询过程是这样的:

一共执行了四次查询,一次查category表,因为有三条记录,所以查了三次product表,以此来填充三个List<Product> products属性。如果category中又几百条数据,而且还有上十个表进行关联查询,结果无法想象。在传统的xml配置中,是可以用一条sql语句查出来的,不过mybatis官方做出了一个说明,由于java注解的局限性,不支持那种映射方式。所以,如果只想用一条sql语句查出关联映射,必须借助xml。

xml无限层嵌套映射

  这里以三层嵌套为例,实现前端的三级菜单树。这是一个tree表,pid是其上级菜单的id。

要得到查询结果Tree对象,这个对象是可以无限递归的

public class TreeMenu {
private Integer Id;
private String MenuName;
private List<TreeMenu> child;

dao

@Mapper
public interface TreeMenuDao {
@ResultMap("treeMenu")
@Select("select p1.id,p1.menuName,p2.id id2,p2.menuName menuName2,p3.id id3,p3.menuName menuName3"+
"from treemenu p1, treemenu p2,treemenu p3 where p1.id = p2.pid and p2.id = p3.pid")
List findTreeMenu();
}

这个sql语句在数据库中查询结果是这样的,可以发现前四个字段是一样的,而且都是冗余数据,如果用java注解的关联查询是不会这样的

@ResultMap("treeMenu"):映射结果集id是treeMenu,这个映射要在xml中配置

application.yml中添加配置

mybatis:
mapper-locations: classpath:mapper/*

在resources/mapper/TreeMenuMapper.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">
<!-- 映射dao -->
<mapper namespace="com.david.dao.TreeMenuDao">
<!-- 结果集类型 -->
<resultMap id="treeMenu" type="com.david.bean.TreeMenu">
<!-- 映射字段 -->
<result column="Id" property="Id" />
<result column="MenuName" property="MenuName" />
<!-- 嵌套第二张表 -->
<collection property="child" ofType="com.david.bean.TreeMenu" >
<id column="Id2" property="Id" />
<result column="MenuName2" property="MenuName" />
<!-- 嵌套第三张表 -->
<collection property="child" ofType="com.david.bean.TreeMenu" >
<id column="Id3" property="Id" />
<result column="MenuName3" property="MenuName" />
</collection>
</collection>
</resultMap>
</mapper>

这里只是配置一个嵌套映射,在dao方法中通过@ResultMap("treeMenu")使用这个映射。最终查询结果会映射成一个TreeMenu对象,通过spring mvc转换为json结果如下,在一些前端框架中,实现属性菜单就是需要用这种结构的json数据值。

[
{
"child": [
{
"child": [
{
"child": null,
"id": 4,
"menuName": "三级菜单-1-1"
},
{
"child": null,
"id": 5,
"menuName": "三级菜单-1-2"
}
],
"id": 2,
"menuName": "二级菜单-1"
},
{
"child": [
{
"child": null,
"id": 6,
"menuName": "三级菜单-2-1"
}
],
"id": 3,
"menuName": "二级菜单-2"
}
],
"id": 1,
"menuName": "一级菜单"
}
]

Spring Boot (11) mybatis 关联映射的更多相关文章

  1. spring boot(9)-mybatis关联映射

    一对多 查询type表的某一条数据,并且要同时查出所有typeid与之配置的user,最终要得到一个以下类型的Type对象 public class Type { String id; String ...

  2. 【spring boot】14.spring boot集成mybatis,注解方式OR映射文件方式AND pagehelper分页插件【Mybatis】pagehelper分页插件分页查询无效解决方法

    spring boot集成mybatis,集成使用mybatis拖沓了好久,今天终于可以补起来了. 本篇源码中,同时使用了Spring data JPA 和 Mybatis两种方式. 在使用的过程中一 ...

  3. Spring Boot整合Mybatis完成级联一对多CRUD操作

    在关系型数据库中,随处可见表之间的连接,对级联的表进行增删改查也是程序员必备的基础技能.关于Spring Boot整合Mybatis在之前已经详细写过,不熟悉的可以回顾Spring Boot整合Myb ...

  4. Spring Boot 整合 Mybatis 实现 Druid 多数据源详解

    摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “清醒时做事,糊涂时跑步,大怒时睡觉,独处时思考” 本文提纲一.多数据源的应用场景二.运行 sp ...

  5. Spring Boot整合Mybatis并完成CRUD操作

    MyBatis 是一款优秀的持久层框架,被各大互联网公司使用,本文使用Spring Boot整合Mybatis,并完成CRUD操作. 为什么要使用Mybatis?我们需要掌握Mybatis吗? 说的官 ...

  6. Spring boot教程mybatis访问MySQL的尝试

    Windows 10家庭中文版,Eclipse,Java 1.8,spring boot 2.1.0,mybatis-spring-boot-starter 1.3.2,com.github.page ...

  7. Spring Boot集成MyBatis开发Web项目

    1.Maven构建Spring Boot 创建Maven Web工程,引入spring-boot-starter-parent依赖 <project xmlns="http://mav ...

  8. 详解Spring Boot集成MyBatis的开发流程

    MyBatis是支持定制化SQL.存储过程以及高级映射的优秀的持久层框架,避免了几乎所有的JDBC代码和手动设置参数以及获取结果集. spring Boot是能支持快速创建Spring应用的Java框 ...

  9. spring boot配置mybatis和事务管理

    spring boot配置mybatis和事务管理 一.spring boot与mybatis的配置 1.首先,spring boot 配置mybatis需要的全部依赖如下: <!-- Spri ...

随机推荐

  1. bootstrap table分页(前后端两种方式实现)

    bootstrap table分页的两种方式: 前端分页:一次性从数据库查询所有的数据,在前端进行分页(数据量小的时候或者逻辑处理不复杂的话可以使用前端分页) 服务器分页:每次只查询当前页面加载所需要 ...

  2. pig常用命令

    一.pig: pig提供了一个基于Hadoop的并行地执行数据流处理的引擎.它包含了一种脚本语言,称为Pig Latin.(类似SQL) 二.Pig Latin: 1.注释: 单行:-- 多行:/* ...

  3. php第十八节课

    PDO 对不同的数据库连接使用 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...

  4. 【js】数组置空的其他方式及使用场景

    数组在js中属于引用型类型. var arr = [1, 2, 3]; a = []; 通常使用以上方式.如果使用场景必须使用方法置空, 可以采用arr.length = 0; 或者使用a.splic ...

  5. JAVA学习总结-基础语法

    /** * 这篇文章供自己学习JAVA总结回顾使用 * 主要借鉴了马士兵老师的视频进行总结 * @author Kingram */ 标识符的概念和命名规则 JAVA常量---不可变的变量 程序的执行 ...

  6. Scrapy实战:使用IDE工具运行爬虫

    一般我们运行爬虫程序都是使用命令行,比如:scrapy crwal sobook.不过这多少有些不方便,可以使用下面的方法使用IDE的方式运行爬虫 我这边使用的是pycharm软件,在pycharm里 ...

  7. 34.分组聚合操作—bucket

    主要知识点: 学习聚合知识     一.准备数据     1.家电卖场案例背景建立index 以一个家电卖场中的电视销售数据为背景,来对各种品牌,各种颜色的电视的销量和销售额,进行各种各样角度的分析 ...

  8. 联想小新Air 15 安装黑苹果macOS High Sierra 10.13.6过程

    联想小新Air 15 安装黑苹果全过程 本文参考:https://blog.csdn.net/qq_28735663/article/details/80634300 本人是联想小新AIr 15 , ...

  9. 清北学堂模拟赛d3t1 a

    [问题描述]你是能看到第一题的friends呢.——hja 怎么快速记单词呢?也许把单词分类再记单词是个不错的选择.何大爷给出了一种分单词的方法,何大爷认为两个单词是同一类的当这两个单词的各个字母的个 ...

  10. nyoj_171_聪明的kk_201402281518

    聪明的kk时间限制:1000 ms  |  内存限制:65535 KB 难度:3描述 聪明的“KK”非洲某国展馆的设计灵感源于富有传奇色彩的沙漠中陡然起伏的沙丘,体现出本国不断变换和绚丽多彩的自然风光 ...