之前写过通过封装 map 和 list 实现两张数据表的关联,今天我们来学习一下如何通过一个中间层 DTO 来实现多张数据表的关联。

以 User(用户表)和 Question (用户提问表)这两张表为例,来进行今天的探索之旅。

POJO:

User :

字段:用户ID,姓名,头像

public class User implements Serializable {
    private Long id;
	private String name;
    private String avatarUrl;
Question :

字段:问题ID,标题,内容,创建用户的ID(外键)

public class Question implements Serializable {
    private Long id;
    private String title;
    private String description;
    private Long creator;

DTO:

中间层 QuestionDTO 关联两张表:
public class QuestionDTO {
    private Question question;
    private User user;
}

Service :

之前通过封装 map 和 list 实现两张数据表的关联是先将数据存进 map,之后再存进 list 。

通过 DTO 也是一个道理:首先将数据存进 DTO ,然后将 DTO 存进 list 。

public class QuestionService {
    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private UserMapper userMapper;

    public List<QuestionDTO> getQuestionDTOList(){
        List<QuestionDTO> questionDTOList = new ArrayList<>();

        List<Question> questions = questionMapper.selectAll();
        for (Question question : questions) {
            User user = userMapper.selectByPrimaryKey(question.getCreator());
            QuestionDTO questionDTO = new QuestionDTO();
            questionDTO.setQuestion(question);
            questionDTO.setUser(user);
            questionDTOList.add(questionDTO);
        }
        return questionDTOList;
    }
}

首先 11 行 questionMapper.selectAll() 取出了所有的 question,然后遍历 question 可以通过 question.getCreator() 得到每一个 question 的作者ID,也就得到了 User 表中的 id 。userMapper.selectByPrimaryKey() 也就得到了每一个问题所对应的 User 的信息。然后将每一个 question 及其对应的 user 写入 QuestionDTO,最后将一个个 QuestionDTO 存进 list 。

Controller:

@Autowired
QuestionService questionService;

public String index(Model model){
    List<QuestionDTO> questionDTOList = questionService.getQuestionDTOList();
    model.addAttribute("list",questionDTOList);
    return "index";
}  

index.html:

<div class="media" th:each="list : ${list}">
    <div class="media-left">
        <a href="#">
            <img class="media-object img-rounded" th:src="${list.user.avatarUrl}" alt="...">
        </a>
    </div>
    <div class="media-body">
        <h4 class="media-heading" th:text="${list.question.title}">Media heading</h4>
        <span th:text="${list.question.description}"></span><br/>
    </div>
</div>