SpringBoot中Mybatis注解一对多和多对多查询实现示例

目录
  • 一、模拟的业务查询
  • 二、对应的实体类如下
  • 三、对应的建表语句和模拟数据如下
  • 四、@One一对一映射
  • 五、@Many一对多查询
  • 六、@One @Many的总结

一、模拟的业务查询

系统中的用户user都有唯一对应的地址信息address,每个用户可以有多量车car,类似如下结构

|-- user
    |-- address
    |-- carList
        |-- car1
        |-- car2

二、对应的实体类如下

@Data
public class AddressPO {
    private Long id;
    /**
     * 省份
     */
    private String province;
    /**
     * 城市
     */
    private String city;
    /**
     * 街道
     */
    private String street;
}
@Data
public class CarPO {
    private Long id;
    /**
     * 颜色
     */
    private String color;
    /**
     * 品牌
     */
    private String name;
    private Long userId;
}
@Data
public class UserPO extends AbstractPO {
    private Long id;
    private String username;
    private String password;
    private Integer age;
    private GenderEnum gender;
    /**
     * 地址信息,和用户是一对一的关系
     */
    private AddressPO address;
    /**
     * 地址id
     */
    private Long addressId;
    /**
     * 用户拥有的车,和用户是一对多的关系
     */
    private List<CarPO> cars;
}

三、对应的建表语句和模拟数据如下

CREATE TABLE IF NOT EXISTS `user`
(
    `id`          int(11)     NOT NULL AUTO_INCREMENT COMMENT '主键',
    `username`    varchar(20) NOT NULL UNIQUE COMMENT '用户名',
    `password`    varchar(50) NOT NULL COMMENT '密码',
    `age`         int(2)      NOT NULL COMMENT '年龄',
    `gender`      varchar(10) NOT NULL COMMENT '性别',
    `address_id`  int(11)              DEFAULT NULL COMMENT '地址',
    `creater`     varchar(20)          DEFAULT NULL COMMENT '创建人',
    `modifier`    varchar(20)          DEFAULT NULL COMMENT '更新人',
    `create_time` datetime    NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `modify_time` datetime    NOT NUll DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
    PRIMARY KEY (`id`),
    KEY `index_gender` (`gender`) USING BTREE COMMENT '性别'
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4
  COLLATE = utf8mb4_bin;
CREATE TABLE IF NOT EXISTS `address`
(
    `id`       int(11) NOT NULL AUTO_INCREMENT,
    `province` varchar(50) DEFAULT NULL,
    `city`     varchar(50) DEFAULT NULL,
    `street`   varchar(50) DEFAULT NULL,
    PRIMARY KEY (`id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4
  COLLATE = utf8mb4_bin;
CREATE TABLE IF NOT EXISTS `car`
(
    `id`      int(11) NOT NULL AUTO_INCREMENT,
    `color`   varchar(50) DEFAULT NULL,
    `name`    varchar(50) DEFAULT NULL,
    `user_id` int(11)     DEFAULT NULL,
    PRIMARY KEY (`id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4
  COLLATE = utf8mb4_bin;
INSERT INTO `user`(username, password, age, gender, address_id)
VALUES ('KimZing', '123456', '25', 'MAN', 1), ('kim', '123456', '25', 'MAN', 2);
INSERT INTO `address`
VALUES ('1', '北京', '北京', '王府井'),
       ('2', '天津', '天津', '周良'),
       ('3', '安徽', '宿州', '涌桥'),
       ('4', '广东', '广州', '顺德');
INSERT INTO
    `car`
VALUES
('1', 'green', '路虎', '1'),
('2', 'white', '奔驰', '2'),
('3', 'blue', '玛莎拉蒂', '1'),
('4', 'yellow', '兰博基尼', '2');

四、@One一对一映射

以获取用户的唯一地址为例,首先我们定义一个根据地址id查询地址的查询方法

@Mapper
public interface AddressRepository {
    /**
     * 根据地址id查询地址
     */
    @Select("SELECT * FROM `address` WHERE id = #{id}")
    AddressPO findAddressById(Long id);
}

然后我们定义一个根据用户id查询用户的方法

@Mapper
public interface MySqlUserRepository {
    @Select("SELECT * FROM `user` WHERE id = #{id}")
    UserPO find(Long id);
}

这个时候我们查询出来的user对象中的address属性是空的,和address并没有任何关联。
那么我们要把user中的addressId传递给AddressRepository的查询地址的方法,
然后把查询出的地址对象address赋值给user的address属性,那么我们怎么做呢?

@Mapper
public interface MySqlUserRepository {
    @Select("SELECT * FROM `user` WHERE id = #{id}")
    @Results({
    @Result(property = "address", column = "address_id",
                    one = @One(select = "com.kimzing.data.repository.AddressRepository.findAddressById"))
    })
    UserPO find(Long id);
}

我们要使用@Resutl注解对返回的结果进行配置,

property = “address”

表示要将返回的查询结果赋值给user的address属性

column = “address_id”

是指将user表中的address_id作为com.kimzing.data.repository.AddressRepository.findAddressById的查询参数

one 表示这是一个一对一的查询

@One(select = "方法全路径)

表示我们调用的方法

五、@Many一对多查询

以获取用户拥有的所有车car为例,首先我们定义一个根据用户id查询车的查询方法

@Mapper
public interface CarRepository {
    /**
     * 根据用户id查询所有的车
     */
    @Select("SELECT * FROM `car` WHERE user_id = #{userId}")
    List<Car> findCarsByUserId(Long userId);
}

然后我们定义一个根据用户id查询用户的方法

@Mapper
public interface MySqlUserRepository {
    @Select("SELECT * FROM `user` WHERE id = #{id}")
    UserPO find(Long id);

}

这个时候我们查询出来的user对象中的List属性是空的,和car的查询方法并没有任何关联。
那么我们要把user中的用户id传递给CarRepository的查询车的方法,
然后把查询出的集合对象List赋值给user的cars属性,那么我们怎么做呢?(和获取地址是有些类似的)

package com.kimzing.data.repository.impl;
import com.kimzing.data.domain.po.UserPO;
import org.apache.ibatis.annotations.*;
import java.util.List;
/**
 * 数据存储.
 *
 * @author KimZing - kimzing@163.com
 * @since 2020/1/31 13:12
 */
@Mapper
public interface MySqlUserRepository {
    @Select("SELECT * FROM `user` WHERE id = #{id}")
    @Results({
            @Result(property = "address", column = "address_id",
                    one = @One(select = "com.kimzing.data.repository.AddressRepository.findAddressById")),
            @Result(property = "cars", column = "id",
                    many = @Many(select = "com.kimzing.data.repository.CarRepository.findCarsByUserId"))
    }),
    // 对userId进行赋值
    @Result(property = "id", column = "id")
    UserPO find(Long id);
}

我们要使用@Resutl注解对返回的结果进行配置,

property = “cars”, 表示要将返回的查询结果赋值给user的cars属性

column = “id” 是指将user表中的用户主键id作为com.kimzing.data.repository.CarRepository.findCarsByUserId的查询参数

many 表示这是一个一对多的查询

@Many(select = "方法全路径)

表示我们调用的方法, 方法参数userId就是上面column指定的列值

六、@One @Many的总结

首先我们统一下概念:查询Address或Car的方法,接下来统称为User的附属查询。

共同点:

  • 无论是一对一还是一对多,都是通过附属查询来实现的,我们需要定义这个附属查询方法。
  • 在主查询方法中通过@One、@Many指定附属查询方法的全路径。
  • 都通过column来传递参数给附属方法。

不同点:

一对一,那么附属方法返回的是一个单独的对象

一对多,那么附属方法返回的是一个对象集合

以上就是SpringBoot中Mybatis注解一对多和多对多查询实现示例的详细内容,更多关于SpringBoot Mybatis注解一对多多对多查询的资料请关注我们其它相关文章!

(0)

相关推荐

  • springboot + mybatis-plus实现多表联合查询功能(注解方式)

    第一步:加入mybatis-plus依赖 第二步:配置数据源 spring: thymeleaf: cache: false encoding: utf-8 prefix: classpath:/templates/ suffix: .html enabled: true datasource: url: jdbc:mysql://192.168.1.152:3306/timo?useUnicode=true&characterEncoding=UTF-8&useSSL=false&

  • Spring boot整合Mybatis实现级联一对多CRUD操作的完整步骤

    前言 在关系型数据库中,随处可见表之间的连接,对级联的表进行增删改查也是程序员必备的基础技能.关于Spring Boot整合Mybatis在之前已经详细写过,不熟悉的可以回顾Spring Boot整合Mybatis并完成CRUD操作,这是本文操作的基础.本文先准备一个测试的数据库,然后使用MyBatis Generator进行部分代码自动生成,再以一个例子来展示稍微高级点的操作:使用Mybatis完成级联一对多的CRUD操作. 数据库准备 数据库用到三张表:user表,role表,user_ro

  • springboot整合mybatis-plus基于注解实现一对一(一对多)查询功能

    因为目前所用mybatis-plus版本为3.1.1,感觉是个半成品,所有在实体类上的注解只能支持单表,没有一对一和一对多关系映射,且该功能还在开发中,相信mybatis-plus开发团队在不久的将来应该会实现此功能. 由于本人开发习惯的原因,实在是太讨厌大量的xml充斥在整个项目中,尤其是表的mapper.xml,虽然有代码生成器可以生成,但是有些复杂的查询还是需要手写配置文件里的动态sql,这点比较反感(至于为什么反感,也是有多方面原因的). 不过可能是大量的java开发人员已经被虐惯了,已

  • springboot使用mybatis一对多的关联查询问题记录

    springboot使用mybatis一对多的关联查询 由于刚开始写java不久,对sql语句的熟悉度还是不够熟练,虽然现在使用的mybatisPlus比较多,但我始终觉得sql不能忘也不能不用,刚好最近有个需求需要做到关联的查询,时间也算充足,所以用sql来写,于是踩了很久坑,终于跳出来了,小小记录一下. 一对多 # 我这里是一对多查询,一张主表两张副表,最后还要有一张VO表(就是做关联映射用的),主表和副表的实体我就不贴了,以下是VO实体 这是我的controller @RequestMap

  • mybatis如何使用注解实现一对多关联查询

    mybatis 注解实现一对多关联查询 @Select("select id,mockexam_section as section,id as sectionId" + " from t_p_qb_mockexam_section" + " where mockexam_charpter_id = #{charpterId} and is_delete = 0" + " order by mockexam_section_idx as

  • springboot整合mybatis实现简单的一对多级联查询功能

    本文的目的是用springboot整合mybatis实现一个简单的一对多查询.(查询一个用户有多少件衣服) 第一步:数据库中,可以直接在navicat中建立两张我们需要用到的表 users DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `id` int(0) NOT NULL AUTO_INCREMENT, `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_

  • SpringBoot中Mybatis注解一对多和多对多查询实现示例

    目录 一.模拟的业务查询 二.对应的实体类如下 三.对应的建表语句和模拟数据如下 四.@One一对一映射 五.@Many一对多查询 六.@One @Many的总结 一.模拟的业务查询 系统中的用户user都有唯一对应的地址信息address,每个用户可以有多量车car,类似如下结构 |-- user |-- address |-- carList |-- car1 |-- car2 二.对应的实体类如下 @Data public class AddressPO { private Long id

  • 详解springboot中mybatis注解形式

    springboot整合mybatis对数据库进行访问,本实例采用注解的方式,如下: pom.xml文件 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> </parent> <pr

  • java 中MyBatis注解映射的实例详解

    java  中MyBatis注解映射的实例详解 1.普通映射 @Select("select * from mybatis_Student where id=#{id}") public Student getStudent(int id); @Insert("insert into mybatis_Student (name, age, remark, pic,grade_id,address_id) values (#{name},#{age},#{remark}, #{

  • SpringBoot 中常用注解及各种注解作用

    本篇文章将介绍几种SpringBoot 中常用注解 其中,各注解的作用为: @PathVaribale 获取url中的数据 @RequestParam 获取请求参数的值 @GetMapping 组合注解,是@RequestMapping(method = RequestMethod.GET)的缩写 @RestController是@ResponseBody和@Controller的组合注解. @PathVaribale 获取url中的数据 看一个例子,如果我们需要获取Url=localhost:

  • Mybatis一对多与多对一查询处理详解

    要点 主要还是结果集映射(resultMap) association标签: 一个复杂类型的关联:许多结果将包装成这种类型(JavaBean)嵌套结果映射,关联可以是 resultMap 元素,或是对其它结果映射的引用 collection标签: 一个复杂类型的集合(List)嵌套结果映射,集合可以是resultMap元素,或是对其它结果映射的引用 一对多(association) 数据库结构 tid是student的外键,是teacher表的id JavaBean public class S

  • springboot中mybatis多数据源动态切换实现

    目录 多数据源配置引入 动态数据源路由实现 动态数据源切换使用 案例源码 在开发中,动态数据源配置还是用的比较多的,比如在多数据源使用方面,又或者是在多个DB之间切换方面.这里给出一个动态数据源的配置方案,两个DB均以mysql为例. 多数据源配置引入 mybatis和mysql在springboot中的引入这里就不在说了,不了解的可以参见springboot中mysql与mybatis的引入. 数据源配置如下: datasource: master: type: com.alibaba.dru

  • SpringBoot中Mybatis + Druid 数据访问的详细过程

    目录 1.简介 2.JDBC 3.CRUD操作 4.自定义数据源 DruidDataSource 1.配置 Druid 数据源监控 2.配置 Druid web 监控 filter 5.SpringBoot 整合mybatis 1. 导入mybatis所需要的依赖 2.配置数据库连接信息 3,创建实体类 4.配置Mapper接口类 6.SpringBoot 整合 1.简介 ​ 对于数据访问层,无论是SQL(关系型数据库) 还是NOSQL(非关系型数据库),SpringBoot 底层都是采用 Sp

  • SpringBoot使用Mybatis注解实现分页动态sql开发教程

    目录 一.环境配置 二.Mybatis注解 三.方法参数读取 1.普通参数读取 2.对象参数读取 四.分页插件的使用 五.动态标签 六.完整示例 一.环境配置 1.引入mybatis依赖 compile( //SpringMVC 'org.springframework.boot:spring-boot-starter-web', "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.3", //Mybatis依赖及分页

  • java  中MyBatis注解映射的实例详解

    java  中MyBatis注解映射的实例详解 1.普通映射 @Select("select * from mybatis_Student where id=#{id}") public Student getStudent(int id); @Insert("insert into mybatis_Student (name, age, remark, pic,grade_id,address_id) values (#{name},#{age},#{remark}, #{

  • SpringBoot中@Import注解的使用方式

    目录 一. @Import引入普通类 二. @Import引入配置类(@Configuration修饰的类) 三 .@Import引入ImportSelector的实现类 3.1 静态import场景(注入已知的类) 3.2 动态import场景(注入指定条件的类) 四. @Import引入ImportBeanDefinitionRegistrar的实现类 前言: @Import注解用来帮助我们把一些需要定义为Bean的类导入到IOC容器里面.下面我们就对@Import注解的使用做一个简单的总结

随机推荐