今天记录一下 【Mybatis高级映射】之一对一映射
一对一查询:
以学生和地址为例子,一个学生对应一个地址。。。。。。。。
学生表:
地址表:
具体sql语句脚本如下:
/*Table structure for table `t_student` */
DROP TABLE IF EXISTS `t_student`;
CREATE TABLE `t_student` (
`t_student_id` varchar(50) DEFAULT NULL COMMENT '学生id',
`t_name` varchar(50) DEFAULT NULL COMMENT '学生名字',
`t_email` varchar(50) DEFAULT NULL COMMENT '学生邮件',
`t_phone` varchar(50) DEFAULT NULL COMMENT '学生电话',
`t_addr_id` varchar(50) DEFAULT NULL COMMENT '地址id'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `t_student` */
insert into `t_student`(`t_student_id`,`t_name`,`t_email`,`t_phone`,`t_addr_id`) values ('1000','曾凡','3546512@qq.com','12345685645','100'),('1001','胡张海','3548412@qq.com','13545685645','101'),('1002','吴可凡','3548712@qq.com','13645685645','102'),('1003','周小小','35874512@qq.com','1345685485645','103'),('1004','秦秦楠','35546512@qq.com','13887585485645','104');
/*Table structure for table `t_address` */
DROP TABLE IF EXISTS `t_address`;
CREATE TABLE `t_address` (
`t_addr_id` varchar(50) DEFAULT NULL COMMENT '地址id',
`t_street` varchar(50) DEFAULT NULL COMMENT '街道',
`t_city` varchar(50) DEFAULT NULL COMMENT '城市',
`t_country` varchar(50) DEFAULT NULL COMMENT '国家',
`t_state` varchar(50) DEFAULT NULL COMMENT '状态',
`t_zip` varchar(50) DEFAULT NULL COMMENT '门牌号'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `t_address` */
insert into `t_address`(`t_addr_id`,`t_street`,`t_city`,`t_country`,`t_state`,`t_zip`) values ('100','北北','重庆','中国','0','1314'),('101','宜昌','宜昌','中国','0','1315'),('102','孝感','湖北','中国','0','1365'),('103','咸宁','湖北','中国','0','1347'),('104','襄阳','湖北','中国','0','1378');
建立pojo对象:
student对象:
package com.tgb.model;
public class Student {
private Integer studentId;
private String name;
private String email;
private String phone;
private Address address;
public Integer getStudentId() {
return studentId;
}
public void setStudentId(Integer studentId) {
this.studentId = studentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
地址对象 Address.java
package com.tgb.model;
public class Address {
private Integer addrId;
private String street;
private String city;
private String state;
private String zip;
private String country;
public Integer getAddrId() {
return addrId;
}
public void setAddrId(Integer addrId) {
this.addrId = addrId;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
今天主要讲解的是,一对一的关系,针对mybatis而言,它的编写方式一般有三种方式,我以StudentMapper.xml来进行讲解:
方法一: 使用点符号和嵌套对象
<resultMap type="com.tgb.model.Student" id="StudentWithAddressResult">
<id property="studentId" column="t_student_id"/>
<result property="name" column="t_name"/>
<result property="email" column="t_email"/>
<result property="phone" column="t_phone"/>
<result property="address.addrId" column="t_addr_id"/>
<result property="address.street" column="t_street"/>
<result property="address.city" column="t_city"/>
<result property="address.state" column="t_state"/>
<result property="address.zip" column="t_zip"/>
<result property="address.country" column="t_country"/>
</resultMap>
<select id="selectStudentWithAddressByStudentId" parameterType="int" resultMap="StudentWithAddressResult">
SELECT
`t_student_id`,
`t_name`,
`t_email`,
`t_phone`,
t.`t_addr_id` ,
tt.`t_addr_id`,
`t_street`,
`t_city`,
`t_country`,
`t_state`,
`t_zip`
FROM
`t_student` t
JOIN t_address tt
ON (t.t_addr_id = tt.t_addr_id)
WHERE t.t_student_id =#{studentId}
</select>
映射接口:
package com.tgb.mapper;
import com.tgb.model.Student;
public interface StudentMapper {
Student selectStudentWithAddressByStudentId(int id);
Student findStudentWithAddress(int studentId);
}
方法二: 使用嵌套ResultMap
使用 < association>
<resultMap type="com.tgb.model.Address" id="AddressResult">
<id property="addrId" column="t_addr_id"/>
<result property="street" column="t_street"/>
<result property="city" column="t_city"/>
<result property="state" column="t_state"/>
<result property="zip" column="t_zip"/>
<result property="country" column="t_country"/>
</resultMap>
<resultMap type="com.tgb.model.Student" id="StudentWithAddressResult">
<id property="studentId" column="t_student_id"/>
<result property="name" column="t_name"/>
<result property="email" column="t_email"/>
<result property="phone" column="t_phone"/>
<association property="address" resultMap="AddressResult"/>
</resultMap>
<select id="selectStudentWithAddressByStudentId" parameterType="int" resultMap="StudentWithAddressResult">
SELECT
`t_student_id`,
`t_name`,
`t_email`,
`t_phone`,
t.`t_addr_id` ,
tt.`t_addr_id`,
`t_street`,
`t_city`,
`t_country`,
`t_state`,
`t_zip`
FROM
`t_student` t
JOIN t_address tt
ON (t.t_addr_id = tt.t_addr_id)
WHERE t.t_student_id =#{studentId}
</select>
当然啦,像上面的方法二中的,两个resultMap也可以合并成一个resultMap,代码如下:
<resultMap type="com.tgb.model.Student" id="StudentWithAddressResult">
<id property="studentId" column="t_student_id"/>
<result property="name" column="t_name"/>
<result property="email" column="t_email"/>
<result property="phone" column="t_phone"/>
<association property="address" javaType="com.tgb.model.Address">
<id property="addrId" column="t_addr_id"/>
<result property="street" column="t_street"/>
<result property="city" column="t_city"/>
<result property="state" column="t_state"/>
<result property="zip" column="t_zip"/>
<result property="country" column="t_country"/>
</association>
</resultMap>
<select id="selectStudentWithAddressByStudentId" parameterType="int" resultMap="StudentWithAddressResult">
SELECT
`t_student_id`,
`t_name`,
`t_email`,
`t_phone`,
t.`t_addr_id` ,
tt.`t_addr_id`,
`t_street`,
`t_city`,
`t_country`,
`t_state`,
`t_zip`
FROM
`t_student` t
JOIN t_address tt
ON (t.t_addr_id = tt.t_addr_id)
WHERE t.t_student_id =#{studentId}
</select>
方法三: 使用嵌套select
< association property=”关联属性” column=”数据库中外键id” select=”嵌套select方法”/>
<resultMap type="com.tgb.model.Address" id="AddressResult">
<id property="addrId" column="t_addr_id"/>
<result property="street" column="t_street"/>
<result property="city" column="t_city"/>
<result property="state" column="t_state"/>
<result property="zip" column="t_zip"/>
<result property="country" column="t_country"/>
</resultMap>
<select id="findAddressById" parameterType="int" resultMap="AddressResult">
SELECT
`t_addr_id`,
`t_street`,
`t_city`,
`t_country`,
`t_state`,
`t_zip`
FROM
`t_address` WHERE t_addr_id = #{addrId}
</select>
<resultMap type="com.tgb.model.Student" id="StudentWithAddressResult">
<id property="studentId" column="t_student_id"/>
<result property="name" column="t_name"/>
<result property="email" column="t_email"/>
<result property="phone" column="t_phone"/>
<association property="address" column="t_addr_id" select="findAddressById"/>
</resultMap>
<select id="findStudentWithAddress" parameterType="int" resultMap="StudentWithAddressResult">
SELECT
`t_student_id`,
`t_name`,
`t_email`,
`t_phone`,
`t_addr_id`
FROM
t_student WHERE t_student_id = #{studentId}
</select>
映射接口:
package com.tgb.mapper;
import com.tgb.model.Student;
public interface StudentMapper {
Student selectStudentWithAddressByStudentId(int id);
Student findStudentWithAddress(int studentId);
}
参考网址:https://www.cnblogs.com/davidgu/p/6270761.html
https://gitee.com/lwh_zfj/mybatis_advanced_mapping_use/tree/onetoone/
源代码,可以并不启动容器,直接使用junit+spring便可以测试,最主要的文件使用如下图: