MyBatis映射一对多和多对多关系配置(看完这篇不吃亏)

一、概念

1、MyBatis中表之间的关系是如何映射的处理的?

resultType:使用多表查询我们经常会resultType="java.utils.Map" ,我们不推荐这样写,但是这样写对自己比较有利。

  1. 好处:resultType 是直接将查询结果映射到 Java 对象,可以使用简单的类型(如 int、String)或复杂的自定义类型。它的好处是简单直观,易于使用。
  2. 弊端:对于复杂的关系映射,resultType 可能会变得冗长,并且无法处理一对多或多对多的关系映射。

resultMap:resultMap 允许我们定义复杂的映射规则,将结果集中的多个字段映射到一个对象中。

  1. 好处:可以处理复杂的关系映射,支持一对多或多对多的关系映射。我们可以在 resultMap 中定义映射规则,指定字段与属性间的映射关系,并通过嵌套 resultMap 处理表之间的关系。
  2. 弊端:相对于 resultType,resultMap 的配置较为繁琐。

二、一对一

文件配置查看这篇spring整合mybatis教程(详细易懂)里面有配置文件

1、建表

建立我们给的sql文件,运行它用这里面的表,让我们更好的示例操作。

运行会有以下这几个表
MyBatis映射一对多和多对多关系配置(看完这篇不吃亏)_第1张图片

【ps】当然可以用自己的表文件进行操作

2、配置generatorConfig.xml

在我们的配置文件里面配置我们需要的几个表,自动生成所需文件

        

3、生成Moder和Mapper

  1. 选中Maven
  2. 选择自己的项目工程
  3. 选择插件
  4. 选择mybatis-generator
  5. 双击mybatis-generator:generate【注意】不要连续双击,会出问题

MyBatis映射一对多和多对多关系配置(看完这篇不吃亏)_第2张图片


后面会生成我们配置的文件等文件
MyBatis映射一对多和多对多关系配置(看完这篇不吃亏)_第3张图片

 5、Tostring

在你生成的类里面添加@ToString

MyBatis映射一对多和多对多关系配置(看完这篇不吃亏)_第4张图片

MyBatis映射一对多和多对多关系配置(看完这篇不吃亏)_第5张图片

6、Vo包的编写

当然我们要先建立这个包里面的类才能更好的下一步。

我们现在示例的是一对一的,所以根据前面以此类推我们建立一个HOrderItemVo类

package com.tgq.vo;

import com.tgq.model.HOrder;
import com.tgq.model.HOrderItem;

/**
 * @软件包名 com.tgq.vo
 * @用户 tgq
 * @create 2023-08-26 下午4:37
 * @注释说明:
 */
public class HOrderItemVo extends HOrderItem {
    private HOrder hOrder;

    public HOrder gethOrder() {
        return hOrder;
    }

    public void sethOrder(HOrder hOrder) {
        this.hOrder = hOrder;
    }
}

7、xml的sql编写


在我们的里面添加一个sql的方法编写

    
        
        
        
        
        
        
            
            
        
    
    


 

8、编写对应接口及实现类

在上面我们已经写好了sql,我们生成对应的接口接口实现方法。

在我们生成的HOrderItemMapper 接口里面编写

package com.tgq.mapper;

import com.tgq.model.HOrderItem;
import com.tgq.vo.HOrderItemVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface HOrderItemMapper {
    int deleteByPrimaryKey(Integer orderItemId);

    int insert(HOrderItem record);

    int insertSelective(HOrderItem record);

    HOrderItem selectByPrimaryKey(Integer orderItemId);

    int updateByPrimaryKeySelective(HOrderItem record);

    int updateByPrimaryKey(HOrderItem record);

    HOrderItemVo selectByHOrderId(@Param("oiid") Integer oiid);
}

创建一个biz的包,里面编写一个HOrderItemBiz接口类并且编写接口方法

package com.tgq.biz;

import com.tgq.vo.HOrderItemVo;

/**
 * @软件包名 com.tgq.biz
 * @用户 tgq
 * @create 2023-08-26 下午4:48
 * @注释说明:
 */
public interface HOrderItemBiz {
    HOrderItemVo selectByHOrderId(Integer oiid);
}

在这个biz里面新建一个impl包,里面创建一个HOrderItemBizImpl 接口实现类,继承HOrderItemBiz

package com.tgq.biz.impl;

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

/**
 * @软件包名 com.tgq.biz.impl
 * @用户 tgq
 * @create 2023-08-26 下午4:48
 * @注释说明:
 */
@Service
public class HOrderItemBizImpl implements HOrderItemBiz {
    @Autowired
    private HOrderItemMapper hOrderItemMapper;

    @Override
    public HOrderItemVo selectByHOrderId(Integer oiid) {
        return hOrderItemMapper.selectByHOrderId(oiid);
    }
}

9、测试

在这个接口实现类里面创建一个测试类

MyBatis映射一对多和多对多关系配置(看完这篇不吃亏)_第6张图片
 

package com.tgq.biz.impl;

import com.tgq.biz.HOrderItemBiz;
import com.tgq.vo.HOrderItemVo;
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;

/**
 * @软件包名 com.tgq.biz.impl
 * @用户 tgq
 * @create 2023-08-26 下午4:58
 * @注释说明:
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-context.xml"})
public class HOrderItemBizImplTest {
    @Autowired
    private HOrderItemBiz hOrderItemBiz;

    @Test
    public void selectByHOrderId() {
        HOrderItemVo hOrderItemVo = hOrderItemBiz.selectByHOrderId(27);
        System.out.println(hOrderItemVo);
    }
}

 运行结果

三、一对多

1、Vo包类的编写

因为我们是一对多的所以我们再编写vo类的时候,里面是使用list集合

package com.tgq.vo;

import com.tgq.model.HOrder;
import com.tgq.model.HOrderItem;

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

/**
 * @软件包名 com.tgq.vo
 * @用户 tgq
 * @create 2023-08-26 下午3:55
 * @注释说明:
 */
public class HOrderVo extends HOrder {
    //    一个订单存在多个订单项
    private List hOrderItems = new ArrayList<>();

    public List gethOrderItems() {
        return hOrderItems;
    }

    public void sethOrderItems(List hOrderItems) {
        this.hOrderItems = hOrderItems;
    }
}

2、xml的sql编写

在原本的基础的sql上我们增加一个一对多的sql

 
    
    
        
        
        
        
        
        
            
            
            
            
        
    
    

3、编写对应接口及实现类

根据sql生成的对应的HOrderMapper 类里面生成已经编写好的sql方法

package com.tgq.mapper;

import com.tgq.model.HOrder;
import com.tgq.vo.HOrderVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface HOrderMapper {
    int deleteByPrimaryKey(Integer orderId);

    int insert(HOrder record);

    int insertSelective(HOrder record);

    HOrder selectByPrimaryKey(Integer orderId);

    int updateByPrimaryKeySelective(HOrder record);

    int updateByPrimaryKey(HOrder record);

    //============================================
    HOrderVo byOid(@Param("oid") Integer oid);
}

biz包里面新建一个接口HOrderBiz 

package com.tgq.biz;

import com.tgq.vo.HOrderVo;

/**
 * @软件包名 com.tgq.biz
 * @用户 tgq
 * @create 2023-08-26 下午4:15
 * @注释说明:
 */
public interface HOrderBiz {
    HOrderVo byOid(Integer oid);
}

biz包里面的impl里面新建一个Java类实现HOrderBiz 接口

package com.tgq.biz.impl;

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

/**
 * @软件包名 com.tgq.biz.impl
 * @用户 tgq
 * @create 2023-08-26 下午4:16
 * @注释说明:
 */
@Service
public class HOrderBizImpl implements HOrderBiz {
    @Autowired
    private HOrderMapper hOrderMapper;

    @Override
    public HOrderVo byOid(Integer oid) {
        return hOrderMapper.byOid(oid);
    }
}

4、测试

我们新建一个测试类进行编写的方法进行测试

package com.tgq.biz.impl;

import com.tgq.biz.HOrderBiz;
import com.tgq.vo.HOrderVo;
import org.junit.After;
import org.junit.Before;
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.*;

/**
 * @软件包名 com.tgq.biz.impl
 * @用户 tgq
 * @create 2023-08-26 下午4:22
 * @注释说明:
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-context.xml"})
public class HOrderBizImplTest {

    @Autowired
    private HOrderBiz hOrderBiz;

    @Test
    public void byOid() {
        HOrderVo hOrderVo = hOrderBiz.byOid(7);
        System.out.println(hOrderVo);

    }
    
}

测试结果 

MyBatis映射一对多和多对多关系配置(看完这篇不吃亏)_第7张图片

四、多对多

1、Vo类

package com.tgq.vo;

import com.tgq.model.HBook;
import com.tgq.model.HCategory;

import java.util.List;

/**
 * @软件包名 com.tgq.vo
 * @用户 tgq
 * @create 2023-08-27 下午10:29
 * @注释说明:
 */
public class HBookVo extends HBook {
    private List hCategoryList;

    public List gethCategoryList() {
        return hCategoryList;
    }

    public void sethCategoryList(List hCategoryList) {
        this.hCategoryList = hCategoryList;
    }
}
package com.tgq.vo;

import com.tgq.model.HBook;
import com.tgq.model.HCategory;

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

/**
 * @软件包名 com.tgq.vo
 * @用户 tgq
 * @create 2023-08-27 下午11:03
 * @注释说明:
 */
public class HCategoryVo extends HCategory {
    private List hBooks = new ArrayList<>();

    public List gethBooks() {
        return hBooks;
    }

    public void sethBooks(List hBooks) {
        this.hBooks = hBooks;
    }
}

2、xml的sql配置

分别在不同的xml配置文件里面配置

 
        
        
        
        
            
            
        
    
    
    

        
        
        
            
            
            
        
    
    

3、接口及接口实现类

在生成的接口类里面编写对应的接口方法

package com.tgq.mapper;

import com.tgq.model.HBook;
import com.tgq.vo.HBookVo;
import org.apache.ibatis.annotations.Param;

public interface HBookMapper {
    int deleteByPrimaryKey(Integer bookId);

    int insert(HBook record);

    int insertSelective(HBook record);

    HBook selectByPrimaryKey(Integer bookId);

    int updateByPrimaryKeySelective(HBook record);

    int updateByPrimaryKey(HBook record);

    HBookVo selectByBId(@Param("bid") Integer bid);
}
package com.tgq.mapper;

import com.tgq.model.HCategory;
import com.tgq.vo.HCategoryVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface HCategoryMapper {
    int deleteByPrimaryKey(Integer categoryId);

    int insert(HCategory record);

    int insertSelective(HCategory record);

    HCategory selectByPrimaryKey(Integer categoryId);

    int updateByPrimaryKeySelective(HCategory record);

    int updateByPrimaryKey(HCategory record);

    HCategoryVo selectByCId(@Param("cid") Integer cid);
}

biz包里面新建一个HBookBiz接口类

package com.tgq.biz;

import com.tgq.vo.HBookVo;

/**
 * @软件包名 com.tgq.biz
 * @用户 tgq
 * @create 2023-08-27 下午10:50
 * @注释说明:
 */
public interface HBookBiz {
    HBookVo selectByBId(Integer bid);
}
package com.tgq.biz;

import com.tgq.vo.HCategoryVo;

public interface HCategoryBiz {

    HCategoryVo selectByCId(Integer cid);
}

Biz里面的impl包里面新建HBookBizImpl 接口实现HBookBiz接口类

package com.tgq.biz.impl;

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

/**
 * @软件包名 com.tgq.biz.impl
 * @用户 tgq
 * @create 2023-08-27 下午10:53
 * @注释说明:
 */
@Service
public class HBookBizImpl implements HBookBiz {
    @Autowired
    private HBookMapper hBookMapper;

    @Override
    public HBookVo selectByBId(Integer bid) {
        return hBookMapper.selectByBId(bid);
    }
}
package com.tgq.biz.impl;

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

/**
 * @软件包名 com.tgq.biz.impl
 * @用户 tgq
 * @create 2023-08-27 下午11:12
 * @注释说明:
 */
@Service
public class HCategoryBizImpl implements HCategoryBiz {
    @Autowired
    private HCategoryMapper hCategoryMapper;

    @Override
    public HCategoryVo selectByCId(Integer cid) {
        return hCategoryMapper.selectByCId(cid);
    }
}

4、测试

建立一个测试类

package com.tgq.biz.impl;

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

/**
 * @软件包名 com.tgq.biz.impl
 * @用户 tgq
 * @create 2023-08-27 下午10:59
 * @注释说明:
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-context.xml"})
public class HBookBizImplTest {
    @Autowired
    private HBookBiz hBookBiz;

    @Test
    public void selectByBId() {
        HBookVo hBookVo = this.hBookBiz.selectByBId(8);
        System.out.println(hBookVo);
    }
}
package com.tgq.biz.impl;

import com.tgq.biz.HCategoryBiz;
import com.tgq.vo.HCategoryVo;
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.*;

/**
 * @软件包名 com.tgq.biz.impl
 * @用户 tgq
 * @create 2023-08-27 下午11:14
 * @注释说明:
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-context.xml"})
public class HCategoryBizImplTest {
    @Autowired
    private HCategoryBiz hCategoryBiz;

    @Test
    public void selectByCId(){
        HCategoryVo hCategoryVo = hCategoryBiz.selectByCId(8);
        System.out.println(hCategoryVo);
        hCategoryVo.gethBooks().forEach(System.out::println);
    }

}

测试结果

 MyBatis映射一对多和多对多关系配置(看完这篇不吃亏)_第8张图片

 

你可能感兴趣的:(java,mybatis,数据库)