MyBatis关联映射详解

本文最后更新于:1 年前

实体关系

实体关系指的就是数据与数据之间的关系,例如:用户和角色、房屋和楼栋、订单和商品。

实体关系分为四种,即一对一关联一对多关联多对一关联多对多关联

一对一关联

如:人和身份证、学生和学生证、用户基本信息和详情……

数据表关系分为以下两种:

  • 主键关联

    用户表主键 和详情主键相同时,表示是匹配的数据。

  • 唯一外键关联

一对多关联、多对一关联

一对多和多对一只是站在不同角度,相对而言,如:

  • 一对多: 班级和学生 、 类别和商品、楼栋和房屋……

  • 多对一:学生和班级 、 商品和类别、房屋和楼栋……

数据表关系:在多的一端添加外键和一的一段进行关联。

多对多关联

如:用户和角色、角色和权限、房屋和业主、学生和社团、订单和商品……

数据表关系:建立第三张关系表添加两个外键分别与两张表主键进行关联。

环境准备

1. 创建web项目(maven)

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 添加web依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>

2. 部署MyBatis框架

2.1 添加依赖

1
2
3
4
5
6
7
8
9
10
11
12
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>

2.2 配置文件

jdbc.properties
mybatis-config.xml

2.3 Mybatis工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class MyBatisUtil {

private static SqlSessionFactory factory;
private static final ThreadLocal<SqlSession> local = new ThreadLocal<SqlSession>();

static{
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}

public static SqlSessionFactory getSqlSessionFactory(){
return factory;
}

public static SqlSession getSqlSession(boolean isAutoCommit){
SqlSession sqlSession = local.get();
if(sqlSession == null){
sqlSession = factory.openSession(isAutoCommit);
local.set(sqlSession);
}
return sqlSession;
}

public static SqlSession getSqlSession(){
return getSqlSession(false);
}

public static <T extends Object>T getMapper(Class<T> c){
SqlSession sqlSession = getSqlSession(true);
return sqlSession.getMapper(c);
}

}

一对一关联

用户信息(1)————用户详情(1)。

1
2
3
4
5
6
7
8
-- 用户信息表
create table users(
user_id int primary key auto_increment,
user_name varchar(20) not null unique,
user_pwd varchar(20) not null,
user_realname varchar(20) not null,
user_img varchar(100) not null
)
1
2
3
4
5
6
7
8
9
-- 用户详情表
create table details(
detail_id int primary key auto_increment,
user_addr varchar(50) not null,
user_tel char(11) not null,
user_desc varchar(200),
uid int not null unique,
-- constraintIFK. LUSER foreign key(uid) references users(user_id)
)

添加操作(事务)

添加用户信息的同时添加用户详情。

实体类

User.java Detail.java

DAO接口

1
2
3
public interface UserDAO {
public int insertUser(User user);
}
1
2
3
public interface DetailDAO {
public int insertDetail(Detail detail);
}

映射文件

UserMapper.xml
DetailMapper.xml
mybatis-config.xml

运行测试

UserDAOTest.java

单表查询

查询用户信息表中一条记录。

DAO接口

1
2
3
public interface UserDAO {
public User queryUser(String username);
}

映射文件

mybatis-config.xml
UserMapper.xml

运行测试

UserDAOTest.java

关联查询操作

在查询用户的同时关联查询出与之对应的详情。

实体

User.java Detail.java

方式一:连接查询

UserMapper.xml

方式二:子查询

DetailDAO.java
DetailMapper.xml
UserMapper.xml

运行测试

UserDAOTest.java

一对多关联

班级(1)————学生(n)。

数据表

1
2
3
4
5
6
-- 班级信息表
create table classes(
cid int primary key auto_increment,
cname varchar(30) not null unique,
cdesc varchar(100)
);
1
2
3
4
5
6
7
-- 学生信息表
create table students(
sid char(5) primary key,
sname varchar(20) not null,
sage int not null,
scid int not null
);

实体类

Clazz.Java Student.java

关联查询

当查询一个班级的时候, 要关联查询出这个班级下的所有学生。

方式一:连接查询

根据班级编号查询班级信息,同时查询这个班级下所有的学生信息。

DAO接口

1
2
3
public interface ClassDAO {
public Clazz queryClass(int classId);
}

映射文件

mybatis-config.xml
ClassMapper.xml

测试代码

ClassDAOTest.java

方式二:子查询

DAO接口

1
2
3
public interface StudentDAO {
public Student queryStudentByCid(int cid);
}

映射文件

StudentMapper.xml
mybatis-config.xml
ClassMapper.xml

测试代码

ClassDAOTest.java

多对一关联

学生(n)———— 班级(1)。

实体类

Student.java Clazz.java

关联查询

当查询一个学生的时候,关联查询这个学生所在的班级信息。

方式一:连接查询

根据学号查询学生信息,同时关联查询到这个学生所属的班级信息。

DAO接口

1
2
3
public interface StudentDAO {
public Student queryStudentBySid(String sid);
}

映射文件

StudentMapper.xml

测试代码

StudentDAOTest.java

方式二:子查询

DAO接口

1
2
3
public interface ClassDAO {
public Clazz queryClass(int classId);
}

映射文件

ClassMapper.xml
StudentMaper.xml

测试代码

StudentDAOTest.java

多对多关联

学生(m)<—————> 课程(n)。

1
2
3
4
5
-- 课程信息表
create table courses(
course_id int primary key auto_increment,
course_name varchar(50) not null
);
1
2
3
4
5
6
-- 选课信息表/成绩表(学号、课程号、成绩)
create table grades(
sid char(5) not null,
cid int not null,
score int not null
);

课程n>>>学生m

根据课程编号查询课程时,同时查询选择了这门课程的学生。

实体

Student.java Course.java

方法一:连接查询

DAO接口

1
2
3
public interface CourseDAO {
public Course queryCourseById(int courseId);
}

映射文件

CourseMapper.xml

测试代码

CourseDAOTest.java

方法二:子查询

DAO接口

1
2
3
public interface StudentDAO {
public Student queryStudentByCourseId(int courseId);
}

映射文件

StudentMapper.xml
CourseMapper.xml

测试代码

CourseDAOTest.java

课程m>>>学生n

查询学生时,同时查询学生选择的课程。

实体

Student.java Course.java

步骤与上面根据课程编号查学生信息类似,只是换了一个角度。