SpringBoot—多对一或一对多关系的多种实现方法

     在SpringBoot多对一或一对多的关联关系中,一般可以分为用注解实现(使用Jpa),或者使用mybatis 在xml文件中进行编写(一个sql语句联表查询完成),另一种方法也是使用mybatis 不过是在service层中用逻辑编写(简单来说就是将前面的一个sql语句分成两个sql语句,变成单表查询)。

        本文不使用Jpa实现,仅通过mybatis 结合Book实例 将后面两种情况进行说明:

实体类如下:

import lombok.Data;
import java.util.List;
/**
 * 图书类别实体
 */
@Data
public class BookType {
	private Integer typeId;
	private String typeName;
	//一个book类别可以有多个book
	private List<Book> books;
	
}
import lombok.Data;
/**
 * 图书实体
 */
@Data
public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;
    }
}

方法一、

mapper层如下:

@Mapper
public interface BookTypeMapper {
    
    public BookType getOne(Integer id);//根据类型ID返回该类型对象的所有数据

}

service实现层如下:(service接口层省略)

@Service
@Slf4j
public class BookTypeServiceImpl implements BookTypeService {
    @Autowired
    private BookTypeMapper bookTypeMapper;

    @Override
    public BookType getOne(Integer typeId) {
        return bookTypeMapper.getOne(typeId);
   }

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.xj.mapper.BookTypeMapper">
	<!--namespace:名称空间,写接口的全类名,相当于告诉MyBatis这个配置文件是实现哪个接口的-->
	<!--XXXXMapper.xml文件相对于XXXXMapper.java(就是DAO层,数据层的接口) Dao层的实现-->
	<!--这个resultMap标签 id="map01"这个ID没有任何关系,没有任何含义,只是一个唯一的标识符,
	而这个type表示最终映射之后返回的是一个类别类型-->
	<resultMap id="map01" type="com.xj.domain.BookType">
		<id property="typeId" column="type_id"></id>
		<result property="typeName" column="type_name"></result>
		<collection property="books" ofType="com.xj.domain.Book">
			<id property="id" column="id"></id>
			<result property="name" column="name"></result>
			<result property="type" column="type"></result>
			<result property="description" column="description"></result>
		</collection>

	</resultMap>
	<select id="getOne" parameterType="Integer"  resultMap="map01">
        select book_type.type_id, book_type.type_name,
        tbl_book.id,tbl_book.type ,tbl_book.name,tbl_book.description
		from book_type  ,tbl_book
		    where book_type.type_id = tbl_book.type and book_type.type_id = #{typeId}
	</select>
</mapper>

方法二、

mapper层如下:

@Mapper
public interface BookTypeMapper {

    BookType findBookType(Integer id);//先通过id去把类型查到

    List<Book> findBooksByType(Integer typeId);//再通过查到的类型id把这个Book集合中的属于这个类型的书全部查到
}

service实现层如下:(service接口层省略,在查询的时候不要忘了非空的判断!)

public class BookTypeServiceImpl implements BookTypeService {
    @Autowired
    private BookTypeMapper bookTypeMapper;

    @Override
    public BookType getOne(Integer typeId) {
        if (typeId == null) {
            return null;
        }
        //1、先通过类别编号找到对应的类别名称
        BookType bookType = bookTypeMapper.findBookType(typeId);

        if (bookType == null) {
            return null;
        }
        //2、再通过类别名称找到对应的书籍
        List<Book> books = bookTypeMapper.findBooksByType(bookType.getTypeId());
        log.info("找到对应的类别:{},找到对应的书籍:{}",bookType,books);

        bookType.setBooks(books);
        log.info("找到类别名称:{},类别编号:{},找到书籍数量:{}",bookType.getTypeName(),bookType.getTypeId(),books.size());
        return bookType;
        //3、在找不到类别的情况下,找不到书籍的情况下,抛出异常,(不过项目中已经有全局异常,不要进行异常处理)
    }
}

xml层:(拆分成两个sql 去写 ,变成两个单表查询,更容易去编写)

<?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.xj.mapper.BookTypeMapper">
	

	<select id="findBookType" parameterType="Integer" resultType="com.xj.domain.BookType">
		SELECT type_id, type_name FROM book_type WHERE type_id = #{typeId}
	</select>

	<select id="findBooksByType" parameterType="Integer" resultType="com.xj.domain.Book">
		SELECT id, name, type, description FROM tbl_book WHERE type = #{typeId}
	</select>

</mapper>

最后在controller层:

@RestController
@RequestMapping("/bookType")
public class BookTypeController {
    @Autowired
    private BookTypeService bookTypeServce;
    
    
    @GetMapping("/{id}")
    public ResultBody getOne(@PathVariable Integer id){
        BookType b=  bookTypeServce.getOne(id);
        Integer code = b != null ? ReturnCode.GET_OK : ReturnCode.GET_ERR;
        String msg = b != null ? "" : "数据失败有误,请重试";
        return new ResultBody(code,b,msg);
    }
}

不过这两种方法效果都一样:(先在数据库中存入两个数据)

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值