Spring Boot (11) mybatis 关联映射
一对多
查询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 关联映射的更多相关文章
- spring boot(9)-mybatis关联映射
一对多 查询type表的某一条数据,并且要同时查出所有typeid与之配置的user,最终要得到一个以下类型的Type对象 public class Type { String id; String ...
- 【spring boot】14.spring boot集成mybatis,注解方式OR映射文件方式AND pagehelper分页插件【Mybatis】pagehelper分页插件分页查询无效解决方法
spring boot集成mybatis,集成使用mybatis拖沓了好久,今天终于可以补起来了. 本篇源码中,同时使用了Spring data JPA 和 Mybatis两种方式. 在使用的过程中一 ...
- Spring Boot整合Mybatis完成级联一对多CRUD操作
在关系型数据库中,随处可见表之间的连接,对级联的表进行增删改查也是程序员必备的基础技能.关于Spring Boot整合Mybatis在之前已经详细写过,不熟悉的可以回顾Spring Boot整合Myb ...
- Spring Boot 整合 Mybatis 实现 Druid 多数据源详解
摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “清醒时做事,糊涂时跑步,大怒时睡觉,独处时思考” 本文提纲一.多数据源的应用场景二.运行 sp ...
- Spring Boot整合Mybatis并完成CRUD操作
MyBatis 是一款优秀的持久层框架,被各大互联网公司使用,本文使用Spring Boot整合Mybatis,并完成CRUD操作. 为什么要使用Mybatis?我们需要掌握Mybatis吗? 说的官 ...
- 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 ...
- Spring Boot集成MyBatis开发Web项目
1.Maven构建Spring Boot 创建Maven Web工程,引入spring-boot-starter-parent依赖 <project xmlns="http://mav ...
- 详解Spring Boot集成MyBatis的开发流程
MyBatis是支持定制化SQL.存储过程以及高级映射的优秀的持久层框架,避免了几乎所有的JDBC代码和手动设置参数以及获取结果集. spring Boot是能支持快速创建Spring应用的Java框 ...
- spring boot配置mybatis和事务管理
spring boot配置mybatis和事务管理 一.spring boot与mybatis的配置 1.首先,spring boot 配置mybatis需要的全部依赖如下: <!-- Spri ...
随机推荐
- Django - 一对多跨表操作
1.views.py 2.host.html 运行结果: 通过外键,来进行多表取值(多表取值包括后台取值及前端获取): 多表获取数据时,可以通过以下几种方式实现: 1.从query set 中获取某 ...
- zoj 3314 CAPTCHA(纯模拟)
题目 有些人用深搜写的,当然我这弱弱的,只理解纯模拟... 纯模拟,第一次写了那么长的代码,我自己也是够坚韧不拔的,,,,必须留念啊!!! 注意,G包含C,E包含L,R包含P,(照图说O应该不包含C, ...
- 前端开发神器之chrome 综述
作为前端工程师,也许你对chrome开发工具不陌生,但也谈不上对各个模块有深入了解. 本文主要是为chrome开发工具使用这个系列做个开篇. 参考资料: 谷歌开发者: https://develope ...
- 【Codeforces 1106E】Lunar New Year and Red Envelopes
[链接] 我是链接,点我呀:) [题意] 给你k个红包,每个红包可以在si..ti的时间范围内拿走. 抢完红包之后你得到wi元,然后你需要在di+1时刻才能继续抢红包 时间是线性的从1..n 然后某个 ...
- 【BestCoder Round #93 1001】MG loves gold
[题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=6019 [题意] 每次选择一段连续的段,使得这一段里面没有重复的元素; 问你最少选多少次; [题解] ...
- 树网的核(codevs 1167)
题目描述 Description [问题描述]设 T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T 为树网(treenetwork),其中V, E分别表 ...
- 用keil编写的 C51错误 *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL SYMBOL: ?C_START
可能原因: 替换工程的文件未先 remove该文件. 正常替换文件步骤: 1. 右键 欲 替换的文件,remove XXXXX.c from build ----> remove XXXX ...
- CODEVS——T 2969 角谷猜想
http://codevs.cn/problem/2969/ 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Descri ...
- Python基础操作-集合
在Python set是基本数据类型的一种集合类型,它有可变集合(set())和不可变集合(frozenset)两种.创建集合set.集合set添加.集合删除.交集.并集.差集的操作都是非常实用的方法 ...
- NLS_NCHAR_CHARACTERSET 和 NLS_CHARACTERSET
SQL> select * from nls_database_parameters; PARAMETER VALUE ------------------------------------- ...