Mybatis之关联关系映射(带你进入Mybatis关联关系映射的世界)

简介: Mybatis之关联关系映射(带你进入Mybatis关联关系映射的世界)



前言

        在上一期的博客中我与老铁们分享了有关Mybatis与Spring的集成,领悟到了Spring给 Mybatis带来的便利以及魅力。今天我来带老铁们进入有关Mybatis关联关系映射的世界,一起来领悟这个世界带给我们的震撼,希望老铁们能有所收获。

一、关联关系映射的简介

1. 概念

  Mybatis的关联关系映射是一种将数据库表之间关联关系映射Java对象之间的技术。它通过配置文件注解的方式,将数据库表的列与Java对象的属性进行映射,从而实现对象与数据库之间的数据交互。这种映射关系可以是一对一、一对多、多对一或多对多的关系。通过Mybatis的关联关系映射,我们可以方便地进行数据库操作,而不需要手动编写SQL语句。

2. 特点

Mybatis关联关系映射的特点

特点 说明 关联关系映射灵活 Mybatis的关联关系映射非常灵活,可以根据实际需求定义各种类型的关联关系,包括一对一、一对多、多对一和多对多等。 方便开发人员配置 通过Mybatis的配置文件或者注解,可以方便地定义关联关系映射,无需编写繁琐的SQL语句,减少了开发人员的工作量。 有利于项目性能优化 Mybatis的关联关系映射可以进行懒加载和延迟加载,即在需要时才去查询关联对象,提高了系统性能,并减少了不必要的查询操作。 提高效率,减少数据库访问压力 Mybatis支持一级缓存和二级缓存,可以缓存关联对象,提高查询效率,减少数据库的访问压力。 使项目具有扩展性 Mybatis的关联关系映射可以通过自定义TypeHandler等扩展点,满足特定需求的定制化开发。

3. 使用场景

  1. 对象关系映射(ORM):Mybatis可以将数据库表与Java对象进行映射,方便进行对象的持久化操作,简化了数据库操作的编写和管理。
  2. 复杂查询:通过关联关系映射,可以方便地进行复杂的查询操作,包括多表关联查询、嵌套查询等,减少了手动编写SQL语句的工作量。
  3. 数据库事务管理:Mybatis的关联关系映射可以与数据库事务管理结合使用,实现数据的一致性和完整性。
  4. 缓存管理:通过关联关系映射,可以方便地进行缓存管理,提高查询效率,减少数据库的访问压力。
  5. 分布式系统:在分布式系统中,Mybatis的关联关系映射可以帮助实现数据的一致性和分布式事务管理。

二、Mybatis中的一对一&一对多关联关系配置

1. 导入相关的数据库表

以上就是我们案例演示所需要的数据库表。

2. 多表查询

resultType"java.yutils.Map"方式

该方式多表查询不推荐在公司的项目中使用,针对于自己开发人员开发是有利的,但是针对于公司开发、项目研发团队来说是不利的。

好处:在针对客户需求发生改变的时候(需求1-->需求2(加字段)-->需求3(加字段) ),针对客户的需求不管怎么变,但我的代码都不会发生改变只需要加个字段即可。

弊端:这种方式在公司或者研发团队中是不利于后期维护和扩展的。

3. 案例部署准备

3.1 生成所需数据库对应的实体类

genreatorConfig.xml 配置实体类信息
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration>
    <!-- 引入配置文件 -->
    <properties resource="jdbc.properties"/>
    <!--指定数据库jdbc驱动jar包的位置-->
    <classPathEntry location="D:\\MYsoftware\\Maven\\mvn_repsoitory\\mysql\\mysql-connector-java\\5.1.44\\mysql-connector-java-5.1.44.jar"/>
    <!-- 一个数据库一个context -->
    <context id="infoGuardian">
        <!-- 注释 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/><!-- 是否取消注释 -->
            <property name="suppressDate" value="true"/> <!-- 是否生成注释代时间戳 -->
        </commentGenerator>
        <!-- jdbc连接 -->
        <jdbcConnection driverClass="${jdbc.driver}"
                        connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}"/>
        <!-- 类型转换 -->
        <javaTypeResolver>
            <!-- 是否使用bigDecimal, false可自动转化以下类型(Long, Integer, Short, etc.) -->
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!-- 01 指定javaBean生成的位置 -->
        <!-- targetPackage:指定生成的model生成所在的包名 -->
        <!-- targetProject:指定在该项目下所在的路径  -->
        <javaModelGenerator targetPackage="com.yx.model"
                            targetProject="src/main/java">
            <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
            <property name="enableSubPackages" value="false"/>
            <!-- 是否对model添加构造函数 -->
            <property name="constructorBased" value="true"/>
            <!-- 是否针对string类型的字段在set的时候进行trim调用 -->
            <property name="trimStrings" value="false"/>
            <!-- 建立的Model对象是否 不可改变  即生成的Model对象不会有 setter方法,只有构造方法 -->
            <property name="immutable" value="false"/>
        </javaModelGenerator>
        <!-- 02 指定sql映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="com.yx.mapper"
                         targetProject="src/main/java">
            <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>
        <!-- 03 生成XxxMapper接口 -->
        <!-- type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象 -->
        <!-- type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象 -->
        <!-- type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口 -->
        <javaClientGenerator targetPackage="com.yx.mapper"
                             targetProject="src/main/java" type="XMLMAPPER">
            <!-- 是否在当前路径下新加一层schema,false路径com.oop.eksp.user.model, true:com.oop.eksp.user.model.[schemaName] -->
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>
        <!-- 配置表信息 -->
        <!-- schema即为数据库名 -->
        <!-- tableName为对应的数据库表 -->
        <!-- domainObjectName是要生成的实体类 -->
        <!-- enable*ByExample是否生成 example类 -->
        <!--<table schema="" tableName="t_book" domainObjectName="Book"-->
        <!--enableCountByExample="false" enableDeleteByExample="false"-->
        <!--enableSelectByExample="false" enableUpdateByExample="false">-->
        <!--&lt;!&ndash; 忽略列,不生成bean 字段 &ndash;&gt;-->
        <!--&lt;!&ndash; <ignoreColumn column="FRED" /> &ndash;&gt;-->
        <!--&lt;!&ndash; 指定列的java数据类型 &ndash;&gt;-->
        <!--&lt;!&ndash; <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" /> &ndash;&gt;-->
        <!--</table>-->
        <table schema="" tableName="t_mvc_Book" domainObjectName="Book"
               enableCountByExample="false" enableDeleteByExample="false"
               enableSelectByExample="false" enableUpdateByExample="false">
            <!-- 忽略列,不生成bean 字段 -->
            <!-- <ignoreColumn column="FRED" /> -->
            <!-- 指定列的java数据类型 -->
            <!-- <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" /> -->
        </table>
<!--        配置要生成的实体类对应的数据库表-->
        <table schema="" tableName="t_hibernate_book" domainObjectName="HBook"
               enableCountByExample="false" enableDeleteByExample="false"
               enableSelectByExample="false" enableUpdateByExample="false">
        </table>
        <table schema="" tableName="t_hibernate_book_category" domainObjectName="HBookCategory"
               enableCountByExample="false" enableDeleteByExample="false"
               enableSelectByExample="false" enableUpdateByExample="false">
        </table>
        <table schema="" tableName="t_hibernate_category" domainObjectName="HCategory"
               enableCountByExample="false" enableDeleteByExample="false"
               enableSelectByExample="false" enableUpdateByExample="false">
        </table>
        <table schema="" tableName="t_hibernate_order" domainObjectName="Order"
               enableCountByExample="false" enableDeleteByExample="false"
               enableSelectByExample="false" enableUpdateByExample="false">
        </table>
        <table schema="" tableName="t_hibernate_order_item" domainObjectName="OrderItem"
               enableCountByExample="false" enableDeleteByExample="false"
               enableSelectByExample="false" enableUpdateByExample="false">
        </table>
    </context>
</generatorConfiguration>

操作

三、关联关系案例演示

3.1 一对多的关联关系案例演示

OrderMapper.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.yx.mapper.OrderMapper" >
  <resultMap id="BaseResultMap" type="com.yx.model.Order" >
    <constructor >
      <idArg column="order_id" jdbcType="INTEGER" javaType="java.lang.Integer" />
      <arg column="order_no" jdbcType="VARCHAR" javaType="java.lang.String" />
    </constructor>
  </resultMap>
  <sql id="Base_Column_List" >
    order_id, order_no
  </sql>
  <resultMap id="OrderVoMap" type="com.yx.vo.OrderVo" >
    <result column="order_id" property="orderId"></result>
    <result column="order_no" property="orderNo"></result>
    <collection property="orderItems" ofType="com.yx.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>
  <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>
</mapper>

OrderMapper.java

package com.yx.mapper;
import com.yx.model.Order;
import com.yx.vo.OrderVo;
import org.apache.ibatis.annotations.Param;
public interface OrderMapper {
    OrderVo selectByOid(@Param("oid") Integer oid);
}

实体类代码

package com.yx.model;
import lombok.ToString;
@ToString
public class Order {
    private Integer orderId;
    private String orderNo;
    public Order(Integer orderId, String orderNo) {
        this.orderId = orderId;
        this.orderNo = orderNo;
    }
    public Order() {
        super();
    }
    public Integer getOrderId() {
        return orderId;
    }
    public void setOrderId(Integer orderId) {
        this.orderId = orderId;
    }
    public String getOrderNo() {
        return orderNo;
    }
    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }
}
//=========================以上是Order实体类代码========================================
//=========================以下是OrderItem实体类代码========================================
package com.yx.model;
import lombok.ToString;
@ToString
public class OrderItem {
    private Integer orderItemId;
    private Integer productId;
    private Integer quantity;
    private Integer oid;
    public OrderItem(Integer orderItemId, Integer productId, Integer quantity, Integer oid) {
        this.orderItemId = orderItemId;
        this.productId = productId;
        this.quantity = quantity;
        this.oid = oid;
    }
    public OrderItem() {
        super();
    }
    public Integer getOrderItemId() {
        return orderItemId;
    }
    public void setOrderItemId(Integer orderItemId) {
        this.orderItemId = orderItemId;
    }
    public Integer getProductId() {
        return productId;
    }
    public void setProductId(Integer productId) {
        this.productId = productId;
    }
    public Integer getQuantity() {
        return quantity;
    }
    public void setQuantity(Integer quantity) {
        this.quantity = quantity;
    }
    public Integer getOid() {
        return oid;
    }
    public void setOid(Integer oid) {
        this.oid = oid;
    }
}

接口类及接口实现类代码

package com.yx.biz;
import com.yx.vo.OrderVo;
/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-04 10:14
 */
public interface OrderBiz {
    OrderVo selectByOid(Integer oid);
}
//============================以上是接口类代码==========================
//============================以下是接口实现类代码======================
package com.yx.biz.impl;
import com.yx.biz.OrderBiz;
import com.yx.mapper.OrderMapper;
import com.yx.vo.OrderVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-04 10:15
 */
@Service
public class OrderBizImpl implements OrderBiz {
    @Autowired
    private OrderMapper orderMapper;
    @Override
    public OrderVo selectByOid(Integer oid) {
        return orderMapper.selectByOid(oid);
    }
}

OrderVo类代码

package com.yx.vo;
import com.yx.model.Order;
import com.yx.model.OrderItem;
import java.util.ArrayList;
import java.util.List;
/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-04 9:05
 */
public class OrderVo extends Order {
    private List<OrderItem> orderItems =new ArrayList<OrderItem>();
    public List<OrderItem> getOrderItems() {
        return orderItems;
    }
    public void setOrderItems(List<OrderItem> orderItems) {
        this.orderItems = orderItems;
    }
}

测试类代码

package com.yx.biz.impl;
import com.yx.biz.OrderBiz;
import com.yx.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 www.yangxin.com
 * @company 木易
 * @create  2023-09-04 10:19
 * 订单测试类
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-context.xml"})
public class OrderBizImplTest {
    @Autowired
    private OrderBiz orderBiz;
    @Test
    public void selectByOid() {
        OrderVo orderVo = orderBiz.selectByOid(7);
        System.out.println(orderVo);
        orderVo.getOrderItems().forEach(System.out::println);
    }
}
测试结果

3.2一对一的关联关系案例演示

OrderItemMapper.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.yx.mapper.OrderItemMapper" >
  <resultMap id="BaseResultMap" type="com.yx.model.OrderItem" >
    <constructor >
      <idArg column="order_item_id" jdbcType="INTEGER" javaType="java.lang.Integer" />
      <arg column="product_id" jdbcType="INTEGER" javaType="java.lang.Integer" />
      <arg column="quantity" jdbcType="INTEGER" javaType="java.lang.Integer" />
      <arg column="oid" jdbcType="INTEGER" javaType="java.lang.Integer" />
    </constructor>
  </resultMap>
  <sql id="Base_Column_List" >
    order_item_id, product_id, quantity, oid
  </sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select 
    <include refid="Base_Column_List" />
    from t_hibernate_order_item
    where order_item_id = #{orderItemId,jdbcType=INTEGER}
  </select>
  <resultMap id="OrderItemVoMap" type="com.yx.vo.OrderItemVo">
    <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>
    <association property="order" javaType="com.yx.model.Order">
      <result column="order_id" property="orderId"></result>
      <result column="order_no" property="orderNo"></result>
    </association>
  </resultMap>
  <select id="selectByOrderItemId" resultMap="OrderItemVoMap" parameterType="java.lang.Integer">
    SELECT
  *
FROM
  t_hibernate_order o,
  t_hibernate_order_item oi
WHERE
  o.order_id = oi.oid
  AND oi.order_item_id=#{oiid}
  </select>
</mapper>

OrderItemMapper.java

package com.yx.mapper;
import com.yx.model.OrderItem;
import com.yx.vo.OrderItemVo;
import org.apache.ibatis.annotations.Param;
public interface OrderItemMapper {
    OrderItemVo selectByOrderItemId(@Param("oiid") Integer oiid);
}

实体类代码

package com.yx.model;
import lombok.ToString;
@ToString
public class Order {
    private Integer orderId;
    private String orderNo;
    public Order(Integer orderId, String orderNo) {
        this.orderId = orderId;
        this.orderNo = orderNo;
    }
    public Order() {
        super();
    }
    public Integer getOrderId() {
        return orderId;
    }
    public void setOrderId(Integer orderId) {
        this.orderId = orderId;
    }
    public String getOrderNo() {
        return orderNo;
    }
    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }
}
//=========================以上是Order实体类代码========================================
//=========================以下是OrderItem实体类代码========================================
package com.yx.model;
import lombok.ToString;
@ToString
public class OrderItem {
    private Integer orderItemId;
    private Integer productId;
    private Integer quantity;
    private Integer oid;
    public OrderItem(Integer orderItemId, Integer productId, Integer quantity, Integer oid) {
        this.orderItemId = orderItemId;
        this.productId = productId;
        this.quantity = quantity;
        this.oid = oid;
    }
    public OrderItem() {
        super();
    }
    public Integer getOrderItemId() {
        return orderItemId;
    }
    public void setOrderItemId(Integer orderItemId) {
        this.orderItemId = orderItemId;
    }
    public Integer getProductId() {
        return productId;
    }
    public void setProductId(Integer productId) {
        this.productId = productId;
    }
    public Integer getQuantity() {
        return quantity;
    }
    public void setQuantity(Integer quantity) {
        this.quantity = quantity;
    }
    public Integer getOid() {
        return oid;
    }
    public void setOid(Integer oid) {
        this.oid = oid;
    }
}

OrderItemVo类代码

package com.yx.vo;
import com.yx.model.Order;
import com.yx.model.OrderItem;
/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-04 11:07
 */
public class OrderItemVo extends OrderItem {
    private Order order;
    public Order getOrder() {
        return order;
    }
    public void setOrder(Order order) {
        this.order = order;
    }
}

接口类及接口实现类代码

package com.yx.biz;
import com.yx.vo.OrderItemVo;
import org.apache.ibatis.annotations.Param;
/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-04 11:10
 */
public interface OrderItemBiz {
    OrderItemVo selectByOrderItemId(@Param("oiid") Integer oiid);
}
//============================以上是接口类代码==========================
//============================以下是接口实现类代码======================
package com.yx.biz.impl;
import com.yx.biz.OrderItemBiz;
import com.yx.mapper.OrderItemMapper;
import com.yx.vo.OrderItemVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-04 11:11
 */
@Service
public class OrderItemBizImpl implements OrderItemBiz {
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Override
    public OrderItemVo selectByOrderItemId(Integer oiid) {
        return orderItemMapper.selectByOrderItemId(oiid);
    }
}

测试类代码

package com.yx.biz.impl;
import com.yx.biz.OrderItemBiz;
import com.yx.vo.OrderItemVo;
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 www.yangxin.com
 * @company 木易
 * @create  2023-09-04 11:13
 * 测试类
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-context.xml"})
public class OrderItemBizImplTest {
@Autowired
private OrderItemBiz orderItemBiz;
    @Test
    public void selectByOrderItemId() {
        OrderItemVo orderItemVo = orderItemBiz.selectByOrderItemId(27);
        System.out.println(orderItemVo);
        System.out.println(orderItemVo.getOrder());
    }
}
测试结果

3.3 多对多的关联关系案例演示

HBookMapper.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.yx.mapper.HBookMapper" >
  <resultMap id="BaseResultMap" type="com.yx.model.HBook" >
    <constructor >
      <idArg column="book_id" jdbcType="INTEGER" javaType="java.lang.Integer" />
      <arg column="book_name" jdbcType="VARCHAR" javaType="java.lang.String" />
      <arg column="price" jdbcType="REAL" javaType="java.lang.Float" />
    </constructor>
  </resultMap>
  <sql id="Base_Column_List" >
    book_id, book_name, price
  </sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select 
    <include refid="Base_Column_List" />
    from t_hibernate_book
    where book_id = #{bookId,jdbcType=INTEGER}
  </select>
  <resultMap id="HBookVoMap" type="com.yx.vo.HBookVo">
    <result column="book_id" property="bookId"></result>
    <result column="book_name" property="bookName"></result>
    <result column="price" property="price"></result>
    <collection property="categories" ofType="com.yx.model.HCategory">
      <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_book_category bc,
  t_hibernate_category c
  where b.book_id=bc.bid
  and bc.cid=c.category_id
  and b.book_id=#{bid}
  </select>
</mapper>

HBookMapper.java

package com.yx.mapper;
import com.yx.model.HBook;
import com.yx.vo.HBookVo;
import org.apache.ibatis.annotations.Param;
public interface HBookMapper {
    HBookVo selectByBookId(@Param("bid") Integer bid);
}

实体类代码

package com.yx.model;
import lombok.ToString;
@ToString
public class HBook {
    private Integer bookId;
    private String bookName;
    private Float price;
    public HBook(Integer bookId, String bookName, Float price) {
        this.bookId = bookId;
        this.bookName = bookName;
        this.price = price;
    }
    public HBook() {
        super();
    }
    public Integer getBookId() {
        return bookId;
    }
    public void setBookId(Integer bookId) {
        this.bookId = bookId;
    }
    public String getBookName() {
        return bookName;
    }
    public void setBookName(String bookName) {
        this.bookName = bookName;
    }
    public Float getPrice() {
        return price;
    }
    public void setPrice(Float price) {
        this.price = price;
    }
}
//==========================以上是HBook实体类代码==========================================
==========================以下是HCategory实体类代码==========================================
package com.yx.model;
import lombok.ToString;
@ToString
public class HCategory {
    private Integer categoryId;
    private String categoryName;
    public HCategory(Integer categoryId, String categoryName) {
        this.categoryId = categoryId;
        this.categoryName = categoryName;
    }
    public HCategory() {
        super();
    }
    public Integer getCategoryId() {
        return categoryId;
    }
    public void setCategoryId(Integer categoryId) {
        this.categoryId = categoryId;
    }
    public String getCategoryName() {
        return categoryName;
    }
    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }
}

HBookVo代码

package com.yx.vo;
import com.yx.model.HBook;
import com.yx.model.HCategory;
import java.util.List;
/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-04 11:34
 */
public class HBookVo extends HBook {
    private List<HCategory> categories;
    public List<HCategory> getCategories() {
        return categories;
    }
    public void setCategories(List<HCategory> categories) {
        this.categories = categories;
    }
}

接口类及接口实现类代码

package com.yx.biz;
import com.yx.vo.HBookVo;
/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-04 11:41
 */
public interface HBookBiz {
    HBookVo selectByBookId(Integer bid);
}
//======================以上是接口类代码===================================
//======================以下是接口实现类代码===============================
package com.yx.biz.impl;
import com.yx.biz.HBookBiz;
import com.yx.mapper.HBookMapper;
import com.yx.vo.HBookVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-04 11:42
 */
@Service
public class HBookBizImpl implements HBookBiz {
    @Autowired
    private HBookMapper hBookMapper;
    @Override
    public HBookVo selectByBookId(Integer bid) {
        return hBookMapper.selectByBookId(bid);
    }
}

测试类代码

package com.yx.biz.impl;
import com.yx.biz.HBookBiz;
import com.yx.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 www.yangxin.com
 * @company 木易
 * @create  2023-09-04 11:43
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-context.xml"})
public class HBookBizImplTest {
@Autowired
private HBookBiz hBookBiz;
    @Test
    public void selectByBookId() {
        HBookVo hBookVo =this.hBookBiz.selectByBookId(8);
        System.out.println(hBookVo);
        hBookVo.getCategories().forEach(System.out::println);
    }
}
测试结果

目录
相关文章
|
1天前
|
Java 数据库连接 Maven
使用mybatis插件generator生成实体类,dao层和mapper映射
使用mybatis插件generator生成实体类,dao层和mapper映射
8 0
|
19天前
|
Java 数据库连接 mybatis
|
22天前
|
SQL Java 数据库连接
MyBatis映射文件深入
MyBatis映射文件深入
51 0
mybatis-2.映射关系(1-1 1-n n-n)
mybatis-2.映射关系(1-1 1-n n-n)
|
1月前
|
SQL Java 数据库连接
myabtis中为什么说 MyBatis 是半自动 ORM 映射工具?它与全自动的区别在哪里
myabtis中为什么说 MyBatis 是半自动 ORM 映射工具?它与全自动的区别在哪里
|
1月前
|
SQL 存储 Java
Mybatis之自定义映射resultMap
【1月更文挑战第3天】 一、resultMap处理字段和属性的映射关系 二、多对一映射处理 1、级联方式处理映射关系 2、使用association处理映射关系 3、分步查询 1. 查询员工信息 2. 查询部门信息 三、一对多映射处理 1、collection 2、分步查询 3. 查询部门信息 4. 根据部门id查询部门中的所有员工 四、延迟加载
149 2
Mybatis之自定义映射resultMap
|
1月前
|
SQL Java 数据库连接
Mybatis之Mybatis简介、搭建Mybatis相关步骤(开发环境、maven、核心配置文件、mapper接口、映射文件、junit测试、log4j日志)
【1月更文挑战第2天】 MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code。随着开发团队转投Google Code旗下,iBatis3.x正式更名为MyBatis。代码于2013年11月迁移到Github iBatis一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBatis提供的持久层框架包括SQL Maps和Data Access Objects(DAO)
142 3
Mybatis之Mybatis简介、搭建Mybatis相关步骤(开发环境、maven、核心配置文件、mapper接口、映射文件、junit测试、log4j日志)
|
1月前
|
XML Java 数据库连接
Mybatis之简介、使用操作(安装、XML、SqlSession、映射的SQL语句、命名空间、作用域和生命周期)
【1月更文挑战第2天】 MyBatis 是一款优秀的持久层框架 MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的过程 MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 实体类 【Plain Old Java Objects,普通的 Java对象】映射成数据库中的记录。
92 2
Mybatis之简介、使用操作(安装、XML、SqlSession、映射的SQL语句、命名空间、作用域和生命周期)
|
1月前
|
Java 数据库连接 mybatis
一文彻底搞懂Mybatis系列(十三)之MyBatis一对多映射查询
一文彻底搞懂Mybatis系列(十三)之MyBatis一对多映射查询
|
1月前
|
Java 数据库连接 mybatis
一文彻底搞懂Mybatis系列(十二)之MyBatis多对一映射延迟加载(association和lazyLoadingEnabled)
一文彻底搞懂Mybatis系列(十二)之MyBatis多对一映射延迟加载(association和lazyLoadingEnabled)