Mybatis的关系关联配置

这篇具有很好参考价值的文章主要介绍了Mybatis的关系关联配置。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言

一. Mybatis关系关联配置的优劣

1.1 MyBatis中的关系关联配置具有以下好处:

1.2 然而,MyBatis中的关系关联配置也存在一些缺点:

二. 关联关系的方向

单向关联

双向关联

三. 一对一关联配置

四. 一对多关联配置

五. 多对多关联配置


前言

MyBatis是一个流行的Java持久化框架,它提供了一种简单而强大的方式来映射Java对象和关系数据库之间的数据。在MyBatis中,关系关联配置是一种用于定义对象之间关系的方式,它允许我们在查询数据库时同时获取相关联的对象。

在MyBatis中,有三种主要的关系关联配置方式:一对一(One-to-One)、一对多(One-to-Many)和多对多(Many-to-Many)。

一. Mybatis关系关联配置的优劣

1.1 MyBatis中的关系关联配置具有以下好处:

  1. 简化数据查询:通过关系关联配置,可以在查询数据时自动加载相关联的数据,无需手动编写复杂的SQL语句。这简化了数据查询的过程,减少了开发人员的工作量。

  2. 提高代码可读性:通过关系关联配置,可以将数据表之间的关系直观地映射到Java对象中。这使得代码更易于理解和维护,提高了代码的可读性。

  3. 减少数据库访问次数:通过关系关联配置,可以一次性加载多个相关联的数据,减少了与数据库的交互次数。这可以提高系统的性能和响应速度。

  4. 支持对象导航:通过关系关联配置,可以在Java对象中直接访问相关联的数据,而无需手动编写额外的查询语句。这简化了代码的编写,提高了开发效率。

1.2 然而,MyBatis中的关系关联配置也存在一些缺点:

  1. 学习成本较高:关系关联配置需要了解MyBatis的配置文件和相关标签的使用方法。对于初学者来说,可能需要花费一些时间来学习和理解这些配置。

  2. 配置复杂性:对于复杂的关系关联,配置文件可能会变得复杂和冗长。这可能增加了维护和调试的难度。

  3. 性能问题:如果关系关联配置不合理,可能会导致数据加载过多或过少,从而影响系统的性能。因此,在配置关系关联时需要注意性能优化的问题。

二. 关联关系的方向

在MyBatis中,关系关联的方向可以分为两种:单向关联和双向关联。

单向关联

单向关联表示关系只在一个方向上存在,其中一个表可以关联到另一个表,但反过来不行。在单向关联中,只有一个表的对象包含了关联对象的引用,而关联对象本身不包含对关联表的引用。

例如,假设我们有两个表:User和Order,一个用户可以有多个订单。在这种情况下,我们可以在User对象中定义一个关联属性List<Order> orders,表示一个用户关联多个订单。但是,在Order对象中并不包含对用户的引用。

单向关联的配置在MyBatis中非常简单,只需要在<resultMap>中使用<collection>或<association>标签来定义关联即可。

双向关联

双向关联表示关系在两个表之间是相互关联的,每个表的对象都包含了对另一个表的引用。这样,我们可以通过一个表的对象访问到关联表的对象,也可以通过关联表的对象访问到原始表的对象。

以前面的例子为例,我们可以在User对象中定义一个关联属性List<Order> orders,表示一个用户关联多个订单。同时,在Order对象中也定义一个关联属性User user,表示一个订单关联一个用户。

双向关联的配置相对复杂一些,需要在<resultMap>中使用<collection>或<association>标签来定义关联,并在关联对象中使用<association>标签来定义反向关联。

需要注意的是,无论是单向关联还是双向关联,都需要在MyBatis的映射文件中进行配置。关联的方向取决于我们在配置时定义的关联属性和关联对象的引用。

总结来说,MyBatis中的关系关联可以是单向关联或双向关联。单向关联表示关系只在一个方向上存在,而双向关联表示关系在两个表之间是相互关联的。在配置关系关联时,我们需要定义关联属性和关联对象的引用,以确定关联的方向。

三. 一对一关联配置

一对一关联配置用于表示两个对象之间的一对一关系(例如夫妻关系,人与身份证)。在数据库中,这通常通过外键来实现。在MyBatis中,我们可以使用<association>元素来配置一对一关联。该元素通常嵌套在<resultMap>元素中,并使用property属性指定关联对象的属性名。

以订单表(order)和订单项表(orderItem)为例,一个订单项对应一个订单。

编写一个vo类继承orderItem,在映射文件中可以通过这个类拿到订单表和订单项表的每个属性:

package com.xissl.vo;

import com.xissl.model.HOrder;
import com.xissl.model.HOrderItem;

/**
 * @author xissl
 * @create 2023-09-04 9:52
 */
public class OrderItemVo extends HOrderItem {

    private HOrder horder;

    public HOrder getHorder() {
        return horder;
    }

    public void setHorder(HOrder horder) {
        this.horder = horder;
    }
}

 在映射文件中配置一对一关联,HOrderItemMapper.xml

  <resultMap id="OrderItemVoMap" type="com.xissl.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="horder" javaType="com.xissl.model.HOrder">
      <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 order_item_id= #{orderItemId}
  </select>

在上面的示例中,我们首先定义了一个resultMap,用于映射OrderItem对象和Order对象之间的关系。在resultMap中,我们使用association元素来配置一对一关联。association元素中的property属性指定了在OrderItem对象中表示Order对象的属性名,javaType属性指定了关联对象的类型。

然后,我们定义了一个查询语句selectByOrderItemId,使用resultMap来映射查询结果。

 编写mapper层接口:

OrderItemVo selectByOrderItemId(@Param("orderItemId") Integer orderItemId);

 业务逻辑层:

package com.xissl.biz;

import com.xissl.model.HOrderItem;
import com.xissl.vo.OrderItemVo;
import org.apache.ibatis.annotations.Param;

public interface HOrderItemBiz {

    OrderItemVo selectByOrderItemId(Integer orderItemId);
}

实现业务层接口:

package com.xissl.biz.impl;

import com.xissl.biz.HOrderItemBiz;
import com.xissl.mapper.HOrderItemMapper;
import com.xissl.vo.OrderItemVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author xissl
 * @create 2023-09-04 9:59
 */
@Service
public class HOrderItemBizImpl implements HOrderItemBiz {

    @Autowired
    private HOrderItemMapper hOrderItemMapper;

    @Override
    public OrderItemVo selectByOrderItemId(Integer orderItemId) {
        return hOrderItemMapper.selectByOrderItemId(orderItemId);
    }
}

  测试代码及结果:

package com.xissl.biz.impl;

import com.xissl.biz.HOrderItemBiz;
import com.xissl.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;

import static org.junit.Assert.*;

/**
 * @author xissl
 * @create 2023-09-04 10:01
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-context.xml"})
public class HOrderItemBizImplTest {

    @Autowired
    private HOrderItemBiz hOrderItemBiz;

    @Test
    public void selectByOrderItemId() {
        OrderItemVo orderItemVo = hOrderItemBiz.selectByOrderItemId(27);
        System.out.println(orderItemVo);
        System.out.println(orderItemVo.getHorder());
    }
}

Mybatis的关系关联配置,java,数据库,开发语言,intellij-idea,mybatis

四. 一对多关联配置

一对多关联配置用于表示一个对象与多个相关对象之间的关系(例如用户与用户的订单,锁和钥匙)。在数据库中,这通常通过外键来实现。在MyBatis中,我们可以使用<collection>元素来配置一对多关联。该元素通常嵌套在<resultMap>元素中,并使用property属性指定关联对象的属性名。

以订单表(order)和订单项表(orderItem)为例,一个订单可以有多个订单项。

编写一个vo类继承order,在映射文件中可以通过这个类拿到订单表和订单项表的每个属性:

package com.xissl.vo;

import com.xissl.model.HOrder;
import com.xissl.model.HOrderItem;

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

/**
 * @author xissl
 * @create 2023-09-04 8:49
 */
public class OrderVo extends HOrder {
    private List<HOrderItem> orderItems = new ArrayList<>();

    public List<HOrderItem> getOrderItems() {
        return orderItems;
    }

    public void setOrderItems(List<HOrderItem> orderItems) {
        this.orderItems = orderItems;
    }
}

在映射文件中配置一对多关联,HOrderMapper.xml

<resultMap id="OrderVoMap" type="com.xissl.vo.OrderVo" >
    <result column="order_id" property="orderId"></result>
    <result column="order_no" property="orderNo"></result>
    <collection property="orderItems" ofType="com.xissl.model.HOrderItem">
      <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 order_id= #{oid}
  </select>

在上面的示例中,我们首先定义了一个resultMap,用于映射Order对象和OrderItem对象之间的关系。在resultMap中,我们使用collection元素来配置一对多关联。collection元素中的property属性指定了在Order对象中表示订单项表的属性名,ofType属性指定了关联对象的类型。

然后,我们定义了一个查询语句selectByOid,使用resultMap来映射查询结果。

编写mapper层接口:

    OrderVo selectByOid(@Param("oid") Integer oid);

 业务逻辑层:

 OrderVo selectByOid(Integer oid);

 实现业务层接口:

package com.xissl.biz.impl;

import com.xissl.biz.HOrderBiz;
import com.xissl.mapper.HOrderMapper;
import com.xissl.vo.OrderVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author xissl
 * @create 2023-09-04 9:08
 */
@Service
public class HOrderBizImpl implements HOrderBiz {

    @Autowired
    private HOrderMapper hOrderMapper;

    @Override
    public OrderVo selectByOid(Integer oid) {
        return hOrderMapper.selectByOid(oid);
    }
}

 测试代码及结果:

package com.xissl.biz.impl;

import com.xissl.biz.HOrderBiz;
import com.xissl.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;

import static org.junit.Assert.*;

/**
 * @author xissl
 * @create 2023-09-04 9:10
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-context.xml"})
public class HOrderBizImplTest {

    @Autowired
    private HOrderBiz hOrderBiz;

    @Test
    public void selectByOid() {
        OrderVo orderVo = hOrderBiz.selectByOid(7);
        System.out.println(orderVo);
        orderVo.getOrderItems().forEach(System.out::println);
    }
}

Mybatis的关系关联配置,java,数据库,开发语言,intellij-idea,mybatis

五. 多对多关联配置

多对多关联配置用于表示两个对象之间的多对多关系(例如老师和学生)。在数据库中,这通常通过中间表来实现。在MyBatis中,我们可以使用<collection>元素来配置多对多关联。该元素通常嵌套在<resultMap>元素中,并使用property属性指定关联对象的属性名。

多对多关系就是和一对多的关系的大同小异,只是多对多的关系可以看成两个一对多关系。

vo类 BookVo:

package com.xissl.vo;

import com.xissl.model.HBook;
import com.xissl.model.HCategory;

import java.util.List;

/**
 * @author xissl
 * @create 2023-09-04 10:43
 */
public class HBookVo extends HBook {

    private List<HCategory> categories;

    public List<HCategory> getCategories() {
        return categories;
    }

    public void setCategories(List<HCategory> categories) {
        this.categories = categories;
    }
}

CategoryVo:

package com.xissl.vo;

import com.xissl.model.HBook;
import com.xissl.model.HCategory;

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

/**
 * @author xissl
 * @create 2023-09-04 11:03
 */
public class CategroyVo extends HCategory {
    private List<HBook> hbooks = new ArrayList<>();

    public List<HBook> getHbooks() {
        return hbooks;
    }

    public void setHbooks(List<HBook> hbooks) {
        this.hbooks = hbooks;
    }
}

映射文件 HBookMapper.xml

 <resultMap id="HBookVoMap" type="com.xissl.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.xissl.model.HCategory">
      <result column="category_id" property="categoryId"></result>
      <result column="category_name" property="categoryName"></result>
    </collection>
  </resultMap>

  <!--  根据书籍id查询出书籍信息及所属类别-->
  <select id="selectByBid" 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>

HCategoryMapper.xml 

  <resultMap id="CategoryVoMap" type="com.xissl.vo.CategroyVo">
    <result column="category_id" property="categoryId"></result>
    <result column="category_name" property="categoryName"></result>
    <collection property="hbooks" ofType="com.xissl.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="selectByCategroyId" resultMap="CategoryVoMap" 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 c.category_id= #{cid}
  </select>

 mapper层接口 BookMapper:

    HBookVo selectByBid(@Param("bid") Integer bid);

CategoryMapper 

    HBookVo selectByBid(@Param("bid") Integer bid);

业务逻辑层:

    HBookVo selectByBid(Integer bid);
    CategroyVo selectByCategroyId(Integer cid);

 实现业务层 BookBiz

package com.xissl.biz.impl;

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

/**
 * @author xissl
 * @create 2023-09-04 10:55
 */
@Service
public class HBookBizImpl implements HBookBiz {
    @Autowired
    private HBookMapper hBookMapper;

    @Override
    public HBookVo selectByBid(Integer bid) {
        return hBookMapper.selectByBid(bid);
    }
}

实现CategoryBiz

package com.xissl.biz.impl;

import com.xissl.biz.HCategoryBiz;
import com.xissl.mapper.HCategoryMapper;
import com.xissl.vo.CategroyVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author xissl
 * @create 2023-09-04 11:11
 */
@Service
public class HCategoryBizImpl implements HCategoryBiz {

    @Autowired
    private HCategoryMapper hCategoryMapper;

    @Override
    public CategroyVo selectByCategroyId(Integer cid) {
        return hCategoryMapper.selectByCategroyId(cid);
    }
}

 测试代码及结果:

package com.xissl.biz.impl;

import com.xissl.biz.HBookBiz;
import com.xissl.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;

import static org.junit.Assert.*;

/**
 * @author xissl
 * @create 2023-09-04 10:56
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-context.xml"})
public class HBookBizImplTest {

    @Autowired
    private HBookBiz hBookBiz;

    @Test
    public void selectByBid() {
        HBookVo hBookVo = hBookBiz.selectByBid(8);
        System.out.println(hBookVo);
        hBookVo.getCategories().forEach(System.out::println);
    }
}

Mybatis的关系关联配置,java,数据库,开发语言,intellij-idea,mybatis

package com.xissl.biz.impl;

import com.xissl.biz.HCategoryBiz;
import com.xissl.vo.CategroyVo;
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;

import static org.junit.Assert.*;

/**
 * @author xissl
 * @create 2023-09-04 11:12
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-context.xml"})
public class HCategoryBizImplTest {

    @Autowired
    private HCategoryBiz hCategoryBiz;

    @Test
    public void selectByCategroyId() {
        CategroyVo categroyVo = hCategoryBiz.selectByCategroyId(8);
        System.out.println(categroyVo);
        categroyVo.getHbooks().forEach(System.out::println);
    }
}

Mybatis的关系关联配置,java,数据库,开发语言,intellij-idea,mybatis

除了上述关系关联配置方式,MyBatis还提供了其他一些配置选项,如延迟加载(Lazy Loading)和级联操作(Cascade)。延迟加载允许我们在需要时才加载关联对象的数据,而级联操作允许我们在操作主对象时同时操作关联对象。

总结起来,MyBatis中的关系关联配置提供了一种灵活而强大的方式来处理对象之间的关系。通过合理配置关系关联,我们可以轻松地进行复杂的数据库查询和操作。文章来源地址https://www.toymoban.com/news/detail-700114.html

到了这里,关于Mybatis的关系关联配置的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java】Mybatis查询数据库

    经过前面的学习Spring系列的操作已经差不多了,接下来我们继续学习更加重要的知识,将前端传递的参数存储起来,或者查询数据库里面的数据 MyBatis是款优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。MyBatis几乎祛除了所有的JDBC代码以及设置参数和获取结果集

    2024年01月18日
    浏览(39)
  • HarmonyOS学习路之开发篇—数据管理(对象关系映射数据库)

    HarmonyOS对象关系映射(Object Relational Mapping,ORM)数据库是一款基于SQLite的数据库框架,屏蔽了底层SQLite数据库的SQL操作,针对实体和关系提供了增删改查等一系列的面向对象接口。应用开发者不必再去编写复杂的SQL语句, 以操作对象的形式来操作数据库,提升效率的同时也

    2024年02月13日
    浏览(32)
  • HarmonyOS学习路之开发篇—数据管理(关系型数据库)

    关系型数据库(Relational Database,RDB)是一种基于关系模型来管理数据的数据库。HarmonyOS关系型数据库基于SQLite组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满足复杂的场景需要。Harmo

    2024年02月13日
    浏览(34)
  • Harmony鸿蒙应用开发——关系型数据库(RelationalStore)

    关系型数据库基于 SQLite 组件,适用于存储包含复杂关系数据的场景,比如一个班级的学生信息,需要包括姓名、学号、各科成绩等,又或者公司的雇员信息,需要包括姓名、工号、职位等,由于数据之间有较强的对应关系,复杂程度比键值型数据更高,此时需要使用关系型

    2024年01月16日
    浏览(39)
  • springboot mybatis-plus数据库超时配置

    超时异常 写XML 写法,单位秒 Mapper类写法,单位秒 超时异常 整个事务的超时时间,单位是秒。 它的原理大致是事务启动时,事务上下文会计算一个到期时间deadLine(当前时间+超时时间),当mybatis - prepareStatement时,会调用 SpringManagedTransaction 的getTimeOut,该方法会计算事务剩

    2024年02月03日
    浏览(43)
  • Mybatis连接MySQL数据库通过逆向工程简化开发流程

    在开发中,一般我们的开发流程是: 数据库:设计数据表 实体类:建立与数据表对应的pojo实体类 持久层:设计持久层,Mapper接口和Mypper.xml sql映射文件 服务层:添加Service接口和ServiceImpl接口实现类 逻辑控制层:设计各页面/功能的Cotroller 但是,我们想的是,很多情况下,实

    2024年02月05日
    浏览(72)
  • Java EE 突击 13 - MyBatis 查询数据库(2)

    这个专栏给大家介绍一下 Java 家族的核心产品 - SSM 框架 JavaEE 进阶专栏 Java 语言能走到现在 , 仍然屹立不衰的原因 , 有一部分就是因为 SSM 框架的存在 接下来 , 博主会带大家了解一下 Spring、Spring Boot、Spring MVC、MyBatis 相关知识点 并且带领大家进行环境的配置 , 让大家真正用好

    2024年02月11日
    浏览(37)
  • MyBatis实现 Java 对象和数据库中日期类型之间的转换(超详细)

    数据库存储的时间字段的类型是datetime Java实体类的时间字段类型是Date 需求:响应前端的时间字段格式为”yyyy-MM-dd HH:mm:ss“ 1、定义resultMap 定义 Java 对象和数据库表字段的对应关系,在 mapper.xml 文件中使用 #{属性名,jdbcType=数据库字段类型} 来进行参数传递和结果集映射,例如

    2024年02月15日
    浏览(35)
  • 【Java】Mybatis查询数据库返回JSON格式的字段映射到实体类属性

    今天遇到了一个bug,大概就是数据库(Mysql)中有一个 type 类型字段,数据类型为json,大概是这样的:[“苹果”,“香蕉”,“葡萄”]的数据格式,这个bug的问题所在呢就是查询后这个json格式的数据无法映射到我们实体类的属性上,解决方案如下: 实体类的配置: @TableField

    2024年02月15日
    浏览(34)
  • MyBatis实现 Java 实体类和数据库中日期类型之间的转换(超详细)

    数据库存储的时间字段的类型是datetime Java实体类的时间字段类型是Date 需求:响应前端的时间字段格式为”yyyy-MM-dd HH:mm:ss“ 1、定义resultMap 定义 Java 对象和数据库表字段的对应关系,在 mapper.xml 文件中使用 #{属性名,jdbcType=数据库字段类型} 来进行参数传递和结果集映射,例如

    2024年02月20日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包