1. 数据库中实体之间的对应关系
- 一对一
例如:人和身份证 、一个人只能拥有一张身份证
- 一对多
例如: 学员拥有多本图书
- 多对多
例如:学员和老师 , 多对多会产生中间关系表、
2. 在mybatis中,上述三种关系分成了两大类
- 对一关联
- 对多关联
代码实现
2.1 环境搭建
1.新建数据库、四张表 (relation)
2.添加依赖 (mysql , mybatis , junit , lombok)
xml
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.11</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
3.新建实体类、BookBean、Card、Person、Student
java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BookBean {
private Integer bid ;
private String bname ;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Card {
private Integer cid;
private String cno;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private Integer pid ;
private String pname ;
private String address ;
//对一关联:一个人拥有一张身份证
private Card card ;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private Integer sid ;
private String sname ;
//一个学员拥有多本图书 : 一对多
private List<BookBean> bookBeanList;
}
4.新建mapper接口 PersonMapper、StudentMapper
java
public interface PersonMapper {
//查询所有的Person信息,每一个Person仅仅是自己的简单属性信息
List<Person> getPersonList();
//查询所有的Person信息,每一个Person不仅包含自己的简单属性信息也包含他拥有的身份证信息
List<Person> getPersonListWithCardInfo();
//查询所有的Person信息,每一个Person不仅包含自己的简单属性信息也包含他拥有的身份证信息
List<Person> getPersonListWithCardInfo2();
}
public interface StudentMapper {
List<Student> getStudentListWithBookBeanList();
}
5.在resources 目录下新建com.bottom.mybatis.mapper 目录,并新建两个mapper.xml文件
PersonMapper.xml
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bottom.mybatis.mapper.PersonMapper">
<select id="getPersonList" resultType="Person">
select * from t_person
</select>
<!-- 这种方式发现person中的三个字段能成功映射,但是card仍然是null -->
<!--
<select id="getPersonListWithCardInfo" resultType="Person">
select * from t_person t1 left join t_card t2 on t1.pid = t2.cid
</select>
-->
<select id="getPersonListWithCardInfo" resultMap="PersonResultMap">
select t1.* , t2.* from t_person t1 left join t_card t2 on t1.pid = t2.cid
</select>
<resultMap id="PersonResultMap" type="Person" autoMapping="true">
<id property="pid" column="pid"/>
<!-- 对一关联 -->
<association property="card" javaType="Card" autoMapping="true">
<id property="cid" column="cid"/>
</association>
</resultMap>
<select id="getPersonListWithCardInfo2" resultType="Person">
select t1.* , t2.cid as 'card.cid' , t2.cno as 'card.cno'
from t_person t1 left join t_card t2 on t1.pid = t2.cid
</select>
</mapper>
StudentMapper.xml
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bottom.mybatis.mapper.StudentMapper">
<select id="getStudentListWithBookBeanList" resultMap="StudentWithBookBeanListResultMap">
select * from t_student t1 left join t_bookbean t2 on t1.sid = t2.stuid
</select>
<resultMap id="StudentWithBookBeanListResultMap" type="Student" autoMapping="true">
<id property="sid" column="sid"/>
<!-- 对多关联 collection -->
<collection property="bookBeanList" ofType="BookBean" autoMapping="true">
<id property="bid" column="bid"/>
</collection>
</resultMap>
</mapper>
5.在 resources 目录下新建 mybatis-config.xml、logback.xml
logback.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
<logger name="com.bottom.mybatis" level="DEBUG" />
</configuration>
mybatis-config.xml
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="SLF4J"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<package name="com.bottom.mybatis.pojo"/>
</typeAliases>
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/relation"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.bottom.mybatis.mapper"/>
</mappers>
</configuration>
6.测试类测试
java
public class PersonMapperTest {
private SqlSession sqlSession;
private PersonMapper personMapper;
private StudentMapper studentMapper ;
@BeforeEach
public void setup() throws IOException {
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
sqlSession = sqlSessionFactory.openSession();
personMapper = sqlSession.getMapper(PersonMapper.class);
studentMapper = sqlSession.getMapper(StudentMapper.class);
}
@AfterEach
public void teardown() throws SQLException {
if(sqlSession!=null && !sqlSession.getConnection().isClosed()){
sqlSession.commit();
sqlSession.close();
}
}
@Test
public void test01(){
personMapper.getPersonList().forEach(System.out::println);
}
//1.演示对一关联
@Test
public void test02(){
personMapper.getPersonListWithCardInfo().forEach(System.out::println);
}
//2.演示对一关联的另一种解决方案
@Test
public void test03(){
personMapper.getPersonListWithCardInfo2().forEach(System.out::println);
}
//3.演示对多关联
@Test
public void test04(){
studentMapper.getStudentListWithBookBeanList().forEach(System.out::println);
}
}
2.2 具体关系分析
2.2.1 一对一
--------------------------------------------场景模拟----------------------------------------------
一个人只能拥有一张身份证
---------------------------------------------代码实现---------------------------------------------
2.2.2 一对
--------------------------------------------场景模拟----------------------------------------------
一个学生可以拥有多本书
---------------------------------------------代码实现---------------------------------------------
2.3 总结
MyBatis 的一对一关联和一对多关联是指在数据库表之间建立的关系。下面是对它们的简单总结:
一对一关联:
-
表示两个表之间的一对一关系,即一个表中的每行对应另一个表中的唯一一行。
-
通常通过外键来建立关联,一个表的主键作为另一个表的外键。
-
在 MyBatis 中,可以通过映射文件中的
association
或collection
元素来配置一对一关联。
一对多关联:
-
表示一个表中的每行可以对应另一个表中的多行。
-
常见的例子是一个主表和一个明细表之间的关系,如学生表和课程表。
-
在 MyBatis 中,可以使用
collection
元素来配置一对多关联,指定关联的列和映射的对象。
通过正确配置 MyBatis 的映射文件,可以在查询和操作数据时利用这些关联关系,方便地获取相关联的数据。这样可以提高数据操作的效率和准确性。