mybatis 关联映射---一对一关联映射
参考:
https://zhuanlan.zhihu.com/p/480525100?utm_id=0
一、一对一关联映射
在我们这节课之前,我们通过mybatis 操作的数据库表,这个表都是单表的操作【CRUD】。我们在实际的操作过程中会遇到多张表(两张表、三张表。。。)之间存在某种关联(
举个例子:设计两张数据表
第一张表:学生证
表名(sCard)
字段:id(自增主键)
sno(学号)
第二张表:学生信息表(studentInfo)
字段:id(自增主键)
name、sex、age、sdept
存在这个样的一对一:一个学生必定对应一个学号,一个学号必定对应一个学生
关联:其实在数据库表的技术手段上,可以通过设置外键的方式把表与表之间关联起来、
给我们的学生信息表设置一个字段 sid(作为一个外键 去关联 学生证表中的 id 字段)
)
c
-- 学生证表 scard
create table scard(
id int primary key auto_increment comment "自增的主键",
sno varchar(8) not null UNIQUE comment "学号,不能为空且必须唯一"
);
insert into scard(sno) values("20840301");
insert into scard(sno) values("20840302");
insert into scard(sno) values("20840303");
select * from scard;
-- 唯一约束:UNIQUE
insert into scard(sno) values("20840303");
-- 不为空约束:not null
delete from scard where id = 4;
-- 学生信息表studentInfo
create table studentInfo(
id int primary key auto_increment comment "自增的主键",
name varchar(8) not null,
sex varchar(2) not null,
age int not null,
sdept varchar(8) not null comment "所在系",
-- 设置一个字段 sid(作为一个外键 去关联 学生证表中的 id 字段【主键】)
sid varchar(8) ,-- 注意:这个字段的类型最好与关联表中字段类型一致
foreign key(sid) REFERENCES scard(id)
);
-- 修改表的字段
ALTER table studentInfo modify column sid int;
-- ALTER TABLE 表名 MODIFY COLUMN 字段名 数据类型(修改后的长度)
-- 查看表结构
desc studentInfo;
insert into studentInfo(name,sex,age,sdept,sid) values("张三","男",21,"信息工程系",2);
insert into studentInfo(name,sex,age,sdept,sid) values("李四","男",21,"信息工程系",1);
insert into studentInfo(name,sex,age,sdept,sid) values("李师师","女",21,"信息工程系",3);
select * from studentInfo;
-- 查询学生信息(包含:学号、姓名、性别、年龄、系别)
select s.sno,s1.name,s1.sex,s1.age,s1.sdept
from scard as s,studentInfo as s1
where s.id = s1.sid
-- 排序默认是:升序(asc)如果想要降序(desc)
order by s.sno asc
;

从数据库的角度出发就是在任意一个表中引入另外一个表的主键作为外键
在本类的定义中定义另外一个类的对象。
二、定义 pojo 的java类
在本类【外键所在的java类】的定义中定义另外一个类【引用主键所在的类】的对象。
1、Scard【另外一个类】
c
package com.pojo;
public class Scard {
private Integer id;
private String sno;// 学号
// getter / setter
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSno() {
return sno;
}
public void setSno(String sno) {
this.sno = sno;
}
// toString
@Override
public String toString() {
return "Scard{" +
"id=" + id +
", sno='" + sno + '\'' +
'}';
}
}
2、StudentInfo【本类】
c
package com.pojo;
public class StudentInfo {
private Integer id ;
private String name;
private String sex ;
private Integer age;
private String sdept;
/* private String sid ;*/
// 在本类中定义另一个类的对象
private Scard scard;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSdept() {
return sdept;
}
public void setSdept(String sdept) {
this.sdept = sdept;
}
public Scard getScard() {
return scard;
}
public void setScard(Scard scard) {
this.scard = scard;
}
@Override
public String toString() {
return "StudentInfo{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", sdept='" + sdept + '\'' +
", scard=" + scard +
'}';
}
}
三、映射文件(mapper.xml)
1、ScardMapper.xml
c
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mapper.ScardMapper">
<!--根据id查询信息-->
<select id="selectScardById" parameterType="Integer" resultType="Scard">
select * from scard where id = #{id}
</select>
</mapper>
2、StudentInfoMapper.xml
c
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mapper.StudentInfoMapper">
<!--根据id 查询信息【(包含:学号、姓名、性别、年龄、系别)】-->
<!--嵌套查询:通过执行另外一条SQL映射语句来返回预期的特殊类型-->
<select id="selectStudentInfoById" parameterType="Integer" resultMap="StudentInfoMap">
select * from studentInfo where id = #{id}
</select>
<!--查询语句的结果映射-->
<resultMap id="StudentInfoMap" type="StudentInfo">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="sex" column="sex"></result>
<result property="age" column="age" javaType="Integer"></result>
<result property="sdept" column="sdept" javaType="String"></result>
<!--一对一关联映射: association 使用select属性引入一条语句-->
<association property="scard" column="sid" javaType="Scard"
select="com.mapper.ScardMapper.selectScardById">
</association>
</resultMap>
<!--第二种-->
<!--根据id 查询信息【学号这个字段在scard表中、【姓名、性别、年龄、系别】这四个字段在studentInfo表中)】-->
<!--嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集-->
<select id="selectStudentInfoById_1" parameterType="Integer" resultMap="StudentInfoMap_1">
select s.sno,s1.name,s1.sex,s1.age,s1.sdept
from scard as s,studentInfo as s1
where s.id = s1.sid
and s1.id = #{id};
</select>
<!--查询结果映射 resultMap -->
<resultMap id="StudentInfoMap_1" type="StudentInfo">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="sex" column="sex"></result>
<result property="age" column="age" javaType="Integer"></result>
<result property="sdept" column="sdept" javaType="String"></result>
<!--一对一关联映射-->
<association property="scard" javaType="Scard">
<id property="id" column="id"></id>
<result property="sno" column="sno"/>
</association>
</resultMap>
</mapper>
四、映射文件对应的接口
1、ScardMapper
c
package com.mapper;
import com.pojo.Scard;
public interface ScardMapper {
Scard selectScardById(Integer id);
}
2、StudentInfoMapper
c
package com.mapper;
import com.pojo.StudentInfo;
public interface StudentInfoMapper {
StudentInfo selectStudentInfoById(Integer id);
}
五、测试代码
c
import com.mapper.StudentInfoMapper;
import com.mapper.UserInfoMapper_1;
import com.pojo.StudentInfo;
import com.pojo.UserInfo_1;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class StudentInfoTest {
SqlSessionFactory sqlSessionFactory;
SqlSession sqlSession;
StudentInfoMapper stu;
@Before
public void init(){
String resource = "mybatis-config.xml";
try {
// 程序去读取外部的文件,那么这个流我们定义为输入流
InputStream input = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
sqlSession = sqlSessionFactory.openSession();
stu = sqlSession.getMapper(StudentInfoMapper.class);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void selectStudentInfoById(){
StudentInfo studentInfo = stu.selectStudentInfoById(1);
System.out.println(studentInfo.toString());
}
@After
public void destroy(){
// 提交事务
sqlSession.commit();
// 关闭会话sqlSession
sqlSession.close();
}
}
