Mybatis-技术专区-如何清晰的解决出现「多对一模型」和「一对多模型」的问题
前提介绍
在mybatis如何进行多对一、一对多(一对一)的多表查询呢?本章带你认识如何非常顺滑的解决!
基础使用篇
一对一
association
association通常用来映射一对一的关系,例如,有个类user,对应的实体类如下:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Student {
private int id;
private String name;
/**
* 学生要关联一个老师
*/
private Teacher teacher;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Teacher {
private int id;
private String name;
}
Dao层进行Mapper查询操作
public interface TeacherMapper {
Teacher getTeacher(@Param("tid") int id);
Teacher getTeacher2(@Param("tid") int id);
}
Dao层进行Mapper.xml文件
<resultMap id="StudentTeacher" type="com.sunreal.pojo.Student">
<result column="id" property="id"></result>
<result column="name" property="name"></result>
<association property="teacher" column="id" javaType="com.sunreal.pojo.Teacher" select="getTeacher"/>
</resultMap>
<select id="getStudent" resultMap="StudentTeacher">
select *
from student
</select>
<select id="getTeacher" resultType="com.sunreal.pojo.Teacher">
select *
from teacher
where id = #{id}
</select>
<resultMap id="StudentTeacher2" type="com.sunreal.pojo.Student">
<result column="sid" property="id"></result>
<result column="sname" property="name"></result>
<association property="teacher" javaType="com.sunreal.pojo.Teacher">
<result property="name" column="tname"></result>
</association>
</resultMap>
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid, s.name sname, t.name tname
from student s,
teacher t
where s.tid = t.id
</select>
- assocication:可以指定联合的JavaBean对象
- select:指定相关查询结果sqlid
- property="role“:指定哪个属性是联合的对象
- javaType:指定这个属性对象的类型
- column="{javabean熟悉=数据库字段,Javabean属性=数据库字段}"
<association property="role" javaType="com.queen.mybatis.bean.Role">
<id column="role_id" property="id"/>
<result column="roleName" property="roleName"/>
</association>
以上如果跨越命名空间的情况下:select:需要用namespace.selectId进行指定。
collection
@Alias("Student")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Student {
private int id;
private String name;
private int tid;
}
@Alias("Teacher")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Teacher {
private int id;
private String name;
/**
* 一个老师包含多个学生
*/
private List<Student> studentList;
}
Dao层进行Mapper查询操作
public interface TeacherMapper {
Teacher getTeacher(@Param("tid") int id);
Teacher getTeacher2(@Param("tid") int id);
}
Dao层进行Mapper.xml文件
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"></result>
<result property="name" column="tname"></result>
<collection property="studentList" ofType="Student">
<result property="id" column="sid"></result>
<result property="name" column="sname"></result>
<result property="tid" column="tid"></result>
</collection>
</resultMap>
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid, s.name sname, t.name name, t.id tid
from student s,
teacher t
where s.tid = t.id
and t.id = #{tid}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<collection property="studentList" javaType="ArrayList" ofType="Student"
select="getStudentByTeacherId" column="id"/>
</resultMap>
<select id="getTeacher2" resultMap="TeacherStudent2">
select *
from teacher
where id = #{tid}
</select>
<select id="getStudentByTeacherId" resultType="Student">
select *
from student
where tid = #{tid}
</select>
注意:各个表之间尽量不要有重名字段,包括主键id,不然可能会造成数据混乱错误;
- JavaType和ofType都是用来指定对象类型的
- property="指的是对象内部(List类型)的属性信息字段名称"
- JavaType是用来指定pojo中属性的类型
- ofType指定的是映射到list集合属性中pojo的类型。
- column="{javabean熟悉=数据库字段,Javabean属性=数据库字段}"
- select:指定相关查询结果sqlid
”特叔“使用篇
一对一映射
实体列 class Tb_blog/TbBlog
private long blogId;
private String blogTitle;
private String blogContent;
private Date createTime;
private String blogType;
private String sId;
private Tb_author author;
List<TbAuthor> tbAuthorList;
实体类 class TbAuthor
private long id;
private String username;
private String password;
private String email;
private String address;
private String phone;
private TbBlog tbBlog;
private List<TbBlog> tbBlogList;
resultMap标签配置
<resultMap id="blogMap" type="Tb_blog" >
<id column="blogId" property="blogId"/>
<result column="blogTitle" property="blogTitle"/>
<result column="blogContent" property="blogContent"/>
<result column="blogType" property="blogType"/>
<result column="createTime" property="createTime"/>
<result column="sId" property="sId"/>
<result column="id" property="author.id"/> <!-- 映射第二张表的实体类属性 -->
<result column="username" property="author.username"/>
<result column="password" property="author.password"/>
<result column="email" property="author.email"/>
</resultMap>
<select id="selectBlogAndAuthor" resultMap="blogMap">
select * from tb_blog g inner join tb_author r
on g.blogId = r.id
</select>
在sql加入别名alias与field属性字段一样,也可以自动注入进入。
association标签配置
<resultMap id="blogMap" type="Tb_blog" >
<id column="blogId" property="blogId"/>
<result column="blogTitle" property="blogTitle"/>
<result column="blogContent" property="blogContent"/>
<result column="blogType" property="blogType"/>
<result column="createTime" property="createTime"/>
<!-- 一对一高效率写法 association一对一关联 property属性为实体类中的第二张表的属性名 -->
<association property="tb_author" javaType="TbAuthor"><!--javaType属性为 返回的实体类对象 -->
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="email" property="email"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="selectBlogAndAuthor" resultMap="blogMap">
select * from tb_blog g inner join tb_author r on g.blogId = r.id
</select>
collection标签配置
mapper接口定义
AuthorMapper.interface
//!通过id 和映射文件中 association的column属性的值sId关联 来嵌套查询 嵌套查询的第二条sql语句都要写条件来关联第一张表
List<TbAuthor> selectAuthorandBlogAssociation(int id);
BlogMapper.interface
List<TbBlog> selectBlogAndAuthorAssociation();
AuthorMapper.xml
<select id="selectAuthorandBlogAssociation" resultType="com.xqh.pojo.TbAuthor">
select * from tb_author where id=#{id}
</select>
<resultMap id="mapCollection" type="TbAuthor">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<result property="email" column="email"/>
<result property="phone" column="phone"/>
<result property="address" column="address"/>
<collection property="tbBlogList" column="id"
select="com.xqh.mapper.BlogMapper.selectBlogAndAuthor"
fetchType="lazy">
</collection>
</resultMap>
<select id="selectAuthor_BlogList" resultMap="mapCollection">
select * from tb_author
</select>
BlogMapper.xml
<select id="selectBlogAndAuthor" resultType="com.xqh.pojo.TbBlog">
select * from tb_blog where sId = #{id}
</select>
总结
多表查询一对一映射
association标签
不嵌套 property=当前实体类中的第二种表的属性名 javaType=返回的实体类
嵌套 多加两个属性 column=当前实体类 关联的 第二张表 的外键字段 select=“第二条查询语句” (必须给第二条sql语句写参数限制 不然会获得所有值)
多表查询一对多
collection标签
不嵌套 property=当前实体类中的第二种表的属性名 ofType=返回是实体类
property=当前实体类中的第二种表的属性名 javaType=返回的实体类
嵌套 多加两个属性 column=当前实体类 关联的 第二张表 的外键字段 select=“第二条查询语句” (必须给第二条sql语句写参数限制 不然会获得所有值)
2.多表查询一对多
collection标签
不嵌套 property=当前实体类中的第二种表的属性名 ofType=返回是实体类
嵌套 多加一个属性 column=当前实体类 关联的 第二张表 的外键字段 select=“第二条查询语句” (必须给第二条sql语句写参数限制 不然会获得所有值) [ofType = collection一对多嵌套查询 嵌套查询所有结果 不需写返回类型因为 select已经映射]
Mybatis-技术专区-如何清晰的解决出现「多对一模型」和「一对多模型」的问题的更多相关文章
- 深入理解Mybatis技术与原理
目录 第1章 Mybatis简介 1.1 传统的JDBC编程 1.2 ORM模型 1.4 MyBatis 1.5 什么时候用MyBatis 第2章 MyBatis入门 2.2 MyBatis构成 2. ...
- 2017.2.9 深入浅出MyBatis技术原理与实践-第八章 MyBatis-Spring(二)-----配置文件详解
深入浅出MyBatis技术原理与实践-第八章 MyBatis-Spring(二) ------配置文件详解 8.2 MyBatis-Spring应用 8.2.1 概述 本文主要讲述通过注解配置MyBa ...
- Mybatis 关联对象不能输出的解决办法
Mybatis 关联对象不能输出的解决办法 1.如图所示,现在进行查询的时候并没有得到来自另一张表address项 2.我们进行如下配置: (1).在mybatis-config.xml 文件中配置, ...
- Mybatis技术内幕(一)——整体架构概览
Mybatis技术内幕(一)--整体架构概览 Mybatis的整体架构分为三层,分别是基础支持层.核心处理层和接口层. 如图所示: 一.基础支持层 基础支持层包含整个Mybatis的基础模块,这些模块 ...
- Mybatis技术原理理——整体流程理解
前言:2018年,是最杂乱的一年!所以你看我的博客,是不是很空! 网上有很多关于Mybatis原理介绍的博文,这里介绍两篇我个人很推荐的博文 Mybatis3.4.x技术内幕和 MyBaits源码分析 ...
- 微服务-技术专区-链路追踪(pinpoint)-部署使用
https://naver.github.io/pinpoint/ https://github.com/naver/pinpoint 背景 随着项目微服务的进行,微服务数量逐渐增加,服务间的调用也越 ...
- mybatis技术总结
一.框架概述 day1 1.什么是框架 框架是系统的可重用设计,是对J2EE底层技术的封装(JDBC,IO流,多线程,Servlet,Socket). 2.框架解决了哪些问题? 1.解决了技术整合问题 ...
- 2MyBatis入门--深入浅出MyBatis技术原理与实践(笔记)
什么是 MyBatis ? MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis ...
- 【MyBatis学习06】_parameter:解决There is no getter for property named in class java.lang.String
我们知道在mybatis的映射中传参数,只能传入一个.通过#{参数名} 即可获取传入的值. Mapper接口文件: public int delete(int id) throws Exception ...
随机推荐
- Spring,Spring-boot(一)
前言 Spring作为java开源世界第一开源框架,已经成为事实上的Java EE开发标准. 最根本的使命就是简化Java开发. 不重复制造车轮 Don't reinvent the wheel .从 ...
- webRTC的标准与发展
Web实时通信(WebRTC)是标准,协议和JavaScript API的集合,两者的组合可实现浏览器(对等)之间的对等音频,视频和数据共享.WebRTC无需依赖第三方插件或专有软件,而是将实时通信转 ...
- 使用策略者模式减少switch case 语句
策略者模式 很简单的一个定义:抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现. 场景 在这之前 ...
- vue中rem的转换
1 function rems(doc: any, win: any): void { 2 let docEl = doc.documentElement, 3 resizeEvt = 'orient ...
- postman怎么调中文
事先准备 1 安装好postman. 下载网址:https://www.postman.com/downloads/ 2 下载好app.zip中文压缩包,下载地址:https://wws.lanzou ...
- windows本地挂载HDFS
1.修改配置文件 进入配置文件目录: cd ${HADOOP_HOME}/etc/hadoop 修改core-site.xml: vim core-site.xml 在文件中增加以下内容: <p ...
- 关于协议栈XDATA,内存溢出的小结
[第二部分的内容仅供参考,自己不是十分确定] ************************************************************** ************** ...
- myvimrc
set nocompatible execute pathogen#infect() call pathogen#helptags() call pathogen#incubate() imap jk ...
- SpringMVC学习04(数据处理及跳转)
4.数据处理及跳转 4.1结果跳转方式 4.1.1 ModelAndView 设置ModelAndView对象 , 根据view的名称 , 和视图解析器跳到指定的页面 . 页面 : {视图解析器前缀} ...
- Apache虚拟web主机构建
目录 一.构建虚拟web主机 1.1.虚拟web主机概述 二.搭建虚拟web主机步骤 2.1.基于域名搭建虚拟主机 ①为虚拟主机提供域名解析 ②为虚拟主机准备网页文档 ③添加虚拟主机配置 ④设置访问路 ...