(八)MyBatis从入门到入土——自动映射的使用 2022-10-30 14:24 95阅读 0赞 这是mybatis系列第8篇。没看前文的建议先去【Java冢狐】公众号中查看前文,方便理解和掌握。在上一篇中我们介绍了一些mybatis使用查询的一些方式,特别是一对一查询和一对多查询进行了重点介绍。没看的推荐去公众号进行查看。 今天我们介绍一下我们一直在使用的但是没有来得及做过多介绍的自动映射。 ## 什么是自动映射? ## 介绍自动映射之前先看一下手动映射,如下: <resultMap id="orderModelMap1" type="com.zhonghu.chat08.demo7.model.OrderModel"> <id column="id" property="id"/> <result column="userId" property="userId" /> <result column="createTime" property="createTime" /> <result column="upTime" property="upTime" /> </resultMap> <select id="getById1" resultMap="orderModelMap1"> <![CDATA[ SELECT a.id, a.user_id userId, a.create_time createTime, a.up_time upTime FROM orders a WHERE a.id = #{value} ]]> </select> 注意上面的resultMap元素中有4行配置,如下: <id column="id" property="id"/> <result column="userId" property="userId" /> <result column="createTime" property="createTime" /> <result column="upTime" property="upTime" /> 这4行代码用于配置sql结果的列和OrderModel对象中字段的映射关系。 大家有没有注意到,映射规则中column和property元素的值都是一样,mybatis中支持自动映射配置,当开启自动映射之后,当sql的列名和Model中的字段名称是一样的时候(不区分大小写),mybatis内部会进行自动映射,不需要我们手动去写上面的4行映射规则。 下面我们将上面的示例改成自动映射的方式,如下: <resultMap id="orderModelMap2" type="com.zhonghu.chat08.demo7.model.OrderModel" autoMapping="true"> </resultMap> <select id="getById2" resultMap="orderModelMap2"> <![CDATA[ SELECT a.id, a.user_id userId, a.create_time createTime, a.up_time upTime FROM orders a WHERE a.id = #{value} ]]> </select> 注意上面的resultMap中的autoMapping属性,是否开启自动映射,我们设置为true,这样mybatis会自动按照列名和Model中同名的字段进行映射赋值。 上面两个配置最后查询结果是一样的,都会将查询结果对应的4个字段的值自动赋值给OrderModel中同名的属性。 ### 自动映射开关 ### mybatis中自动映射主要有2种配置,一种是全局的配置,对应用中所有的resultMap起效,这个是在mybatis配置文件中进行设置的;另外一种是通过resultMap的autoMapping属性进行配置。 mybatis判断某个resultMap是否开启自动映射配置的时候,会先查找自身的autoMapping属性,如果这个属性设置值了,就直接用这个属性的值,如果resultMap元素的autoMapping属性没有配置,则走全局配置的自动映射规则。 下面我们来详解介绍一下这款的内容。 ### mybatis自动映射全局配置 ### 在mybatis全局配置文件中加入下面配置: <settings> <setting name="autoMappingBehavior" value="自动映射规则"/> </settings> 主要有一下几种: * NONE:关闭全局映射开关 * PARTIAL:对除在内部定义了嵌套结果映射(也就是连接的属性)以外的属性进行映射,这个也是默认值。 * FULL:自动映射所有属性。 #### NONE #### 当mybatis全局配置中将autoMappingBehavior的值置为了NONE,表示全局自动映射被关闭了,会导致sql实际上有返回结果,但是结果映射的时候不会自动映射所以返回的时候是空 #### PARTIAL #### 会进行自动映射,但是有些复杂的查询映射会在resultMap中嵌套一些映射(如:association,collection),当使用PARTIAL的时候,如果有嵌套映射,则这个嵌套映射不会进行自动映射了。 #### FULL #### 自动映射所有属性。 ### autoMapping使用 ### 上面我们有说过,当在resultMap中指定了autoMapping属性之后,这个resultMap的自动映射就受autoMapping属性的控制,和mybatis中全局映射配置(autoMappingBehavior)行为无关了。 #### 案例1 #### ##### 这个核心配置主要在sqlmap中,如下: ##### <resultMap id="orderModelMap7" type="com.zhonghu.chat08.demo7.model.OrderModel" autoMapping="true"> <association property="userModel" autoMapping="true"> <id column="user_id" property="id"/> </association> </resultMap> <select id="getById7" resultMap="orderModelMap7"> <![CDATA[ SELECT a.id, a.user_id userId, a.create_time createTime, a.up_time upTime, b.id as user_id, b.name FROM orders a,user b WHERE a.user_id = b.id AND a.id = #{value} ]]> </select> ##### 对应测试用例 ##### com.zhonghu.chat08.demo7.Demo7Test#getById7 @Test public void getById7() throws IOException { this.before("demo7/mybatis-config1.xml"); try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) { OrderMapper mapper = sqlSession.getMapper(OrderMapper.class); OrderModel orderModel = mapper.getById7(2); log.info("{}", orderModel); } } ##### 运行输出 ##### 24:37.544 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById7 - ==> Preparing: SELECT a.id, a.user_id userId, a.create_time createTime, a.up_time upTime, b.id as user_id, b.name FROM orders a,user b WHERE a.user_id = b.id AND a.id = ? 24:37.589 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById7 - ==> Parameters: 2(Integer) 24:37.610 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById7 - <== Total: 1 24:37.610 [main] INFO c.j.chat05.demo7.Demo7Test - OrderModel(id=2, userId=1, createTime=1610803573, upTime=1610803573, userModel=UserModel(id=1, name=冢狐)) OrderModel中所有属性都自动映射成功。 自动装配并不是那么好玩,玩不转可能带来一些隐患,我们看一个案例,见下面的示例2。 #### 示例2 #### 根据订单编号,查询出订单信息,顺便查询出订单明细列表。这个我们使用mybatis中的一对多查询。 ##### OrderDetaiMapper.xml加入 ##### <select id="getListByOrderId1" resultType="com.zhonghu.chat08.demo7.model.OrderDetailModel"> <![CDATA[ SELECT a.id, a.order_id AS orderId, a.goods_id AS goodsId, a.num, a.total_price AS totalPrice FROM order_detail a WHERE a.order_id = #{value} ]]> </select> 这个可以根据订单的id,查询出订单关联的明细列表。 ##### OrderMapper.xml加入 ##### <resultMap id="orderModelMap8" type="com.zhonghu.chat08.demo7.model.OrderModel" autoMapping="true"> <collection property="orderDetailModelList" select="com.zhonghu.chat08.demo7.mapper.OrderDetailMapper.getListByOrderId1" column="id"/> </resultMap> <select id="getById8" resultMap="orderModelMap8"> <![CDATA[ SELECT a.id, a.user_id userId, a.create_time createTime, a.up_time upTime FROM orders a WHERE a.id = #{value} ]]> </select> ##### 测试用例 ##### com.zhonghu.chat08.demo7.Demo7Test#getById8 @Test public void getById8() throws IOException { this.before("demo7/mybatis-config.xml"); try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) { OrderMapper mapper = sqlSession.getMapper(OrderMapper.class); OrderModel orderModel = mapper.getById8(1); log.info("{}", orderModel); } } ##### 运行输出 ##### 11:06.193 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById8 - ==> Preparing: SELECT a.id, a.user_id userId, a.create_time createTime, a.up_time upTime FROM orders a WHERE a.id = ? 11:06.229 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById8 - ==> Parameters: 1(Integer) 11:06.250 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ====> Preparing: SELECT a.id, a.order_id AS orderId, a.goods_id AS goodsId, a.num, a.total_price AS totalPrice FROM t_order_detail a WHERE a.order_id = ? 11:06.251 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ====> Parameters: 1(Integer) 11:06.255 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - <==== Total: 2 11:06.256 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById8 - <== Total: 1 11:06.256 [main] INFO c.j.chat05.demo7.Demo7Test - OrderModel(id=null, userId=2, createTime=1610803573, upTime=1610803573, userModel=null, orderDetailModelList=[OrderDetailModel(id=1, orderId=1, goodsId=1, num=2, totalPrice=16.00), OrderDetailModel(id=2, orderId=1, goodsId=1, num=1, totalPrice=16.00)]) 注意输出中OrderModel的id属性,怎么是null值?主要是下面这行配置导致的 <collection property="orderDetailModelList" select="com.zhonghu.chat08.demo7.mapper.OrderDetailMapper.getListByOrderId1" column="id"/> 上面这个配置中有个column属性,指定的是id,此时mybatis认为你对id字段手动指定了映射关系,就跳过了对id字段到OrderModel.id属性的自动映射,所以导致OrderModel对象的id属性没有赋值,此时需要我们在orderModelMap8手动指定id的映射规则,如下: <resultMap id="orderModelMap8" type="com.zhonghu.chat08.demo7.model.OrderModel" autoMapping="true"> <id column="id" property="id" /> <collection property="orderDetailModelList" select="com.zhonghu.chat08.demo7.mapper.OrderDetailMapper.getListByOrderId1" column="id"/> </resultMap> 再去运行测试用例就正常了。 ### 总结一下 ### 对于咱们开发来说,自动映射确实可以帮助我们节省一些代码,不过也存在一些隐患,我们希望自己开发的系统是健壮的,建议大家写mapper xml的时候,还是花点时间将映射的配置都给写上去,这样能够杜绝一些隐患,使我们的系统更稳定。 ### 最后 ### * 如果觉得看完有收获,希望能关注一下,顺便给我点个赞,这将会是我更新的最大动力,感谢各位的支持 * 欢迎各位关注我的公众号【java冢狐】,专注于java和计算机基础知识,保证让你看完有所收获,不信你打我 * 求一键三连:点赞、转发、在看。 * 如果看完有不同的意见或者建议,欢迎多多评论一起交流。感谢各位的支持以及厚爱。 ——我是冢狐,和你一样热爱编程。 > 欢迎关注公众号“ Java冢狐”,获取最新消息
相关 (一)MyBatis从入门到入土——简介 这是MyBatis系列第1篇。大概会用十三篇的篇幅来讲解MyBatis,喜欢这个系列的欢迎关注公众号【Java冢狐】获取最新文章。那么废话不多说,让我们开始吧! 没有MyB 电玩女神/ 2022年10月27日 01:33/ 0 赞/ 70 阅读
相关 (二)MyBatis从入门到入土——开发一个Mybatis项目 这是mybatis系列第2篇。没看前文的建议先去【Java冢狐】公众号中查看前文,方便理解和掌握这篇文章主要接着前文介绍了如何创建并使用Mybatis。 实战演练 上一 心已赠人/ 2022年10月27日 13:38/ 0 赞/ 58 阅读
相关 (三)MyBatis从入门到入土——使用详解 这是mybatis系列第3篇。没看前文的建议先去【Java冢狐】公众号中查看前文,方便理解和掌握 MyBatis使用详解 上篇我们手动开发了一个MyBatis项目,但是 快来打我*/ 2022年10月28日 10:28/ 0 赞/ 69 阅读
相关 (六) MyBatis从入门到入土——主键的获取 这是mybatis系列第六篇。没看前文的建议先去【Java冢狐】公众号中查看前文,方便理解和掌握。 前面五篇把MyBatis的基本用法基本介绍完毕了,强烈推荐大家先把前面五篇 谁借莪1个温暖的怀抱¢/ 2022年10月29日 15:19/ 0 赞/ 76 阅读
相关 (七)MyBatis从入门到入土——花式查询 这是mybatis系列第7篇。没看前文的建议先去【Java冢狐】公众号中查看前文,方便理解和掌握。上一篇中我们讲述了一些关于获取主键的方法,这篇文章中我们将会更加深入的介绍一些 水深无声/ 2022年10月30日 02:28/ 0 赞/ 71 阅读
相关 (八)MyBatis从入门到入土——自动映射的使用 这是mybatis系列第8篇。没看前文的建议先去【Java冢狐】公众号中查看前文,方便理解和掌握。在上一篇中我们介绍了一些mybatis使用查询的一些方式,特别是一对一查询和一 深藏阁楼爱情的钟/ 2022年10月30日 14:24/ 0 赞/ 96 阅读
相关 MyBatis从入门到入土——动态SQL 这是mybatis系列第10篇,没看前文的建议先去【Java冢狐】公众号中查看前文,方便理解和掌握。在上一篇中重点介绍了延迟加载、鉴别器以及继承的相关知识。 在这篇文章中我们 柔光的暖阳◎/ 2022年11月03日 00:43/ 0 赞/ 84 阅读
相关 MyBatis从入门到入土——缓存的使用 这是mybatis系列第11篇。没看前文的建议先去【Java冢狐】公众号中查看前文,方便理解和掌握。 什么是缓存? 缓存就是存储数据的一个地方(称作:Cache),当程 谁践踏了优雅/ 2022年11月04日 05:55/ 0 赞/ 74 阅读
相关 Java学习路线从入门到入土 Java学习路线从入门到入土 Java学习路线从入门到入土 Java学习路线从入门到入土 简介 Java基础课程 朴灿烈づ我的快乐病毒、/ 2022年12月08日 14:27/ 0 赞/ 90 阅读
相关 Git从入门到入土 Git介绍 Git是开发中必须用到的分布式的版本控制软件,这是其官网[Git][]。 我们可以在官网中找到其说明文档,十分的详细并且使用简单。 下载并安装 官网 末蓝、/ 2023年01月09日 15:56/ 0 赞/ 58 阅读
还没有评论,来说两句吧...