文章目录

  • 1、结果处理
    • 1.1、简单类型输出映射!
    • 1.2、pojo对象输出映射!
    • 1.3、定义resultMap
    • 1.4、resultMap使用(association,collection)注意!
      • 1.4.1、association
      • 1.4.2、collection
    • 1.5、懒加载

1、结果处理

1.1、简单类型输出映射!

简单类型,比如int,注意哦,一些类型的resultType,mybatis已经帮我们定义好了,我们直接用人家定义好的就行了!

详情见:https://mybatis.org/mybatis-3/zh/configuration.html#typeAliases

public interface CarsMapper {int findAllCars();
}
<select id="findAllCars" resultType="int">select count(*) from cars
</select>
@Test
public void findAllCars(){System.out.println(mapper.findAllCars());
}

[DEBUG] 2021-04-08 16:35:02,038 ==> Preparing: select count(*) from cars
[DEBUG] 2021-04-08 16:35:02,084 ==> Parameters:
[DEBUG] 2021-04-08 16:35:02,233 <== Total: 1
3

1.2、pojo对象输出映射!

之前,我们测试了,如果列名和我们的属性名一致的话,那么mybatis会自动映射,将查询结果封装到对象中。

那如果我们数据库中的列名是game_desc呢? 单独列名desc是通不过的,那我们只能起game_desc,那我们pojo的Game对象呢,总不能起game_desc把,这样就不规范了,我们标准是不是驼峰啊,gameDesc,那么问题来了,我们按照原来的方法是不是就映射不了啊,mybatis虽然厉害,但他也不能明白你的意思,对不对,他只能对队列名和属性名一致的来进行封装数据!

一种解决方法是我们在mybatis-config.xml文件中配置

<setting name=“mapUnderscoreToCamelCase” value=“true”/>,

这个时候,他才会为我们自动映射!

那好,我们来测试一下

创建game表

CREATE TABLE game(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(10),game_desc VARCHAR(10)
)

创建Game实体类

看不懂注解,请移位:1.4.3小节!

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Game {private int id;private String name;private String gameDesc;
}

GameMapper接口!

public interface GameMapper {List<Game> queryAllGameInfo();}

GameMapper.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tian.mapper.GameMapper"><select id="queryAllGameInfo" resultType="game">select * from game</select></mapper>

记得一定要在mapper注册GameMapper.xml ,一定要记得!!!

测试

@Test
public void queryAllGameInfos(){System.out.println(gameMapper.queryAllGameInfo());
}

结果! 是不是,我们的gameDesc经过配置后,也可以封装到poji对象了!

[DEBUG] 2021-04-08 16:57:33,651 ==> Preparing: select * from game
[DEBUG] 2021-04-08 16:57:33,687 ==> Parameters:
[DEBUG] 2021-04-08 16:57:33,724 <== Total: 4
[Game(id=1, name=lol, gameDesc=塔防类), Game(id=2, name=cf, gameDesc=射击类), Game(id=3, name=dnf, gameDesc=地下类), Game(id=4, name=qq, gameDesc=聊天类)]

如果我们去了呢,来试下嘛,肯定是有问题的,这不用说!

看嘛,是不是获取不到gameDesc, gameDesc=null

[DEBUG] 2021-04-08 17:00:39,544 ==> Preparing: select * from game
[DEBUG] 2021-04-08 17:00:39,588 ==> Parameters:
[DEBUG] 2021-04-08 17:00:39,619 <== Total: 4
[Game(id=1, name=lol, gameDesc=null), Game(id=2, name=cf, gameDesc=null), Game(id=3, name=dnf, gameDesc=null), Game(id=4, name=qq, gameDesc=null)]

1.3、定义resultMap

首先再学resultMap之前,思考一下我们什么要定义resultMap,定义它是要来解决与什么的?

  • 在我们多表关联查询的时候,如果不加别名,查询的结果是不是可能有重复,我们自己写的可能不会太懵,那别人来看呢,别人调试一下你的代码,唉,这什么啊,为什么查出来有两个id,name啊,这是那个的name,id啊!
  • 诶,这个时候问题就很严重了,起了别名是不是和数据库的属性又不对应了,即使我们上边设置了<setting name=“mapUnderscoreToCamelCase” value=“true”/> ,但是还是保不齐不发建立映射关系,那这个时候我们需要定义一个resultMap来帮我们解决这个问题!

案例

创建表 person,game如下

CREATE TABLE person(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(10),game_id INT,CONSTRAINT game_id_fk FOREIGN KEY(game_id) REFERENCES game(id)
)CREATE TABLE game(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(10),game_desc VARCHAR(10)
)

Person实体类

看不懂注解,请移位:1.4.3小节!

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {private int id;private String name;private Game game;
}

Game实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Game {private int id;private String name;private String gameDesc;
}

我们先来跑一下不加别名的sql查询

SELECTp.id,p.name,g.id,g.name,g.game_desc game_Desc
FROMperson pLEFT JOIN game gON p.game_id = g.id
WHERE p.id = 1

是不是一头雾水啊,人都傻了!

我们起别名之后,就豁然开朗了,瞬间清晰了很多有没有

清晰归清晰,我们查出来能映射吗? 我们查询最终是以别名为准,别名和我们pojo属性一致吗?

  • 很显然,并不一致,这个时候就有小伙伴说了,诶,我们将person属性设置的和别名一致不就好了吗,

    • 答案毋庸置疑是可以的,但是你考虑过我们如果不只查这个表呢,我们又该怎么办,是不是还映射不出来,那这个时候,我们显然选择映射前者即字段名和属性名一致,我们定义resultMap解决映射!

ok我们来写查询语句!

PersonMapper接口

public interface PersonMapper {List<Person> queryAll();}

PersonMapper.xml文件

  • select标签中的id对应我们接口中的方法名
  • select标签中的resultMap对应我们定义的resultMap的id
  • resultMap的type对应我们查的表对应的java实体类类型
  • person表关联game表,我们association标签是用来封装game对象的
  • association中的property对应person类中的 private Game game; 属性 即game
  • association中javaType对应java实体类类型
  • id标签的column,很明显,对应数据库列名,
  • id标签的property,那就对应实体类中的属性喽!
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.tian.mapper.PersonMapper"><resultMap id="queryAllPersonInfo" type="Person"><id column="pid" property="id"/><id column="pname" property="name"/><!-- 封装game对象 --><association property="game" javaType="Game"><id column="gid" property="id"/><id column="gname" property="name"/><id column="game_desc" property="gameDesc"/></association></resultMap><select id="queryAll" resultMap="queryAllPersonInfo" >SELECTp.id pid,p.name pname,g.id gid,g.name gname,g.game_desc game_DescFROMperson pLEFT JOIN game gON p.game_id = g.idWHERE p.id=2</select></mapper>

至此,我们就写完了,来测试一下

bingo! 我们的值是不是封装到了我们的实体类中,也就是说我们的列名和属性达到了映射!

[DEBUG] 2021-04-08 17:24:08,277 ==> Preparing: SELECT p.id pid, p.name pname, g.id gid, g.name gname, g.game_desc game_Desc FROM person p LEFT JOIN game g ON p.game_id = g.id WHERE p.id=2
[DEBUG] 2021-04-08 17:24:08,311 ==> Parameters:
[DEBUG] 2021-04-08 17:24:08,338 <== Total: 1
[Person(id=2, name=张三, game=Game(id=2, name=cf, gameDesc=射击类))]

1.4、resultMap使用(association,collection)注意!

当我们关联查询时候

  • 如果实体类封装的是对象,我们使用association,

  • 当我们封装的是对象集合的时候,用collection,

1.4.1、association

案例!

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {private int id;private String name;private Game game; // 对象!
}

这个时候我们得用association

如果你非得对象用collection,会出现下述错误:简单的说就是注入不进去!用association就好了!

org.apache.ibatis.exceptions.PersistenceException:

Error querying database. Cause: org.apache.ibatis.executor.ExecutorException: Error instantiating collection property for result ‘game’. Cause: org.apache.ibatis.reflection.ReflectionException: Could not set property ‘game’ of ‘class com.tian.pojo.Person’ with value ‘[]’ Cause: java.lang.IllegalArgumentException: argument type mismatch

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.tian.mapper.PersonMapper"><resultMap id="queryAllPersonInfo" type="Person"><id column="pid" property="id"/><id column="pname" property="name"/><!-- 封装game对象 --><association property="game" javaType="Game"><id column="gid" property="id"/><id column="gname" property="name"/><id column="game_desc" property="gameDesc"/></association></resultMap><select id="queryAll" resultMap="queryAllPersonInfo" >SELECTp.id pid,p.name pname,g.id gid,g.name gname,g.game_desc game_DescFROMperson pLEFT JOIN game gON p.game_id = g.idWHERE p.id=2</select></mapper>

安全通过!

[DEBUG] 2021-04-08 17:33:11,578 ==> Preparing: SELECT p.id pid, p.name pname, g.id gid, g.name gname, g.game_desc game_Desc FROM person p LEFT JOIN game g ON p.game_id = g.id WHERE p.id=2
[DEBUG] 2021-04-08 17:33:11,614 ==> Parameters:
[DEBUG] 2021-04-08 17:33:11,636 <== Total: 1
[Person(id=2, name=张三, game=Game(id=2, name=cf, gameDesc=射击类))]

1.4.2、collection

当我们用的是对象的集合时,注意,这里 写法有些区稍稍不一样!

我们管理查询的时候,需要变动一下,由原来的 javaType=“Game” 变为 --> javaType=“list” ofType=“Game”

  • javaType是我们 private List game; 返回的类型,list已经返回已经被mybatis定义了,我们直接小写list即可,或者 java.util.List ,写全类名!

  • ofType是 private List<Game> game; 的泛型,即关联表映射的pojo类类型!

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {private int id;private String name;private List<Game> game;   // 对象的集合
}

这里我们得用collection

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.tian.mapper.PersonMapper"><resultMap id="queryAllPersonInfo" type="Person"><id column="pid" property="id"/><id column="pname" property="name"/><!-- 封装game集合 --><collection property="game" javaType="list" ofType="Game"><id column="gid" property="id"/><id column="gname" property="name"/><id column="game_desc" property="gameDesc"/></collection></resultMap><select id="queryAll" resultMap="queryAllPersonInfo" >SELECTp.id pid,p.name pname,g.id gid,g.name gname,g.game_desc game_DescFROMperson pLEFT JOIN game gON p.game_id = g.idWHERE g.id=2</select></mapper>

如果我们用association的话,还是会出一样的错误,出现这类错误,我们就能定位到是哪里出现了错误!

Cause: org.apache.ibatis.reflection.ReflectionException: Could not set property ‘game’ of ‘class com.tian.pojo.Person’ with value ‘Game(id=2, name=cf, gameDesc=射击类)’ Cause: java.lang.IllegalArgumentException: argument type mismatch

为了确保准确,这里我们查询条件换为g.id = 2,

[DEBUG] 2021-04-08 17:36:36,243 ==> Preparing: SELECT p.id pid, p.name pname, g.id gid, g.name gname, g.game_desc game_Desc FROM person p LEFT JOIN game g ON p.game_id = g.id WHERE g.id=2
[DEBUG] 2021-04-08 17:36:36,278 ==> Parameters:
[DEBUG] 2021-04-08 17:36:36,405 <== Total: 2
[Person(id=2, name=张三, game=[Game(id=2, name=cf, gameDesc=射击类)]), Person(id=5, name=李四, game=[Game(id=2, name=cf, gameDesc=射击类)])]

1.5、懒加载

  • 需要查询关联信息时,使用 Mybatis 懒加载特性可有效的减少数据库压力,

  • 首次查询只查询主表信息,关联表的信息在用户获取时再加载。

  • Mybatis 一对一关联的 association 和一对多的 collection 可以实现懒加 载。

  • 懒加载时要使用 resultMap,不能使用 resultType。

懒加载

设置项 描述 允许值 默认值
lazyLoadingEnabled 是否开启懒加载模式 true | false false

启动懒加载

在mybatis-config.xml中的settings标签中设置

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

在关联表即从表设置

 fetchType="lazy"

如果是这样,表示不启动懒加载

fetchType="eager"
<association property="game" javaType="Game" fetchType="lazy" select="findGameByID" column="game_id"></association>

(1). Select:指定关联查询懒加载对象的 Mapper Statement ID 为

findGameByID

(2). column=“game_id”:关联查询时将 game_id列的值传入 findGameByID,

并将 findGameByID查询的结果映射到 Person的 Game属性中

(3).collection 和 association 都需要配置 select 和 column 属性,两者配置方法

相同

SSM—mybatis框架-结果处理-resultMap定义-association-collection相关推荐

  1. 【MyBatis框架】配置文件-resultMap总结

    resultMap总结 resultType: 作用: 将查询结果按照sql列名pojo属性名一致性映射到pojo中. 场合: 常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页 ...

  2. SSM—mybatis框架-注解开发-动态sql(where,set,trim,choose,when,foreach)-模糊查询写法-特殊符号处理-缓存

    文章目录 2.0.注解 2.1.动态sql 2.1.1.where 2.1.2.set 2.1.3.trim 2.1.3.1.trim的where 2.1.3.2.trim的set 2.1.4.1.c ...

  3. MyBatis框架学习 DAY_02:使用XML配置文件/多参数问题 / FOREACH /IF / #{}和${} / 创建SSM框架流程

    XML文件配置SQL 1. 使用XML文件配置SQL语句 2. 关于多参数的问题 2. 练习 3. 动态SQL -- foreach 4. 动态SQL -- if 5. 关于#{}和${}格式的占位符 ...

  4. Mybatis 高级结果映射 ResultMap Association Collection

    来源:http://www.verydemo.com/demo_c152_i1880.html MyBatis的创建基于这样一个思想:数据库并不是您想怎样就怎样的.虽然我们希望所有的数据库遵守第三范式 ...

  5. SSM之Mybatis框架高级

    1.resultMap高级操作:联合查询操作 #1 一对一关联查询 例如:根据订单关联查询用户 输出映射: resultType:自定义一个拓展的的pojo resultMap: 这里的resultM ...

  6. SSM之Mybatis框架初步

    1. SSH:Spring 中间层(容器框架,整合框架) Struct(控制层,Servlet) Hibernate(DAO,持久层框架) Structs2  Hibernate 两个重量级框架,入门 ...

  7. SSM之Mybatis框架

    最近在学SSM框架,现在来简单介绍一下,SSM里的mybatis框架. 首先来介绍一下ORM 1.ORM简介 Object Relational Mapping:对象关系映射. 简单的理解:ORM是通 ...

  8. mybatis元素类型为 “resultMap“ 的内容必须匹配 “(constructor?,id *,result*,association报错解决

    1.前言 太久没写这种套娃式的sql语句了,导致今天一写,直接给我整了个报错. 原因其实蛮简单的,mybatis的xml中的resultMap标签规定了内标签的顺序,写错了就会直接解析不出来,从而报错 ...

  9. (Spring+SpringMVC+MyBatis)SSM三大框架整合教程

    目录 一.基本概念 1.Spring 2.SpringMVC 3.MyBatis 二.开发环境搭建 三.Maven Web项目创建 四.SSM整合 1.Maven引入需要的JAR包 2.Spring与 ...

最新文章

  1. 观点 | 转行人士如何在人工智能领域保持一定的竞争力?
  2. 递归和迭代的区别是什么,各有什么优缺点?
  3. 协程 线程 进程的一点理解
  4. TensorFlow、MXNet、Keras如何取舍? 常用深度学习框架对比
  5. 5去掉button按钮的点击样式_CSS实现复古按钮
  6. stm32 fatfs fopen err_disk__小型文件系统FatFS和LittleFS对比和区别
  7. CTFHub-Web-信息泄露
  8. 关于 V C++ 中 Error 6 fatal error C1075的解决办法
  9. Spring Cloud CLI简介
  10. Consider renaming one of the beans or enabling overriding by setting
  11. linux是发展历史,linux发展历史.doc.doc
  12. RSync实现文件同步备份配置详解
  13. c语言编写记账程序,C语言会计记账管理系统
  14. 倍福PLC通过CANOpen通信控制伺服
  15. WordPress优化攻略:全面提升WP网站速度仅需3个加速方法和1个插件
  16. (原)使用ass字幕文件通过ffmpeg给视频添加字幕的一些研究
  17. ATFX:美国通胀转折点已来,激进加息势将暂缓?
  18. 猫眼爬取专业评分的python技术
  19. 第14届蓝桥杯省赛真题剖析-2023年5月7日Scratch编程初级组
  20. 进阶:主流的cpu插槽类型详解

热门文章

  1. hive 索爱_达内大数据云计算
  2. 紧锣密鼓完成小闭环,微型 CSDN 项目快快进入下一阶段
  3. 删除或关闭Word中的超链接
  4. 项目四 可视化编程工具
  5. 差异表达基因热图怎么看_R绘图 雷达图-单基因泛癌差异表达的另类展现形式
  6. 如何用剪贴蒙版实现字体渐变
  7. android 中的悬浮按钮,Android 中FloatingActionButton(悬浮按钮)实例详解
  8. 【VScode】基本使用+快捷键
  9. VIM 常用操作(转载)
  10. 百闻不如一见,4款名不见经传的极品软件,让你眼界大开