ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

mybatis中的sql映射文件(2)—resultMap

2022-01-31 19:34:02  阅读:174  来源: 互联网

标签:name resultMap class stu sql mybatis null id uid


原文链接:这里
0.前言

总有一些奇葩的问题需要你去解决。mybatis中又遇到了一个resultMap,刚解决了resultType和parameterType。

1.属性说明

resultMap有一些属性

  • id:resultMap标签的标识。
  • type:返回值的全限定类名,或类型别名。
  • autoMapping:值范围true(默认值)|false, 设置是否启动自动映射功能,自动映射功能就是自动查找与字段名小写同名的属性名,并调用setter方法。而设置为false后,则需要在resultMap内明确注明映射关系才会调用对应的setter方法。
2.用法1:SQL字段与实体属性映射

(1)问题来源

mybatis负责和mysql交互的时候,一般要求pojo实体类与数据库字段名一一对应。例如下面这个样子:

实体类:

package com.cat.pojo; import lombok.Data;   @Data public class Students { private int id; private String stu_name; private String stu_sex; private int class_id; private int age; }

XML文件:

<?xml version="1.0" encoding="UTF-8"?>   <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.cat.dao.StudentsMapper"> <!--展示所有学生--> <select id="listAllStudents" resultType="com.cat.pojo.Students"> select id ,stu_name ,class_id from students; </select> </mapper>

一开始我们都这样操作,从数据库取出的数据可以和pojo中的实体类做到一一对应。当然,这是理想状态下,实际情况下可能会遇到很多不一致的情况。公司中可能有人单独写数据库,有人单独写后端,这个时候数据库字段名和后端的实体类中的属性名不一致很正常,比如:

pojo中实体类

package com.cat.pojo; import lombok.Data;   @Data public class Students { private int uid; private String name; private String stu_sex; private int class_id; private int age; }

xml的数据库映射文件:

<?xml version="1.0" encoding="UTF-8"?>   <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.cat.dao.StudentsMapper"> <!--展示所有学生--> <select id="listAllStudents" resultType="com.cat.pojo.Students"> select id ,stu_name ,class_id from students; </select> </mapper>

在上面中,我们定义的实体类中的ID、name和数据库中的字段id、stu_name不一样。这个时候你执行查询语句,就会出现下面这样的结果:

数据库查询log显示:(前提你要安装相应的插件或启用相关功能,不然看不到数据库的log信息)

==> Preparing: select id ,stu_name ,class_id from students; ==> Parameters: <== Columns: id, stu_name, class_id <== Row: 1000, 张三, 1001 <== Row: 1001, 王晓红, 2001 <== Row: 1002, 李清乐, 1001 <== Row: 1003, 赵倚天, 3001 <== Row: 1004, 孙思淼, 3001 <== Row: 1005, 李思露, 2001 <== Row: 1006, 杨阳, 1001 <== Total: 7

返回到程序中就变成:

[Students(uid=0, name=null, stu_sex=null, class_id=1001, age=0), Students(uid=0, name=null, stu_sex=null, class_id=2001, age=0), Students(uid=0, name=null, stu_sex=null, class_id=1001, age=0), Students(uid=0, name=null, stu_sex=null, class_id=3001, age=0), Students(uid=0, name=null, stu_sex=null, class_id=3001, age=0), Students(uid=0, name=null, stu_sex=null, class_id=2001, age=0), Students(uid=0, name=null, stu_sex=null, class_id=1001, age=0)]

从上面中可以看出,如果我们实体类和数据库字段名不一致,数据库执行的sql语句并不能完整的映射到实体类中。

(2)解决办法1

数据库字段定义完了基本不会乱动了,可是我又不想改实体类怎么办。那就只能从配置下手了。我可以把XML文件改成下面这样:

<?xml version="1.0" encoding="UTF-8"?>   <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.cat.dao.StudentsMapper"> <!--展示所有学生--> <select id="listAllStudents" resultType="com.cat.pojo.Students"> select id as uid, stu_name as name, class_id from students; </select> </mapper>

当使用as 时可以把 数据库字段名”当作“实体类属性名。这个时候,数据库查询的log显示如下:

==> Preparing: select id as uid, stu_name as name, class_id from students; ==> Parameters: <== Columns: uid, name, class_id <== Row: 1000, 张三, 1001 <== Row: 1001, 王晓红, 2001 <== Row: 1002, 李清乐, 1001 <== Row: 1003, 赵倚天, 3001 <== Row: 1004, 孙思淼, 3001 <== Row: 1005, 李思露, 2001 <== Row: 1006, 杨阳, 1001 <== Total: 7

打印实体类显示的结果:

[Students(uid=1000, name=张三, stu_sex=null, class_id=1001, age=0), Students(uid=1001, name=王晓红, stu_sex=null, class_id=2001, age=0), Students(uid=1002, name=李清乐, stu_sex=null, class_id=1001, age=0), Students(uid=1003, name=赵倚天, stu_sex=null, class_id=3001, age=0), Students(uid=1004, name=孙思淼, stu_sex=null, class_id=3001, age=0), Students(uid=1005, name=李思露, stu_sex=null, class_id=2001, age=0), Students(uid=1006, name=杨阳, stu_sex=null, class_id=1001, age=0)]

可以看出,这种方式可以做到数据库字段名和实体类属性名不一致的时候取数据的情况。

(3)解决办法2

上面的解法方法可以做到当数据库字段名和实体类名不一致的时候取数据的问题,但是我们也能看出,你的sql语句改变了,我现在不想改变sql语句,又想做到正常映射怎么办?这就用到了今天的主题:resultMap。

比如下面这样写sql映射文件

<?xml version="1.0" encoding="UTF-8"?>   <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.cat.dao.StudentsMapper">   <resultMap id="getStudentByMap" type="com.cat.pojo.Students"> <result property="uid" column="id"></result> <result property="name" column="stu_name"></result> </resultMap>   <select id="listAllStudents" resultMap="getStudentByMap"> select id ,stu_name,class_id from students; </select> </mapper>

其中:

  • id元素 ,用于设置主键字段与领域模型属性的映射关系
  • result元素 ,用于设置普通字段与领域模型属性的映射关系

id、result语句属性配置细节:

属性 描述
property 需要映射到JavaBean 的属性名称。
column 数据表的列名或者标签别名。
javaType 一个完整的类名,或者是一个类型别名。如果你匹配的是一个JavaBean,那MyBatis 通常会自行检测到。然后,如果你是要映射到一个HashMap,那你需要指定javaType 要达到的目的。
jdbcType 数据表支持的类型列表。这个属性只在insert,update 或delete 的时候针对允许空的列有用。JDBC 需要这项,但MyBatis 不需要。如果你是直接针对JDBC 编码,且有允许空的列,而你要指定这项。
typeHandler 使用这个属性可以覆写类型处理器。这项值可以是一个完整的类名,也可以是一个类型别名。

其他都不用改动,运行结果:

sql的log显示

==> Preparing: select id ,stu_name,class_id from students; ==> Parameters: <== Columns: id, stu_name, class_id <== Row: 1000, 张三, 1001 <== Row: 1001, 王晓红, 2001 <== Row: 1002, 李清乐, 1001 <== Row: 1003, 赵倚天, 3001 <== Row: 1004, 孙思淼, 3001 <== Row: 1005, 李思露, 2001 <== Row: 1006, 杨阳, 1001 <== Total: 7

打印实体类显示:

[Students(uid=1000, name=张三, stu_sex=null, class_id=1001, age=0), Students(uid=1001, name=王晓红, stu_sex=null, class_id=2001, age=0), Students(uid=1002, name=李清乐, stu_sex=null, class_id=1001, age=0), Students(uid=1003, name=赵倚天, stu_sex=null, class_id=3001, age=0), Students(uid=1004, name=孙思淼, stu_sex=null, class_id=3001, age=0), Students(uid=1005, name=李思露, stu_sex=null, class_id=2001, age=0), Students(uid=1006, name=杨阳, stu_sex=null, class_id=1001, age=0)]

可以看出,这样的方法也能够让数据库的字段名和实体类属性名做到对应,而且我们原来写好的sql文件就不用动了,当然也有人觉得麻烦,看个人喜好。

标签:name,resultMap,class,stu,sql,mybatis,null,id,uid
来源: https://www.cnblogs.com/longkui-site/p/15858526.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有