Mybatis查询语句结果集的总结大全

2025-05-29 0 68

简单查询-resulttype

数据准备

字段 注释
sno 学号
sname 学生名字
ssex 性别
sbirithday 生日
class 班级
?

1

2

3

4

5

6

7

8

9
<!--建表语句:-->

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

)

?

1

2

3

4

5

6

7

8

9

10

11
<!--bean 文件-->

public class student {

private string sno;

private string sname;

private string ssex;

private date sbirthday;

private string class;

<!--get 和 set 方法-->

...

}

例子

按照返回数据类型大致分为基础数据类型,javabean 和 map。其中虽然返回的结果行数有单条也有多条,对应的接口返回类型是集合或者单个对象,但是在 xml 映射文件中,resulttype 的值是相同的。

1、指定字段-基础数据类型

接口类:

?

1

2

3

4
<!--单条结果集-->

string querysinglestudent();

<!--多条结果集-->

list<string> queryallstudent();

mapper 文件:

?

1

2

3

4

5

6

7

8
<!--单条结果集-->

<select id="querysinglestudent" resulttype="string">

select sname from test.student limit 1

</select>

<!--多条结果集-->

<select id="queryallstudent" resulttype="string">

select sname from test.student

</select>

2、map,一般为 hashmap

接口类:

?

1

2

3

4

5

6

7

8

9

10

11

12

13
<!--单条结果集-->

map<string, object> querystudentmap();

<!--多条结果集-->

list<map<string, object>> queryallstudentmap();

复制代码mapper 文件:

<!--单条结果集-->

<select id="querystudentmap" resulttype="hashmap">

select sname from test.student limit 1

</select>

<!--多条结果集-->

<select id="queryallstudentmap" resulttype="hashmap">

select sname from test.student

</select>

其中:

  • hashmap 为简写,也可以使用 java.util.hashmap 全称
  • 默认情况下,结果集中值为 null 时, 不会增加映射对象的 setter 方法, (map 对象时为 put)。该行为可以在 mybatis-config.xml 配置文件中设置
    <setting name="callsettersonnulls" value="true"/> 覆盖默认设定。

3、javabean

接口类:

?

1

2

3

4
<!--单条结果集-->

student querysinglestudentbean();

<!--多条结果集-->

list<student> queryallstudentbean();

mapper 文件:

?

1

2

3

4

5

6

7

8
<!--单条结果集-->

<select id="querystudentmap" resulttype="student">

select sname from test.student limit 1

</select>

<!--多条结果集-->

<select id="queryallstudentmap" resulttype="student">

select sname from test.student

</select>

resulttype="student" 为 student.java 的别名,也可以是全限定名。别名在 mybatis-config.xml 配置文件中设置:

?

1

2

3

4
<typealiases>

<typealias type="com.bean.student" alias="student"/>

...

</typealiases>

但是如果 javabean 文件很多,不想一个个指定,也可以使用 package 标签 设置mybatis自动扫描,别名即为类名的小写。

?

1

2

3
<typealiases>

<package name="包名"/>

</typealiases>

复杂查询 resultmap

对于一般的查询语句,resulttype 足够了。对于多表查询等情况,就要请出 resultmap 了。

数据库字段和 java 数据类型映射关系

数据库字段类型 jdbctype 和 java 数据类型 并不是一一对应的关系,而且不同数据库类型也不尽相同。而 mybatis 将 typehandler 作为两者之间的映射关系。大部分情况下都是没有问题的,但是并非能覆盖所有的情况,特殊情况下可以使用 resultmap 自定义这种映射关系。

举个例子,数据库 longvarchar 字段类型对应 java 中的 string 类型。但是在 db2 数据库中,查询的 longvarchar 类型的字段,在 mybatis 中被识别成 jdbctype 为 blob。有两种解决方法,第一种是在 sql 中对该字段使用 cast 转换为 varchar(长度)类型。另一种是使用 resultmap:

?

1

2

3

4

5

6

7
<resultmap id="resultmapdemo" type="" automapping="true">

<result property="" column="" jdbctype="varchar" />

</resultmap>

<select id="demoid" resultmap="resultmapdemo">

...

<select>

1、<select>标签中使用 resultmap 指定返回集合。注意 resultmap 和 resulttype 不能同时使用

2、<resultmap> 标签

  • id 和 select 标签指定映射关系
  • type 和 resulttype 一样为返回类型的全限定名或者别名
  • automapping 自动映射关系,在这里目的只是修改一个字段,其他自动采用自动完成映射关系

3、<result> 标签

  • 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 成绩
?

1

2

3

4

5

6

7
<!--建表语句-->

create table score

(

sno varchar(3) not null,

cno varchar(5) not null,

degree decimal(10, 1) not null

)

?

1

2

3

4

5

6

7

8
<!--bean 文件-->

public class score {

private string sno;

private string cno;

private double degree;

<!--get 和 set 方法-->

...

}

一对一关系

这里的一对多关系是两个表字段一一对应,一个学生的某门课的成绩是唯一确定的。 在一一对应的情况下要在 resultmap 中使用 标签。

在 student.java 中增加字段 score

?

1

2

3

4

5

6

7

8
<!--student.java-->

private score score;

public score getscore() {

return score;

}

public void setscore(score score) {

this.score = score;

}

有两种使用情况,第一种为嵌套查询,即前一个 sql 查询结果集中的字段作为参数传递给下一个 sql。第二种情况为嵌套结果集,即两个表做关联查询,将结果集映射到多个 javabean 文件。

嵌套查询

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16
<resultmap id="allstudentresultmap" type="student">

<!--指定第二个 select 语句,和传递的字段-->

<association property="score" column="sno" select="queryscore" />

</resultmap>

<!--第一个 sql -->

<select id="queryallstudent" resultmap="allstudentresultmap">

select sno,sname

from test.student

</select>

<!--第二个 sql-->

<select id="queryscore" resulttype="score">

select degree from test.score

where sno = #{sno}

</select>

在标签中

  • 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)
?

1

2

3
<!--mybatis-config.xml-->

<setting name="lazyloadingenabled" value="true"/>

<setting name="aggressivelazyloading" value="false"/>

也可以在标签中设置 fetchtype = “lazy” 开启懒加载,会覆盖全局的参数设置。

嵌套结果集

对于多表关联查询,一般在 sql 中使用别名来避免字段名的重复。mybatis 要做的是将别名正确的映射到 javabean 属性上。

?

1

2

3

4

5

6

7

8

9

10

11

12

13
<!--嵌套结果-->

<resultmap id="associationdemomap" type="student" automapping="true">

<association property="score" javatype="score">

<result property="sno" column="sc_sno"/>

</association>

</resultmap>

<select id="querystudentscore" resultmap="associationdemomap">

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';

</select>

通过设置标签指定了表列名和属性之间的映射关系。但这样如果字段很多,会需要一一指定,标签提供了columnprefix属性,指定别名的前缀,这样可以重用resultmap

?

1

2

3

4

5

6

7

8
<resultmap id="associationdemomap" type="student" automapping="true">

<!--columnprefix 指定别名的前缀-->

<association property="score" resultmap="anothermap" columnprefix="sc_" />

</resultmap>

<!--方便重用-->

<resultmap id="anothermap" type="score" automapping="true">

</resultmap>

一对多关系

除了一对一的关系,还有一对多的关系,比如这里一个学生student 对应多门课的成绩。 一对多对应的情况下要在 resultmap 中使用 标签。首先需要调整 javabean 文件中两个表之间的关系。

?

1

2

3

4

5

6

7

8
<!--student.java-->

private list<score> score;

public list<score> getscore() {

return score;

}

public void setscore(list<score> score) {

this.score = score;

}

以嵌套结果集为例

?

1

2

3

4

5

6

7

8

9

10

11

12
<resultmap id="collectiondemomap" type="student" automapping="true">

<!--多出了 oftype 属性-->

<collection property="score" oftype="score">

<result property="sno" column="sc_sno"/>

</collection>

</resultmap>

<select id="querystudentscore" resultmap="collectiondemomap">

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

</select>

注意到相比 association 多了一个属性oftype,是用来表示 list 集合中的类型的。其他属性的用法同 association 是一样的。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对快网idc的支持。

原文链接:https://juejin.im/post/5b63a710e51d4518f5443d23

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Mybatis查询语句结果集的总结大全 https://www.kuaiidc.com/111438.html

相关文章

发表评论
暂无评论