一、数据库
演示的小demo涉及两张表,一张是Person表,记录用户基本信息,另一张是phone表,记录电话号码,Person的phoneID外键关联phone表id。此处示例涉及并不符合实际情况,一对多方式是一个号码有多个用户使用的(更符合实际情况的是一个用户有多个号码),原因是从一对一demo直接扒拉过来用的,见谅,不过也能体现mybatis关联查询一对多的细节了。
1. 数据库设计
CREATE TABLE `tbl_person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) NOT NULL,
`password` varchar(30) NOT NULL,
`gender` varchar(30) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`phoneID` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
UNIQUE KEY `username` (`username`),
KEY `per_pho_fk` (`phoneID`),
CONSTRAINT `per_pho_fk` FOREIGN KEY (`phoneID`) REFERENCES `tbl_phone` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
CREATE TABLE `tbl_phone` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`phoneNum` varchar(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `phoneNum` (`phoneNum`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
2. 数据库补充
phoneID作为tbl_person的外键,关联tbl_phone的主键id,此处假设的业务逻辑是一个号码存在多个用户。
用例数据:
id,username,password,gender,age,phoneID
1,zhangsan,123,male,18,2
2,lisi,123,female,24,2
id,phoneNum
2,15200898242
二、一对多两种方式详解
通过phone id查询电话信息,并关联查询拥有该电话的Person信息列表,一种方式是先查询tbl_phone表,获取到phone id,再通过phone id从tbl_person表中查询Person信息列表,这种方式要和数据库交互两次,发出两次sql语句,但是数据库返回的数据没有冗余;另一种方式是直接关联查询,只与数据库交互一次,只发出一次sql语句,但是数据库返回数据存在主表信息冗余,冗余数据为主表内容,冗余次数为从表中满足条件的记录数。
因此,应该选择哪一种方式更合理,需要根据具体的业务场景来选择,没有绝对的正确,只有相对的适合。
两种方式的实现,最核心的差异在于mapper.xml配置文件,完整的示例工程,需要mybatis-config.xml以及log4j的配置文件等,此处不一一列举出来,在第三部分附上完整代码download地址,此处仅仅关注核心问题——实现以及差异。两种方式的po类相同,主要关注Phone类中通过List<Person>体现关联关系,示例代码如下。
package cn.wxy.domain;
import java.io.Serializable;
public class Person implements Serializable {
private static final long serialVersionUID = 6028193740527306730L;
private Integer id;
private String username;
private String password;
private String gender;
private Integer age;
private Integer phoneID;
public Person() {
}
public Person(Integer id, String username, String password, String gender,
Integer age, Integer phoneID) {
super();
this.id = id;
this.username = username;
this.password = password;
this.gender = gender;
this.age = age;
this.phoneID = phoneID;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getP