实际的开发中,对数据库的操作常常会涉及到多张表,这在面向对象中就涉及到了对象与对象之间的关联关系。

针对多表之间的操作,MyBatis提供了关联映射,通过关联映射就可以很好的处理对象与对象之间的关联关系。

你需要了解的知识点

1、关联关系种类

数据库:

在关系型数据库中,多表之间存在着三种关联关系,分别为一对一一对多多对多

  1. 一对一:在任意一方引入对方主键作为外键;
  2. 一对多:在“多”的一方,添加“一”的一方的主键作为外键;
  3. 多对多:产生中间关系表,引入两张表的主键作为外键,两个主键成为联合主键或使用新的字段作为主键。

java

  1. 一对一:在本类中定义对方类型的对象,如A类中定义B类类型的属性b,B类中定义A类类型的属性a;(双向一对一)

  2. 一对多:一个A类类型对应多个B类类型的情况,需要在A类中以集合的方式引入B类类型的对象,在B类中定义A类类型的属性a;

  3. 多对多:在A类中定义B类类型的集合,在B类中定义A类类型的集合。

2、关联查询方式

MyBatis加载关联关系对象主要通过两种方式:嵌套查询嵌套结果

使用



项目目录如图,其中红色标注的为本次所需要的,本次主要讲解一对多关系映射,如果你对mybatis的xml版不熟悉的话请前往

数据层框架应用--Mybatis(一) 基于XML映射文件实现数据的CRUD

1、创建实体类

创建实体类:在com.lomtom.mybaris.entity包中创建实体类AdminDetail.javaAdminInfo.java

1、AdminDetail.java
/**
* @Author: LOMTOM
* @Date: 2020/4/26
* @Time: 16:43
* @Email: lomtom@qq.com
*/
@Data
public class AdminInfo {
private int id; private String name; private String pwd; private AdminDetail ad; public AdminInfo() {
} public AdminInfo(String name, String pwd) {
this.name = name;
this.pwd = pwd;
}
} 2、AdminInfo.java
/**
* @Author: LOMTOM
* @Date: 2020/4/26
* @Time: 16:42
* @Email: lomtom@qq.com
*/
@Data
public class AdminDetail {
private int id; private String address; private String realName; public AdminDetail() {
} public AdminDetail(String address, String realName) {
this.address = address;
this.realName = realName;
}
}

2、创建SQL映射的XML文件

com.lomtom.mybaris.mapper包中创建SQL映射的XML文件adminDetailMapper.xmladminInfoMapper.xml

  • 配置<insert>元素向数据表中插入记录。
  • 配置<select>元素向数据表中插入记录。
1、adminDetailMapper.xml
<mapper namespace="com.lomtom.mybatis.mapper.adminDetailMapper">
<insert id="addAdminDetail" parameterType="AdminDetail"
keyProperty="id" useGeneratedKeys="true">
insert into admin_detail(address ,realName) values (#{address},#{realName})
</insert>
</mapper> 2、adminInfoMapper.xml
<mapper namespace="com.lomtom.mybatis.mapper.adminInfoMapper">
<insert id="addAdminInfo" parameterType="AdminInfo">
insert into admin_info(id, name, pwd) values( #{ad.id}, #{name}, #{pwd})
</insert> <select id="getAdminInfo" parameterType="int" resultMap="getAdminInfoMap">
select ai.id, name, pwd, address, realName from admin_info ai, admin_detail ad where ai.id=ad.id and ai.id=#{id}
</select>
<!--嵌套结果映射,最后返回的结果,见 select元素的 resultMap属性-->
<resultMap type="com.lomtom.mybatis.entity.AdminInfo" id="getAdminInfoMap">
<id property="id" column="id" />
<result property="name" column="name"/>
<result property="pwd" column="pwd"/>
<association property="ad" javaType="com.lomtom.mybatis.entity.AdminDetail">
<id property="id" column="id"/>
<result property="address" column="address"/>
<result property="realName" column="realName"/>
</association>
</resultMap> <select id="getAdminInfo2" parameterType="int"
resultMap="getAdminInfo2Map">
select * from admin_info where id=#{id}
</select>
<select id="getAdminDetail" parameterType="int" resultType="AdminDetail">
select * from admin_detail where id=#{id}
</select>
<resultMap type="AdminInfo" id="getAdminInfo2Map">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="pwd" column="pwd"/>
<association property="ad" column="id" select="getAdminDetail"/>
</resultMap>
</mapper>

其中,插入keyProperty="id" useGeneratedKeys="true"实现自增,以上有两种查询方式分别为嵌套查询与嵌套结果

3、注册SQL映射的XML文件

在XML配置文件mybatis-config.xml中注册adminDetailMapper.xmladminInfoMapper.xml。

    <mappers>
<mapper resource="com/lomtom/mybatis/mapper/adminDetailMapper.xml"/>
<mapper resource="com/lomtom/mybatis/mapper/adminInfoMapper.xml"/>
</mappers>

4、创建表格

创建两个表admin_detail和admin_info,注意两个表之间的依赖关系,可以先创建好两个表,在关联两个表

1、admin_detail
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0; -- ----------------------------
-- Table structure for admin_detail
-- ----------------------------
DROP TABLE IF EXISTS `admin_detail`;
CREATE TABLE `admin_detail` (
`id` int(0) NOT NULL AUTO_INCREMENT,
`address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`realName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1; 2、admin_info
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0; -- ----------------------------
-- Table structure for admin_info
-- ----------------------------
DROP TABLE IF EXISTS `admin_info`;
CREATE TABLE `admin_info` (
`id` int(0) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`pwd` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
CONSTRAINT `admin_info_ibfk_1` FOREIGN KEY (`id`) REFERENCES `admin_detail` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1;

5、测试一对一关联映射

在测试类里加入以下,用于测试我们刚刚写的插入与查询

    @Test
public void testAddAdminInfo() {
SqlSession sqlSession= MybatisUtils.getSession();
//创建 AdminDetail对象
AdminDetail adminDetail = new AdminDetail("湖南长沙", "杨二蛋子");
//创建 AdminInfo对象
AdminInfo adminInfo = new AdminInfo("杨二蛋子", "123456");
//向数据表 admin_detail插入记录
sqlSession.insert("addAdminDetail", adminDetail);
//设置 AdminInfo对象关联的 AdminDetail对象
adminInfo.setAd(adminDetail);
//向数据表 admin_info插入记录
sqlSession.insert("addAdminInfo", adminInfo);
sqlSession.commit();
sqlSession.close();
} @Test
public void testGetAdminInfoById(){
SqlSession sqlSession= MybatisUtils.getSession();
AdminInfo adminInfo = sqlSession.selectOne("getAdminInfo",4);
System.out.println(adminInfo);
sqlSession.commit();
sqlSession.close();
} @Test
public void testGetAdminInfoById2(){
SqlSession sqlSession= MybatisUtils.getSession();
AdminInfo adminInfo = sqlSession.selectOne("getAdminInfo2",4);
System.out.println(adminInfo);
sqlSession.commit();
sqlSession.close();
}

你可能会出现的问题

问题一:提示缺少构造函数

描述:

Cause: org.apache.ibatis.executor.ExecutorException: No constructor found in com.lomtom.mybatis.entity.AdminInfo matching [java.lang.Integer, java.lang.String, java.lang.String, java.lang.String, java.lang.String]

分析:我们明明使用了lombok,为啥还会提示缺少构造函数,那是因为我们这里使用复杂的bean,lombok自己识别不出来

解决:AdminDetail.javaAdminInfo.java创造空的构造函数

写在最后

关注公众号:博奥思园 ,精彩内容不错失

你的支持是作者最大的动力

【mybatis xml】数据层框架应用--Mybatis(三)关系映射之一对一关系映射的更多相关文章

  1. 【mybatis xml】数据层框架应用--Mybatis 基于XML映射文件实现数据的CRUD

    使用MyBatis框架进行持久层开发 MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架. MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索. MyBa ...

  2. 【mybatis annotation】数据层框架应用--Mybatis(二) 基于注解实现数据的CRUD

    使用MyBatis框架进行持久层开发 MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架. MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索. MyBa ...

  3. 闭关修炼180天--手写持久层框架(mybatis简易版)

    闭关修炼180天--手写持久层框架(mybatis简易版) 抛砖引玉 首先先看一段传统的JDBC编码的代码实现: //传统的JDBC实现 public static void main(String[ ...

  4. int不可为null引发的 MyBatis做持久层框架,返回值类型要为Integer问题

    MyBatis做持久层框架,返回值类型要为Integer MyBatis 做持久层时,之前没注意,有时候为了偷懒使用了int类型做为返回的类型,这样是不可取的,MyBatis做持久层框架,返回值类型要 ...

  5. JAVA 利用反射自定义数据层框架

    之前的随笔一直都在介绍c#,主要公司最近的业务都是做桌面程序,那么目前c#中的WPF肯定是我做桌面程序的不二之选,做了半年的WPF,也基本摸清了c#写代码的套路和规则(本人之前是两年多的JAVA开发者 ...

  6. 持久层框架之MyBatis

    1.mybatis框架介绍: MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并 ...

  7. 持久层框架:MyBatis 3.2(1)

    MyBatis 的前身就是 iBatis .是一个数据持久层(ORM)框架. iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架.iBATIS提供的持久 ...

  8. Java 持久层框架之 MyBatis

    MyBatis 简介 MyBatis 是一个基于 Java 的持久层框架,它内部封装了 JDBC,使开发者只需关注 SQL 语句本身,而不用再花费精力去处理诸如注册驱动.创建 Connection.配 ...

  9. CYQ.Data 开源数据层框架 官方下载

    CYQData 数据框架 介绍: CYQ.Data 是一款操作数据库用的数据框架:安全稳定.简洁易用.功能强大.性能优越.内置支持多数据库.多语言.RSS.AOP.事务等功能. 使用本框架进行开发,入 ...

随机推荐

  1. Fastdfs文件系统扩容

    1.简介     FastDFS文件服务器在设计时,为了支持大容量,存储节点(服务器)采用了分卷(或分组)的组织方式.存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是 ...

  2. 2017蓝桥杯取位数(C++B组)

    题目: 标题:取数位求1个整数的第k位数字有很多种方法.以下的方法就是一种.// 求x用10进制表示时的数位长度 int len(int x){ if(x<10) return 1; retur ...

  3. intelij idea 和 eclipse 使用上的区别

    一.项目创建区别 使用基于IntelliJ的IDE,都会对project和module的关系比较糊涂.用简单的一句话来概括是: IntelliJ系中的Project相当于Eclipse系中的works ...

  4. foreach-- for循环的增强型:for(类型 变量 : 数组对象) { 使用变量 }

    /* * foreach:增强for循环,一般用于遍历集合或者数组 * 格式: * for(元素的类型 变量 : 集合或者数组对象) { * 可以直接使用变量; * } 注意:在增强for循环中不能修 ...

  5. Js异步机制的实现

    Js异步机制 JavaScript是一门单线程语言,所谓单线程,就是指一次只能完成一件任务,如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推.这种模式的好处是实现起来比较简单 ...

  6. 数据结构和算法(Golang实现)(19)排序算法-冒泡排序

    冒泡排序 冒泡排序是大多数人学的第一种排序算法,在面试中,也是问的最多的一种,有时候还要求手写排序代码,因为比较简单. 冒泡排序属于交换类的排序算法. 一.算法介绍 现在有一堆乱序的数,比如:5 9 ...

  7. C# 基础知识系列- 10 反射和泛型(二)

    0. 前言 这篇文章延续<C# 基础知识系列- 5 反射和泛型>,继续介绍C#在反射所开发的功能和做的努力.上一篇文章大概介绍了一下泛型和反射的一些基本内容,主要是通过获取对象的类型,然后 ...

  8. ES5和ES6基本介绍与面向对象的基本思想

    ES6和ES5基本介绍 let  const  关键词定义变量 let 定义变量 特点: let 定义的变量,不会进行预解析  let 定义的变量,与 forEach() 中的变量类似  每次执行都会 ...

  9. react性能优化最佳实践

    1.PureComponent 的使用场景 PureComponent 和 Component 的区别是,PureComponent 自带 shouldComponentUpdate 生命周期函数,会 ...

  10. 惊呆了,Servlet Filter和Spring MVC Interceptor的实现居然这么简单

    前言 创建型:单例模式,工厂模式,建造者模式,原型模式 结构型:桥接模式,代理模式,装饰器模式,适配器模式,门面模式,组合模式,享元模式 行为型:观察者模式,模板模式,策略模式,责任链模式,状态模式, ...