【MyBatis】自定义resultMap三种映射关系

目录

一、一对一映射(One-to-One)

[1.1 表关系](#1.1 表关系)

[1.2 resultMap设置自定义映射](#1.2 resultMap设置自定义映射)

二、一对多映射(One-to-Many)

[2.1 创建实体](#2.1 创建实体)

[2.2 级联方式处理映射关系](#2.2 级联方式处理映射关系)

[2.3 定义SQL](#2.3 定义SQL)

[2.4 OrderMapper接口](#2.4 OrderMapper接口)

[2.5 编写业务逻辑层](#2.5 编写业务逻辑层)

[2.6 Junit测试](#2.6 Junit测试)

三、多对多映射(Many-to-Many)

[3.1 表关系](#3.1 表关系)

[3.2 创建实体](#3.2 创建实体)

[3.3 处理映射关系、定义sql](#3.3 处理映射关系、定义sql)

[3.4 HBookMapper 接口](#3.4 HBookMapper 接口)

[3.5 编写业务逻辑层](#3.5 编写业务逻辑层)

[3.6 Junit测试](#3.6 Junit测试)


一、一对一映射(One-to-One)

1.1 表关系

一对一映射是指一个对象与另一个对象具有一对一的关系。例如,一个用户(User)与一个地址(Address)之间的关系。假设我们有以下表结构:

user 表:

java 复制代码
id (int)
name (varchar)
address_id (int)

address 表:

java 复制代码
id (int)
street (varchar)
city (varchar)

首先,创建 User 和 Address 实体类:

User.java

java 复制代码
public class User {
    private int id;
    private String name;
    private Address address;
    // getters and setters
}

Address.java

java 复制代码
public class Address {
    private int id;
    private String street;
    private String city;
    // getters and setters
}

接下来,创建一个 resultMap 进行一对一映射:

1.2 resultMap设置自定义映射

UserMapper.xml

java 复制代码
<resultMap id="UserAddressResultMap" type="User">
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    //一对一关系使用association
    <association property="address" javaType="Address">
        <id property="id" column="address_id"/>
        <result property="street" column="street"/>
        <result property="city" column="city"/>
    </association>
</resultMap>

属性:

  • id:表示自定义映射的唯一标识
  • type:查询的数据要映射的实体类的类型

子标签:

  • id:设置主键的映射关系
  • result:设置普通字段的映射关系
  • association :设置多对一的映射关系
  • collection:设置一对多的映射关系

子标签属性:

  • property:设置映射关系中实体类中的属性名
  • column:设置映射关系中表中的字段名

最后,编写一个查询方法来使用这个 resultMap:

UserMapper.xml

java 复制代码
<select id="findUserWithAddress" resultMap="UserAddressResultMap">
    SELECT u.id, u.name, a.id as address_id, a.street, a.city
    FROM user u
    INNER JOIN address a ON u.address_id = a.id
    WHERE u.id = #{id}
</select>

最后实现接口findUserWithAddress方法测试即可,通过以上简单的案例,我相信你已经明白自定义关系映射了。往往实际开发中数据和表是要复杂的多,进阶用法请看以下示例:

二、一对多映射(One-to-Many)

一对多映射是指一个对象与多个对象具有一对多的关系。例如,一个订单(Oeder)与一个订单详情(OrderItem)之间的关系。假设我们有以下表结构:

2.1 创建实体

利用mybatis逆向工程(generatorConfig.xml)生成模型层代码 :

创建 OrderVo 它是一个值对象(Value Object),继承 Order 类并添加了一个额外的属性 orderItems。该类用于在应用程序的各个层之间传递数据,尤其是在表示层和业务逻辑层之间。在这个例子中,OrderVo 类用于表示一个订单及其关联的订单项。

java 复制代码
package com.ycxw.vo;

import com.ycxw.model.Order;
import com.ycxw.model.OrderItem;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 云村小威
 * @site blog.csdn.net/Justw320
 * @create 2023-08-26 16:30
 */
@Data
public class OrderVo extends Order {
    private List<OrderItem> orderItems = new ArrayList<>();
}

2.2 级联方式处理映射关系

java 复制代码
    <resultMap id="OrderVoMap" type="com.ycxw.vo.OrderVo">
        <result column="order_id" property="orderId"></result>
        <result column="order_no" property="orderNo"></result>
        //多关系使用collection
        <collection property="orderItems" ofType="com.ycxw.model.OrderItem">
            <result column="order_item_id" property="orderItemId"></result>
            <result column="product_id" property="productId"></result>
            <result column="quantity" property="quantity"></result>
            <result column="oid" property="oid"></result>
        </collection>
    </resultMap>

2.3 定义SQL

java 复制代码
    <select id="SelectByOid" resultMap="OrderVoMap" parameterType="java.lang.Integer">
        SELECT *
        FROM t_hibernate_order o,
             t_hibernate_order_item oi
        WHERE o.order_id = oi.oid
          AND o.order_id = #{oid}
    </select>

2.4 OrderMapper接口

java 复制代码
package com.ycxw.mapper;

import com.ycxw.model.Order;
import com.ycxw.vo.OrderVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface OrderMapper {

    OrderVo SelectByOid(@Param("oid") Integer oid);
}

2.5 编写业务逻辑层

复制代码
OrderItmeBiz 接口
java 复制代码
package com.ycxw.biz;

import com.ycxw.vo.OrderItemVo;

/**
 * @author 云村小威
 * @site blog.csdn.net/Justw320
 * @create 2023-08-26 21:48
 */
public interface OrderItmeBiz {
    OrderItemVo SelectByOitemId(Integer oiid);
}
复制代码
OrderBizImpl 接口实现类
java 复制代码
package com.ycxw.biz.impl;

import com.ycxw.biz.OrderBiz;
import com.ycxw.mapper.OrderMapper;
import com.ycxw.vo.OrderVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author 云村小威
 * @site blog.csdn.net/Justw320
 * @create 2023-08-26 16:46
 */
@Service
public class OrderBizImpl implements OrderBiz {
    @Autowired
    private OrderMapper orderMapper;

    @Override
    public OrderVo SelectByOid(Integer oid) {
        return orderMapper.SelectByOid(oid);
    }
}

2.6 Junit测试

java 复制代码
package com.ycxw.biz.impl;

import com.ycxw.biz.OrderBiz;
import com.ycxw.vo.OrderVo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @author 云村小威
 * @site blog.csdn.net/Justw320
 * @create 2023-08-26 16:48
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-mybatis.xml"})
public class OrderBizImplTest {
    @Autowired
    private OrderBiz orderBiz;


    @Test
    public void selectByOid() {
        OrderVo orderVo = orderBiz.SelectByOid(8);
        //获取订单
        System.out.println(orderVo);
        //获取订单项信息
        orderVo.getOrderItems().forEach(System.out::println);
    }

}

运行结果:

三、多对多映射(Many-to-Many)

3.1 表关系

多对多映射是指多个对象与多个对象具有多对多的关系。表之间的多对多关系稍微复杂,需要一个中间表来表示:

中间表有三个字段,其中两个字段分别作为外键指向各自一方的主键,由此通过中间表来表示多对多关系,通过一个表联合另一个中间表可以表示为一对多关系。

**如:**根据书籍id查找关联属性类别:

3.2 创建实体

利用mybatis逆向工程(generatorConfig.xml)生成模型层代码 :

创建 HBookVo 值对象(Value Object)

java 复制代码
package com.ycxw.vo;

import com.ycxw.model.BookCategory;
import com.ycxw.model.HBook;
import lombok.Data;

import java.util.List;

/**
 * @author 云村小威
 * @site blog.csdn.net/Justw320
 * @create 2023-08-27 21:03
 */
@Data
public class HBookVo extends HBook {
    private List<BookCategory> bookc = new ArrayList<>();
}

3.3 处理映射关系、定义sql

java 复制代码
  <resultMap id="HBookVoMap" type="com.ycxw.vo.HBookVo" >
    <result column="book_id" property="bookId"></result>
    <result column="book_name" property="bookName"></result>
    <result column="price" property="price"></result>
    <collection property="bookc" ofType="com.ycxw.model.Category">
      <result column="category_id" property="categoryId"></result>
      <result column="category_name" property="categoryName"></result>
    </collection>
  </resultMap>

  <!--根据书籍的id查询书籍的信息及所属属性-->
  <select id="selectByBookId" resultMap="HBookVoMap" parameterType="java.lang.Integer">
    SELECT
      *
    FROM
      t_hibernate_book b,
      t_hibernate_category c,
      t_hibernate_book_category bc
    WHERE
      b.book_id = bc.bid
      AND c.category_id = bc.bcid
      AND b.book_id = #{bid}
  </select>

3.4 HBookMapper 接口

java 复制代码
HBookVo selectByBookId(@Param("bid") Integer bid);

3.5 编写业务逻辑层

复制代码
HBookBiz 接口
java 复制代码
package com.ycxw.biz;

import com.ycxw.vo.HBookVo;

/**
 * @author 云村小威
 * @site blog.csdn.net/Justw320
 * @create 2023-08-29 12:47
 */
public interface HBookBiz {
    HBookVo selectByBookId(Integer bid);
}
复制代码
HBookBizImpl 接口实现类
java 复制代码
package com.ycxw.biz.impl;

import com.ycxw.biz.HBookBiz;
import com.ycxw.mapper.HBookMapper;
import com.ycxw.vo.HBookVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author 云村小威
 * @site blog.csdn.net/Justw320
 * @create 2023-08-29 12:48
 */
@Service
public class HBookBizImpl implements HBookBiz {
    @Autowired
    private HBookMapper hBookMapper;
    @Override
    public HBookVo selectByBookId(Integer bid) {
        return hBookMapper.selectByBookId(bid);
    }
}

3.6 Junit测试

java 复制代码
package com.ycxw.biz.impl;

import com.ycxw.biz.HBookBiz;
import com.ycxw.vo.HBookVo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @author 云村小威
 * @site blog.csdn.net/Justw320
 * @create 2023-08-26 16:48
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-mybatis.xml"})
public class OrderBizImplTest {
    @Autowired
    private HBookBiz hBookBiz;


    @Test
    public void selectByBookId(){
        HBookVo hBookVo = hBookBiz.selectByBookId(22);
        //数据所有信息
        System.out.println(hBookVo);
        //书籍有关的类别
        System.out.println(hBookVo.getBookc());
    }
}

反之亦然,**如:**根据类别id查找书籍信息

java 复制代码
 <resultMap id="CategotyVoMap" type="com.ycxw.vo.CategoryVo">
    <result column="category_id" property="categoryId"></result>
    <result column="category_name" property="categoryName"></result>
    <collection property="books" ofType="com.ycxw.model.HBook">
      <result column="book_id" property="bookId"></result>
      <result column="book_name" property="bookName"></result>
      <result column="price" property="price"></result>
    </collection>
  </resultMap>

  <select id="selectCategoryId" resultMap="CategotyVoMap" parameterType="java.lang.Integer">
    SELECT
      *
    FROM
      t_hibernate_book b,
      t_hibernate_category c,
      t_hibernate_book_category bc
    WHERE
      b.book_id = bc.bid
      AND c.category_id = bc.bcid
      AND c.category_id = #{cid}
  </select>

测试运行:

相关推荐
猿饵块1 分钟前
cmake--get_filename_component
java·前端·c++
编程小白煎堆2 分钟前
C语言:枚举类型
java·开发语言
王哈哈嘻嘻噜噜9 分钟前
c语言中“函数指针”
java·c语言·数据结构
qq_3391911417 分钟前
spring boot admin集成,springboot2.x集成监控
java·前端·spring boot
GoFly开发者25 分钟前
GoFly快速开发框架/Go语言封装的图像相似性比较插件使用说明
开发语言·后端·golang
苹果酱056733 分钟前
通过springcloud gateway优雅的进行springcloud oauth2认证和权限控制
java·开发语言·spring boot·后端·中间件
Sunny_yiyi36 分钟前
Gateway--服务网关
java·开发语言·gateway
可爱推推41 分钟前
头歌数据库系统原理数据模型测试
数据库·头歌
Mike!1 小时前
C++进阶 set和map讲解
java·开发语言·数据结构·c++·set·map·cpp
翔云1234561 小时前
Go语言的垃圾回收(GC)机制的迭代和优化历史
java·jvm·golang·gc