Mybatis アソシエーション マッピング (Mybatis アソシエーション マッピングの世界へご案内します)

目次

序文

1. 関係マッピングの概要

1.コンセプト

2. 特徴

3. 利用シーン

2. Mybatis での 1 対 1 および 1 対多の関係の構成

1. 関連するデータベーステーブルをインポートする

 2. 複数テーブルのクエリ

resultType "java.yutils.Map" メソッド:

3. ケース展開の準備

3.1 必要なデータベースに対応するエンティティクラスの生成

エンティティクラス情報を設定するのは、generatorConfig.xml です。

3. 関連する関係の事例のデモンストレーション

3.1 1対多の関連関係の例のデモ

オーダーマッパー.xml

オーダーマッパー.java

エンティティクラスコード

インターフェースクラスとインターフェース実装クラスのコード

OrderVoクラスコード

テストコード

試験結果

3.2 1対1の関連関係の例のデモンストレーション

OrderItemMapper.xml

OrderItemMapper.java

エンティティクラスコード

 OrderItemVo クラスコード

インターフェースクラスとインターフェース実装クラスのコード

テストコード

試験結果

編集

3.3 多対多の関連関係の例のデモ

HBookMapper.xml

 HBookMapper.java

エンティティクラスコード

HBookVoコード

インターフェースクラスとインターフェース実装クラスのコード

 テストコード

試験結果


序文

         前回のブログでは、Mybatis と Spring の統合についてベテランと共有し、Spring が Mybatis にもたらす利便性と魅力を実感しました。今日は退役軍人を Mybatis リレーションシップ マッピングの世界に連れて行き、この世界が私たちにもたらす衝撃について理解してもらいたいと思います。退役軍人が何かを得られることを願っています。

1. 関係マッピングの概要

1.コンセプト

   Mybatis の関連付けマッピングは、データベース テーブル間の関連付けをJava オブジェクトマッピングするテクノロジです。構成ファイルまたは注釈を通じてデータベース テーブルの列を Java オブジェクトのプロパティにマップし、それによってオブジェクトとデータベース間のデータ対話を実現します。このマッピング関係は、1 対 1、1 対多、多対 1、または多対多のいずれかになりますMybatis のアソシエーション マッピングを使用すると、SQL ステートメントを手動で記述せずにデータベース操作を簡単に実行できます。

2. 特徴

Mybatis の関連付け関係マッピングの特徴

機能 の説明: 柔軟な関連付けマッピング: Mybatis の関連付けマッピングは非常に柔軟で、1 対 1、1 対多、多対 1、多対 など、実際のニーズに応じてさまざまなタイプの関連付けを定義できます。多くの。 開発者にとって便利な構成: Mybatis 構成ファイルまたはアノテーションを通じて、面倒な SQL ステートメントを作成することなく関連付けマッピングを簡単に定義できるため、開発者の作業負荷が軽減されます。 プロジェクトのパフォーマンスの最適化に貢献 Mybatis のアソシエーション マッピングは遅延ロードおよび遅延ロードが可能です。つまり、関連オブジェクトは必要な場合にのみクエリされるため、システム パフォーマンスが向上し、不必要なクエリ操作が削減されます。 効率の向上とデータベース アクセスの負荷の軽減 Mybatis は、関連するオブジェクトをキャッシュし、クエリの効率を向上させ、データベース アクセスの負荷を軽減できる 1 次キャッシュと 2 次キャッシュをサポートしています。 プロジェクトを拡張可能にする: Mybatis の関連付け関係マッピングは、カスタム TypeHandler やその他の拡張ポイントを通じて、特定のニーズのカスタマイズされた開発に対応できます。

3. 利用シーン

  1. オブジェクト リレーショナル マッピング (ORM) : Mybatis は、データベース テーブルを Java オブジェクトにマップして、オブジェクトの永続化操作を容易にし、データベース操作の作成と管理を簡素化できます。

  2. 複雑なクエリ:アソシエーション関係マッピングにより、複数テーブルの関連付けられたクエリ、ネストされたクエリなどの複雑なクエリ操作を簡単に実行でき、SQL ステートメントを手動で記述する作業負荷が軽減されます。

  3. データベース トランザクション管理: Mybatis のアソシエーション マッピングをデータベース トランザクション管理と組み合わせて使用​​すると、データの一貫性と整合性を実現できます。

  4. キャッシュ管理:アソシエーション関係マッピングにより、キャッシュ管理を簡単に実行でき、クエリ効率が向上し、データベース アクセスの負荷が軽減されます。

  5. 分散システム:分散システムでは、Mybatis のアソシエーション マッピングはデータの一貫性と分散トランザクション管理の実現に役立ちます。

2. Mybatis での 1 対 1 および 1 対多の関係の構成

1. 関連するデータベーステーブルをインポートする

 

 上記は、ケースのデモンストレーションに必要なデータベース テーブルです。

 2. 複数テーブルのクエリ

resultType "java.yutils.Map" メソッド:

この複数テーブル クエリの方法は、企業プロジェクトでの使用には推奨されません。自社の開発者にとっては有益ですが、企業の開発チームやプロジェクトの R&D チームにとっては不利です。

利点:顧客のニーズが変化した場合 (要件 1 -> 要件 2 (フィールドの追加) -> 要件 3 (フィールドの追加))、顧客のニーズがどのように変化しても、コードは変更されません。フィールドを追加するだけです。

短所:この方法は、会社や研究開発チームでのその後のメンテナンスや拡張には役に立ちません。

3. ケース展開の準備

3.1 必要なデータベースに対応するエンティティクラスの生成

エンティティクラス情報を設定するのは、generatorConfig.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. 関連する関係の事例のデモンストレーション

3.1 1対多の関連関係の例のデモ

オーダーマッパー.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>

オーダーマッパー.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 1対1の関連関係の例のデモンストレーション

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);
    }
}
試験結果

おすすめ

転載: blog.csdn.net/weixin_74352229/article/details/132566671