Mybatis 查询语句结果集总结
简单查询-resultType
数据准备
表 Student
字段 注释 SNO 学号 SNAME 学生名字 SSEX 性别 SBIRITHDAY 生日 CLASS 班级
create table TEST.STUDENT
(
SNO varchar(3) not null,
SNAME varchar(4) not null,
SSEX varchar(2) not null,
SBIRTHDAY datetime null,
CLASS varchar(5) null
)
public class Student {
private String SNO;
private String SNAME;
private String SSEX;
private Date SBIRTHDAY;
private String CLASS;
...
}
例子
按照返回数据类型大致分为基础数据类型,JavaBean 和 Map。其中虽然返回的结果行数有单条也有多条,对应的接口返回类型是集合或者单个对象,但是在 xml 映射文件中,resultType 的值是相同的。
指定字段-基础数据类型
接口类:
String querySingleStudent();
List queryAllStudent();
Mapper 文件:
SELECT SNAME FROM TEST.STUDENT LIMIT 1
SELECT SNAME FROM TEST.STUDENT
Map,一般为 hashMap
接口类:
Map queryStudentMap();
List> queryAllStudentMap();
Mapper 文件:
SELECT SNAME FROM TEST.STUDENT LIMIT 1
SELECT SNAME FROM TEST.STUDENT
其中:
hashmap 为简写,也可以使用 java.util.HashMap 全称
默认情况下,结果集中值为 null 时, 不会增加映射对象的 setter 方法, (map 对象时为 put)。该行为可以在 mybatis-config.xml 配置文件中设置 覆盖默认设定。
JavaBean
接口类:
Student querySingleStudentBean();
List queryAllStudentBean();
Mapper 文件:
SELECT SNAME FROM TEST.STUDENT LIMIT 1
SELECT SNAME FROM TEST.STUDENT
resultType="student" 为 Student.java 的别名,也可以是全限定名。别名在 mybatis-config.xml 配置文件中设置:
...
但是如果 JavaBean 文件很多,不想一个个指定,也可以使用 package 标签 设置mybatis自动扫描,别名即为类名的小写。
复杂查询 resultMap
对于一般的查询语句,resultType 足够了。对于多表查询等情况,就要请出 resultMap 了。
数据库字段和 java 数据类型映射关系
数据库字段类型 jdbcType 和 java 数据类型 并不是一一对应的关系,而且不同数据库类型也不尽相同。而 mybatis 将 TypeHandler 作为两者之间的映射关系。大部分情况下都是没有问题的,但是并非能覆盖所有的情况,特殊情况下可以使用 resultMap 自定义这种映射关系。
举个例子,数据库 LongVarchar 字段类型对应 java 中的 String 类型。但是在 DB2 数据库中,查询的 LongVarchar 类型的字段,在 mybatis 中被识别成 jdbcType 为 BLOB。有两种解决方法,第一种是在 SQL 中对该字段使用 CAST 转换为 VARCHAR(长度)类型。另一种是使用 resultMap:
...
标签中使用 resultMap 指定返回集合。注意 resultMap 和 resultType 不能同时使用
标签
id 和 select 标签指定映射关系
type 和 resultType 一样为返回类型的全限定名或者别名
autoMapping 自动映射关系,在这里目的只是修改一个字段,其他自动采用自动完成映射关系
标签
property 为 java 变量名
column 为数据库字段名
jdbcType 这里指定为 VARCHAR
id
字段的映射关系的标签即有,也有,在 mybatis 文档中指出不使用id,会造成性能下降,因此将主键字段使用 id 标签是推荐的做法。但是如果不存在主键呢,当你在 ResultMap 只提供了部分字段而不是全部字段,即使使用了 autoMapping 属性,那么 mybatis 会按照你提供的字段名进行去重。那么在使用 resultMap 的时候,最优选择是:
如果表存在主键,就使用id标签指定
如果表不存在主键,要么不配置字段的映射关系,使用 autoMapping 属性自动映射;或者不使用 autoMapping 将所有字段罗列。
多表关联查询
在 resultType 的例子中都只涉及到一张表,如果涉及多张表关联查询呢。我们可以简单的将所有列映射到 hashmap 的键值上。
但是 HashMap 不是一个很好的领域模型。 你的程序更可能会使用 JavaBean 或 POJO(Plain Old Java Objects,普通 Java 对象)作为领域模型。
因此这里均采用 JavaBean 作为领域模型。增加一个成绩表 Score
字段 注释 SNO 学号 CNO 课程编号 DEGREE 成绩
create table SCORE
(
SNO varchar(3) not null,
CNO varchar(5) not null,
DEGREE decimal(10, 1) not null
)
public class Score {
private String SNO;
private String CNO;
private Double DEGREE;
...
}
一对一关系
这里的一对多关系是两个表字段一一对应,一个学生的某门课的成绩是唯一确定的。 在一一对应的情况下要在 resultMap 中使用 标签。
在 Student.java 中增加字段 Score
private Score score;
public Score getScore() {
return score;
}
public void setScore(Score score) {
this.score = score;
}
有两种使用情况,第一种为嵌套查询,即前一个 SQL 查询结果集中的字段作为参数传递给下一个 SQL。第二种情况为嵌套结果集,即两个表做关联查询,将结果集映射到多个 JavaBean 文件。
嵌套查询
select SNO,SNAME
from test.STUDENT
select degree from test.SCORE
where sno = #{sno}
在标签中
property 指向了 Student.java 中新增的 score 字段。
column 指定了作为参数传递给下一个查询SQL的字段,需要注意的是对于传递单个字段的情况,mybatis 只是简单的将 #{参数} 替换为占位符 ?, 然后执行 resultSet.getString(columnName),没有进行参数匹配,因此第二个 SQL 中 #{} 中写任何字符都可以;如果需要传递多个字段,使用 column = " {prop1=col1,prop2=col2} ",这种情况下会以参数对象的形式来传递。
select 指定了下一个 SELECT 语句
另外需要注意的是这种嵌套查询对于大型结果集和列名并友好,存在 N+1 的问题,因为下一条 SQL 会执行 N 次去循环查询,使用关联查询更合适。再者也可以开启 mybatis 的懒查询功能,嵌套的 SQL 不是一口气顺序执行完,而是在使用的时候才会执行下一条 SQL。例如执行student.getScore().getSNO()才会执行queryScore的 SQL。默认情况下没有开启,需要在配置文件中设置
设置参数 描述 默认值 lazyLoadingEnabled 延迟加载的全局开关,特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态 false aggressiveLazyLoading 当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载 false (true in ≤3.4.1)
也可以在标签中设置 fetchType = “lazy” 开启懒加载,会覆盖全局的参数设置。
嵌套结果集
对于多表关联查询,一般在 SQL 中使用别名来避免字段名的重复。mybatis 要做的是将别名正确的映射到 JavaBean 属性上。
SELECT SNAME, SSEX, CLASS, ST.SNO, SC.SNO AS SC_SNO
FROM test.student st INNER JOIN test.score sc
ON st.sno = sc.sno
where CNO = '3-105';
通过设置标签指定了表列名和属性之间的映射关系。但这样如果字段很多,会需要一一指定,标签提供了columnPrefix属性,指定别名的前缀,这样可以重用resultMap
一对多关系
除了一对一的关系,还有一对多的关系,比如这里一个学生Student 对应多门课的成绩。 一对多对应的情况下要在 resultMap 中使用 标签。首先需要调整 JavaBean 文件中两个表之间的关系。
private List score;
public List getScore() {
return score;
}
public void setScore(List score) {
this.score = score;
}
以嵌套结果集为例
SELECT SNAME,SSEX,CLASS,ST.SNO,SC.SNO AS SC_SNO
FROM test.student st INNER JOIN test.score sc
ON st.sno = sc.sno
注意到相比 association 多了一个属性ofType,是用来表示 List 集合中的类型的。其他属性的用法同 association 是一样的。
Java高架构师、分布式架构、高可扩展、高性能、高并发、性能优化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分布式项目实战学习架构师视频免费学习加群:835638062 点击链接加入群聊【Java高级架构】:https://jq.qq.com/?_wv=1027&k=5S3kL3v

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
再有人问你synchronized是什么,就把这篇文章发给他。
在《深入理解Java虚拟机》中,有这样一段话: synchronized关键字在需要原子性、可见性和有序性这三种特性的时候都可以作为其中一种解决方案,看起来是“万能”的。的确,大部分并发控制操作都能使用synchronized来完成。 海明威在他的《午后之死》说过的:“冰山运动之雄伟壮观,是因为他只有八分之一在水面上。” 对于程序员来说,synchronized只是个关键字而已,用起来很简单。之所以我们可以在处理多线程问题时可以不用考虑太多,就是因为这个关键字帮我们屏蔽了很多细节。 那么,本文就围绕synchronized展开,主要介绍其用法、原理,以及如何提供原子性、可见性和有序性保障的等。 synchronized的用法 synchronized是Java提供的一个并发控制的关键字。主要有两种用法,分别是同步方法和同步代码块。 也就是说,synchronized既可以修饰方法也可以修饰代码块。代码如下: /** *@authorHollis18/08/04. */ publicclassSynchronizedDemo{ //同步方法 publicsynchronizedvoidd...
- 下一篇
Spring Cloud Turbine(集群监控)
简介: Turbine是聚合服务器发送事件流数据的一个工具,Hystrix的监控中,只能监控单个节点,实际生产中都为集群,因此可以通过Turbine来监控集群下Hystrix的metrics情况Turbine的github地址:https://github.com/Netflix/Turbine 使用场景 在复杂的分布式系统中,相同服务的结点经常需要部署上百甚至上千个,很多时候,运维人员希望能够把相同服务的节点状态以一个整体集群的形式展现出来,这样可以更好的把握整个系统的状态。 为此,Netflix又提供了一个开源项目Turbine来提供把多个hystrix.stream的内容聚合为一个数据源供Dashboard展示。 Turbine使用了Netflix的另一个开源项目Archaius来做配置文件的管理,其提供了非常强大的配置文件管理策略Archaius的https://github.com/Netflix/archaius 集成Spring Cloud Turbine 引入相关依赖,Turbine能够汇集监控信息,并将聚合后的信息提供给Hystrix Dashboard来集中展示和监...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8编译安装MySQL8.0.19
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Red5直播服务器,属于Java语言的直播服务器
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS6,CentOS7官方镜像安装Oracle11G
- MySQL8.0.19开启GTID主从同步CentOS8
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作