美文网首页
MyBatis多表联查

MyBatis多表联查

作者: Java机械师 | 来源:发表于2022-09-05 10:51 被阅读0次

前言


创建数据库表(user和message),并插入数据:

CREATE TABLE `user` (

`id`  varchar(64) NOT NULL ,

`name`  varchar(64) NULL ,

PRIMARY KEY (`id`)

);

CREATE TABLE `info` (

`id`  varchar(64) NOT NULL ,

`uid`  varchar(64) NULL ,

`msg`  varchar(255) NULL ,

PRIMARY KEY (`id`)

);

INSERT INTO `user` (`id`, `name`) VALUES ('1001', 'ahzoo');

INSERT INTO `user` (`id`, `name`) VALUES ('1002', 'ouo');

INSERT INTO `info` (`id`, `uid`, `msg`) VALUES ('2001', '1001', '测试信息');

INSERT INTO `info` (`id`, `uid`, `msg`) VALUES ('2002', '1001', '第二条信息');

再创建两个数据库表(role和user_role),并插入数据,用于多对多操作:

CREATE TABLE `role` (

`id`  varchar(64) NOT NULL ,

`name`  varchar(64) NULL ,

PRIMARY KEY (`id`)

);

CREATE TABLE `user_role` (

`user_id`  varchar(64) NOT NULL ,

`role_id`  varchar(64) NOT NULL

);

INSERT INTO `role` (`id`, `name`) VALUES ('3001', '用户');

INSERT INTO `role` (`id`, `name`) VALUES ('3002', '管理员');

INSERT INTO `user_role` (`user_id`, `role_id`) VALUES ('1001', '3001');

INSERT INTO `user_role` (`user_id`, `role_id`) VALUES ('1001', '3002');

INSERT INTO `user_role` (`user_id`, `role_id`) VALUES ('1002', '3002');

创建一个springboot项目,并生成增删改查,快速开始。

项目结构:

依赖:

<dependencies>

        <dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

        </dependency>

        <dependency>

            <groupId>org.mybatis.spring.boot</groupId>

            <artifactId>mybatis-spring-boot-starter</artifactId>

            <version>2.2.2</version>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter</artifactId>

        </dependency>

        <dependency>

            <groupId>org.projectlombok</groupId>

            <artifactId>lombok</artifactId>

            <optional>true</optional>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>

    </dependencies>

一对一

一条信息对应一个发送者,查询信息的发送者。在Info实体类中增加User对象,这样在对user和info进行联查时,将User对象一起返回:entity/Info

import lombok.Data;

@Data

public class Info {

    private String id;

    private String uid;

    private String msg;

//    接收一对一查询到的User对象

    private User user;

}

映射文件:mapper/InfoDao.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.example.demo.mapper.InfoMapper">

<!--    使用Map对象作为返回结果-->

    <select id="selectListToMap" resultType="Map">

        SELECT u.id,u.name,i.id,i.uid,i.msg

        FROM user u,info i

        WHERE u.id=i.uid

    </select>

    <resultMap id="BaseResultMap" type="com.example.demo.entity.Info">

        <id property="id" column="id" jdbcType="VARCHAR"/>

        <result property="uid" column="uid" jdbcType="VARCHAR"/>

        <result property="msg" column="msg" jdbcType="VARCHAR"/>

        <association property="user" javaType="com.example.demo.entity.User">

持久层:mapper/InfoMapper

import com.example.demo.entity.Info;

import org.apache.ibatis.annotations.Mapper;

import java.util.List;

import java.util.Map;

@Mapper

public interface InfoMapper {

    List<Map<String,String>> selectListToMap();

    List<Info> selectListByMap();

}

测试:查询目标信息对应的用户信息

import com.example.demo.entity.Info;

import com.example.demo.mapper.InfoMapper;

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import java.util.Map;

@SpringBootTest

class InfoTests {

    @Autowired

    InfoMapper infoMapper;

    /**

    * 使用Map对象作为返回结果

    */

    @Test

    public void toGetMapResult(){

        List<Map<String, String>> infos = infoMapper.selectListToMap();

        infos.forEach(System.out::println);

        /*

        {msg=测试信息, uid=1001, name=ahzoo, id=1001}

        {msg=第二条信息, uid=1001, name=ahzoo, id=1001}

        */

    }

    /**

    * 使用Info对象作为返回结果

    */

    @Test

    public void toGetInfoResult(){

        List<Info> infos = infoMapper.selectListByMap();

        infos.forEach(System.out::println);

        /*

        Info(id=2001, uid=1001, msg=测试信息, user=User(id=1001, name=ahzoo))

        Info(id=2002, uid=1001, msg=第二条信息, user=User(id=1001, name=ahzoo))

        */

    }

}

一对多

一个用户可以发送多条信息,查询用户下的所有信息。在User实体类中增加Info的List对象,用于返回查询到的多个Info对象:entity/User

import lombok.Data;

import java.util.List;

@Data

public class User{

    private String id;

    private String name;

//    接收一对多查询到的Info对象集合

    private List<Info> infos;

}

持久层:mapper/UserMapper

import com.example.demo.entity.User;

import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper

public interface UserMapper {

    List<User> findAllByMap();

}

映射文件:mapper/UserMapper.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.example.demo.mapper.UserMapper">

    <resultMap id="BaseResultMap" type="com.example.demo.entity.User">

        <id property="id" column="id" jdbcType="VARCHAR"/>

        <result property="name" column="name" jdbcType="VARCHAR"/>

        <!--配置集合信息

        property:自定义集合的名称

        ofType:集合的数据类型

        -->

        <collection property="infos" ofType="com.example.demo.entity.Info">

            <result property="id" column="info_id" jdbcType="VARCHAR"/>

            <result property="uid" column="uid" jdbcType="VARCHAR"/>

            <result property="msg" column="msg" jdbcType="VARCHAR"/>

        </collection>

    </resultMap>

    <!-- 查询目标用户所有发布的信息(这里使用左外连接查询) -->

    <select id="findAllByMap" resultMap="BaseResultMap">

        SELECT u.id,u.name,i.id AS info_id,i.uid,i.msg

        FROM user u

        LEFT OUTER JOIN info i

            ON u.id = i.uid;

    </select>

</mapper>

测试:

import com.example.demo.entity.User;

import com.example.demo.mapper.UserMapper;

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest

public class UserTests {

    @Autowired

    UserMapper userMapper;

    @Test

    public void toGetAll(){

        List<User> allByMap = userMapper.findAllByMap();

        allByMap.forEach(System.out::println);

        /*

        User(id=1001, name=ahzoo, infos=[Info(id=2001, uid=1001, msg=测试信息, user=null), Info(id=2002, uid=1001, msg=第二条信息, user=null)])

        */

    }

}

可以看到所有用户下的所有信息都被查询到

多对多

一个用户可以有多个角色,一个角色可以属于多个用户,查询用户对应的角色,及角色对应的用户。在User实体类中增加Role的List对象,用于返回查询到的多个Role对象:entity/User

import lombok.Data;

import java.util.List;

@Data

public class User{

    private String id;

    private String name;

    private List<Role> roles;

}

同理:entity/Role

import lombok.Data;

import java.util.List;

@Data

public class Role {

    private String id;

    private String name;

    private List<User> users;

}

持久层:mapper/RoleMapper

import com.example.demo.entity.Role;

import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper

public interface RoleMapper {

    List<Role> getAllUser();

}

mapper/UserMapper

import com.example.demo.entity.User;

import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper

public interface UserMapper {

    List<User> getAllRole();

}

映射文件:mapper/RoleMapper

<resultMap id="roleMap" type="com.example.demo.entity.Role">

        <id property="id" column="id" jdbcType="VARCHAR"/>

        <result property="name" column="name" jdbcType="VARCHAR"/>

        <collection property="users" ofType="com.example.demo.entity.User">

            <result property="id" column="role_id" jdbcType="VARCHAR"/>

            <result property="name" column="name" jdbcType="VARCHAR"/>

        </collection>

    </resultMap>

    <select id="getAllUser" resultMap="roleMap">

        SELECT u.id,u.name,r.id AS role_id,r.name

        FROM user u

        LEFT OUTER JOIN user_role ur ON u.id = ur.user_id

        LEFT OUTER JOIN role r ON r.id = ur.role_id

    </select>

mapper/UserMapper

<resultMap id="userMap" type="com.example.demo.entity.User">

        <id property="id" column="id" jdbcType="VARCHAR"/>

        <result property="name" column="name" jdbcType="VARCHAR"/>

        <collection property="roles" ofType="com.example.demo.entity.Role">

            <result property="id" column="role_id" jdbcType="VARCHAR"/>

            <result property="name" column="name" jdbcType="VARCHAR"/>

        </collection>

    </resultMap>

    <select id="getAllRole" resultMap="userMap">

        SELECT u.id,u.name,r.id AS role_id,r.name

        FROM user u

        LEFT OUTER JOIN user_role ur ON u.id = ur.user_id

        LEFT OUTER JOIN role r ON r.id = ur.role_id

    </select>

测试:

@Autowired

    RoleMapper roleMapper;

    @Autowired

    UserMapper userMapper;

    @Test

    public void toGetAllUser(){

        List<Role> allUser = roleMapper.getAllUser();

        allUser.forEach(System.out::println);

/*

        Role(id=1001, name=ahzoo, users=[User(id=3001, name=ahzoo, roles=null), User(id=3002, name=ahzoo, roles=null)])

        Role(id=1002, name=ouo, users=[User(id=null, name=ouo, roles=null)])

*/

    }

    @Test

    public void toGetAllRole(){

        List<User> allRole = userMapper.getAllRole();

        allRole.forEach(System.out::println);

/*

        User(id=1001, name=ahzoo, roles=[Role(id=3001, name=ahzoo, users=null), Role(id=3002, name=ahzoo, users=null)])

        User(id=1002, name=ouo, roles=[Role(id=null, name=ouo, users=null)])

*/

    }

原文链接:https://juejin.cn/post/7120591216349020167

相关文章

  • MyBatis多表联查

    前言 创建数据库表(user和message),并插入数据: CREATE TABLE `user` (`id` ...

  • InvalidDefinitionException: No s

    在使用springboot + mybatis实现多表关联查询时报以下错误:com.fasterxml.jacks...

  • python面试题01

    1、什么是多表关联查询,有几种多表关联的查询方式,分别是什么? 多表关联查询概念: 多表关联查询分类:1.1内连接...

  • Mybatis第二章——多表同时插入和级联查询

    Mybatis第二章——多表同时插入和级联查询 知识点一:多表同时插入,其中要插入的Blog的数据中的author...

  • mybatis 多表关联查询

    首先这里有两个表分别是seckill(秒杀表),success_killed(秒杀成功明细表)两个表和seckil...

  • mybatis的多表关联查询

    平时项目中不可避免的会使用多表关联查询。 xml文件的写法 分页插件的使用,使用pagehelperpackage...

  • 多表联查

    1、原生查询示例:代码如下:$Model = new Model();$sql = 'select a.id,a....

  • 多表联查

  • 多表联查

    表结构 t_sys_user系统用户表image t_course班课表image 内连接查询 就是两个表的相同部...

  • 多表联查

    多表联查 多个有关系的表可以同时查询,语法和单表查询基本一致 select from 表1,表2,... wher...

网友评论

      本文标题:MyBatis多表联查

      本文链接:https://www.haomeiwen.com/subject/lhsinrtx.html