MyBatis -- 结果集映射
一。字段映射
比如有张数据表结构如下:
在后台的JavaBean中,如果遵守规范的话,属性名和列名一致,那么我们就不需要手动做字段映射,MyBatis会自动帮我们把值填充到Bean中。但现在情况不一样,Bean的属性名和数据库列名对应不上。
import java.util.ArrayList;
import java.util.List;
public class Grade {
private String gradeId; // 班级ID
private String gName; // 班级名
private List<Student> stuList = new ArrayList<Student>(); // 班级中的学生
public String getGradeId() {
return gradeId;
}
public void setGradeId(String gradeId) {
this.gradeId = gradeId;
}
public String getgName() {
return gName;
}
public void setgName(String gName) {
this.gName = gName;
}
public List<Student> getStuList() {
return stuList;
}
public void setStuList(List<Student> stuList) {
this.stuList = stuList;
}
@Override
public String toString() {
return "Grade [gradeId=" + gradeId + ", gName=" + gName + ", stuList="
+ stuList + "]";
}
}
gradeId和GID明显对应不上,但是修改列或者属性名是不可取的,原因不多说。我们可以通过MyBatis的字段映射在不修改代码的情况下完成这个需求,给它俩建立一种映射关系:
字段映射,当数据库的列名和类的属性名不一致时,需要通过建立映射关系使得它俩对应上。
返回的结果都是grade(自己取的typeAliases),只是多了一层映射关系。
<resultMap type="grade" id="mappingGid">
<!-- 主键列用id标签 -->
<id property="gradeId" column="GID"/>
<!--
非主键就用result:
<result property="gName" column="gname"/> -
->
</resultMap>
<select id="queryAll" resultType="grade" resultMap="mappingGid">
select * from grade
</select>
restltMap属性指向上边定义的resultMap的id即可。resultMap标签还有个autoMapping属性,意思是自动映射,默认值是true,改成false的话就要手动指定需要建立映射关系的列以及属性了。
二。多对一(many to one) 映射
表关系:
grade表:GID、GNAME
student表:SID、SNAME、GID
GID是关联grade表的外键。
多对一的视角:student --> grade。多个学生对应一个grade,一个学生只能有一个grade。
在设计Bean的时候,应该是这样的:
public class Student {
private String sId;
private String sName;
private Grade grade;
public String getsId() {
return sId;
}
public void setsId(String sId) {
this.sId = sId;
}
public String getsName() {
return sName;
}
public void setsName(String sName) {
this.sName = sName;
}
public Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student [sId=" + sId + ", sName=" + sName + ", grade=" + grade
+ "]";
}
}
包含一个grade属性,在查询到学生信息的同时把对应的班级查出来并填充进去。当然用Java代码编写逻辑也是完全能够实现的,但是有了MyBatis的结果集映射,我们并不需要编写这样的逻辑。确定好是一对多关系后,在映射文件中声明映射关系。下面就把这个例子的代码都贴上来吧:
Student映射接口:
import java.util.List;
import cn.et.lesson03.entity.Student;
public interface StudentMapper {
<!-- 映射多对一关系 -->
<resultMap type="student" id="mappingGrade">
<association property="grade" column="gid" select="cn.et.lesson03.xml.GradeMapper.queryGradeByGid"></association>
</resultMap>
/* 根据ID查询学生 */ public Student queryStuById(String sId); /*根据班级ID查询学生*/ public List<Student> queryStusByGId(String gId);}
现在要调用queryStuById,返回一个student的同时,把这个student的grade属性填充进去,也就是说还需要一个 select * from grade where gid = x 这么一条SQL语句,定义在grade类对应的映射文件中:
<select id="queryGradeByGid" resultType="grade">
select * from grade where GID = #{gid}
</select>
然后在Student类的映射文件中建立映射关系:
<!-- 映射多对一关系 -->
<resultMap type="student" id="mappingGrade">
<association property="grade" column="gid" select="cn.et.lesson03.xml.GradeMapper.queryGradeByGid"></association>
</resultMap>
type = 查询返回结果
id = 映射命名
association = 声明是多对一映射。
property="grade" 需要填充的属性
column="gid" 外键列
select= 获取对应的grade数据行的SQL语句,上上边那个,语法格式:命名空间.声明。
映射接口中方法的SQL语句:
<select id="queryStuById" resultType="student" resultMap="mappingGrade">
select * from student where SID = #{0}
</select>
测试方法:
@Test
public void mappingGrade() throws IOException{
SqlSession session = getSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
Student student = mapper.queryStuById("1");
System.out.println(student.getGrade());
}
结果:
流程:
调用方法 --> 执行接口映射方法之前先执行resultMap -->
通过association中的column外键,执行association对应的SQL语句获取结果集,填充到
property --> resultMap结束 --> 执行方法对应的SQL语句返回最终结果。
三。一对多映射(one to many)
一对多映射很简单,一个班级对应多个学生,查询一个班级的同时获取班级中的所有学生,填充到stuList属性中:
把上面的例子反过来想就OK了。班级和学生在数据库中的关系是主外键关联,通过grade表的主键到student表查询,需要一个这个的语句:select * from student where GID = #{gid}。
这个语句在Student的映射文件中定义:
<select id="queryStusByGId" resultType="student">
select * from student where GID = #{gid}
</select>
然后在Grade的映射文件中,定义结果集映射:
<resultMap type="grade" id="mappingStuList">
<collection property="stuList" javaType="arraylist" column="gid" select="cn.et.lesson03.xml.StudentMapper.queryStusByGId"></collection>
</resultMap>
一对多关系用collection表示。
property = 要填充的属性
javaType = 该属性的数据类型
column = 主键,studen表的外键
select = student映射文件中的语句: select * from student where GID = #{gid}
测试方法:
@Testpublic void queryStu() throws IOException {
SqlSession session = getSession();
GradeMapper mapper = session.getMapper(GradeMapper.class);
Grade grade = mapper.queryGradeById("1");
List<Student> list = grade.getStuList();
for (Student student : list) {
System.out.println(student.getsId() + "---" + student.getsName());
}
}
运行结果:
四。基于注解实现的结果集映射
字段映射:
@Results({
@Result(column="SID" , property = "stuId" , id = true)})
@Select("select * from student where sid = #{sId}")
public Student queryStuById(String sId);
多对一映射:
@Results({
@Result(column = "SID", property = "stuId", id = true),
@Result(property = "grade", column = "GID",
one = @One(select = "cn.et.lesson03.anno.GradeMapper.queryGradeById")) })
@Select("select * from student where sid = #{sId}")
public Student queryStuById(@Param("sId") String sId);
one表示多对一映射,多个学生属于一个grade,指向的方法也是一个grade:
@Select("select * from grade where GID = #{0}")
public Grade queryGradeById(String gId);
一对多映射:
指向的方法返回值是个list,所以还要在映射声明中指定一下javaType。
@Results({
@Result(column = "GID", property = "stuList", javaType = ArrayList.class,
many = @Many(select = "cn.et.lesson03.anno.StudentMapper.queryStusByGId")) })
@Select("select * from grade where GID = #{0}")
public Grade queryGradeById(String gId);
一对多用many表示,因为查询结果是多条,指向方法:
@Results({
@Result(column = "SID" , property = "stuId")})
@Select("select * from student where GID = #{param1}")
public List<Student> queryStusByGId(String gId);
MyBatis -- 结果集映射相关推荐
- Mybatis结果集映射
一.使用场景 当数据库里的列名和实体类的属性名不一致,就需要进行结果映射 二.UserMapper接口 package com.william.dao;import com.william.domai ...
- 一文彻底读懂优秀开源产品MyBatis一级缓存设计!
孙玄 奈学教育CEO 读完需要 3 分钟 速读仅需 1 分钟 孙玄, 现任奈学教育科技创始人&CEO ,毕业于浙大,前百度资深研发工程师.前 58 集团技术委员会主席/高级系统架构师到前转转公 ...
- Mybatis为什么查询结果为空时返回值为NULL或空集合?
以下内容如有错误欢迎指出,有则改之无则加勉~ 一行数据记录如何映射成一个 Java 对象,这种映射机制是 MyBatis 作为 ORM 框架的核心功能之一,也是我们这篇文章需要学习的内容 开始前我们先 ...
- mybatis多对一映射association详解
简单映射(一对一) 多对一映射 方式1:按照查询嵌套处理 方式2:按照结果嵌套处理 简单映射(一对一) mybatis结果集映射ResultMap 多对一映射 我们有2个类,一个班级类ClassRoo ...
- mybatis学习2之ResultMap结果集映射
前言 当实体类的属性和数据库的字段无法对应时我们改怎么办呢? 这里我们一起来学习ResultMap结果映射集 1.ResultMap是什么? resultMap元素用来描述如何将结果集映射到Java对 ...
- Mybatis 一对多 结果集映射 简单入门 易懂
Mybatis官方文档说明处 Mybatis 一对多 结果集映射 简单入门 易懂 一.搭建数据库环境 二.idea 搭建maven 项目 (mybatis-demo) 2.1.项目结构 2.2.导入依 ...
- [mybatis]select_resultMap_自定义结果集映射规则
resultMap 自定义某个javaBean的封装规则 type:自定义规则的Java类型 id:唯一id方便引用 指定主键列的封装规则 id:定义主键底层会有优化 column:指定哪一列 pro ...
- Mybatis源码阅读(三):结果集映射3.1 —— ResultSetBuilder与简单映射
*************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 如 ...
- Java-Mybatis(二): Mybatis配置解析、resultMap结果集映射、日志、分页、注解开发、Mybatis执行流程分析
Java-Mybatis-02 学习视频:B站 狂神说Java – https://www.bilibili.com/video/BV1NE411Q7Nx 学习资料:mybatis 参考文档 – ht ...
最新文章
- java新手笔记1 Hello World!
- centos7安装tensorflow_gpu完整教程
- SpringBoot2.1+SpringCloud:注册中心搭建(Eureka)
- GitHub Pages搭建属于自己的静态网站,并绑定个人域名
- 在保护继承中基类的共有成员_C++学习大纲:继承方式的调整
- Net Core下使用RabbitMQ比较完备两种方案(虽然代码有点惨淡,不过我会完善)
- 解决nginx无法启动的问题——端口被占用
- navicat无法连接mysql
- 2020年java最新招聘_2021年北京Java 工程师招聘-北京Java 工程师招聘求职信息-拉勾招聘...
- javascript绘制静态或者动态的图表、关系表、流程图-JointJS
- Atiit 如何手写词法解析器
- Ubuntu下 VS code安装并配置C/C++模块
- html+css基础教程入门学习之CSS表格
- 【ACM】心路历程2019.9.29
- redmi Note12T屏幕刷新率是多少 Redmi Note12T相机怎么样 有几个摄像头
- 【ZYNQ】中断机制介绍(一)
- UKF-协方差矩阵分解
- 批量分析中通快运单号物流,并查看是否签收
- 测试管理之--团队组建
- 如何重新设置苹果id密码_苹果ID密码忘记应该怎么做
热门文章
- 双机热备_什么是双机热备?
- AT串口抽象层的设计思路及代码实现
- java 转发上传文件_Java 发送http请求上传文件功能实例
- 64位指针膨胀 java_Java 程序优化知识笔记
- 知识图谱学习笔记-风控知识图谱设计
- 将单链表的每K个节点之间逆序
- 论文笔记 Traffic Data Reconstruction via Adaptive Spatial-Temporal Correlations
- 错误处理: pip install 时候 “Read timed out”
- 报错整理:ImportError: cannot import name ‘mean_absolute_percentage_error‘ from ‘sklearn.metrics‘
- Java高阶部分知识点汇总(一)- 成员变量与局部变量详讲