一对多

  查询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. (1)搜索广告CTR预估

    https://www.cnblogs.com/futurehau/p/6181008.html 一.广告投放系统 广告系统包含多个子系统.除了上图所示的广告投放系统外,还包含商业系统(广告库的获得) ...

  2. java 导入导出的 命令

    $exp lddba/ld_321@192.168.1.3/testora file=E:\db_bak\ld20170219_1testora.dmp log=E:\db_bak\ld2017021 ...

  3. 安装RHEL7红帽操作系统

    1.单击“开启此虚拟机”启动RHEL 7系统安装. 开启虚拟机 2.通过键盘方向键选择Install Red Hat Enterprise Linux 7.0选项,然后回车,开始安装RHEL7操作系统 ...

  4. 第十五节:pandas之concat()级联

    Pandas 提供了concat()函数可以轻松的将Series.DataFrame对象进行合并在一起. pandas.concat(obj , axis=0 , join="inner&q ...

  5. The Morning after Halloween uva1601

    这道题思路还是比较清晰的,建图加bfs或双向bfs,其实后者比前者少了将近一半的时间.. 建图可以把某一点所拥有邻接点长度(数目)记录在数组0这个位置,因为这道题使用vector会超时. #inclu ...

  6. linux学习5-命令执行顺序控制与管道

    一.命令执行顺序控制 1.顺序执行命令——[:] eg:whoami:cd ~:pwd 问题:不适合存在依赖关系的命令 2.有选择的执行命令[&&].[||] [&&] ...

  7. ARC 73 E - Ball Coloring

    E - Ball Coloring Time limit : 2sec / Memory limit : 256MB Score : 700 points Problem Statement Ther ...

  8. B - Oulipo

    The French author Georges Perec (1936�C1982) once wrote a book, La disparition, without the letter ' ...

  9. html简单实现下拉菜单

    主要用到的知识ul和li标签 ul li 是一个组合:是无序列表标签,在实际中用的非常多,与之对应的是有序列表:ol lili是不能单独使用,必须在于ul之中的ul是块级元素,能直接定义宽高,而li是 ...

  10. sql server 学习课件 PPT

    http://www.cnblogs.com/woodytu/p/4465288.html