关于mybatis扩展的一点想法

本文主要目的是为mybatis的 include 标签添加扩展属性

当使用mybatis进行单表查询时 可以方便的使用 <include> 标签将定义好的<sql> 节点内容包含进来,具体示例如下

<sql id="t_agent_Base_Column_List">
		ID,  WORKER_ID,  <span style="font-family: Arial, Helvetica, sans-serif;">WORKER_NAME,  </span>
		WORKER_MAIN_NUM,  WORKER_EXT_NUM,  SALE_PHONE,
		IS_PART_TIME,  	LAST_LOGIN_TIME,  SIGN,
		HEAD_PIC,WEI_XIN,  WX_EWM,
		WEIBO,  PRACTIC_CERT,  	WORK_YEAR,
		SERVICE_JSON,  	SERVICE_AREA,  	PRAISE_COUNT,
		SHOP_VIEW_COUNT,  CITY_CODE,  	AREA_CODE,
		AREA_NAME,  PLACE_CODE,  PLACE_NAME,
		SORT_SCORE,  VOCAT_SKILL, FEATURES,
		LEAD_REPUTABLY,  STATUS,  VERSION,
		INSERT_TIME,  UPDATE_TIME,  BUSINESS_TYPE,
		MANIFESTO,  BACKGROUND_IMAGE,  	TITLE_ID
	</sql>

	<!-- 根据主键查询 -->
	<select id="selectById" resultMap="AgentInfo" parameterType="java.lang.Integer">
		SELECT
			<include refid="t_agent_Base_Column_List" />
		FROM
			AGENT_INFO
		WHERE
			ID = #{id,jdbcType=INTEGER}
	</select>

但是当我们还需要其他表的一些字段时,那就要去联合查询另一个表的数据了,就不太方便复用 t_agent_Base_Column_List 这个sql节点了,比如说还有一张表存放的是经纪人等级以及经纪人带看记录数等一些信息,我们用的sql语句如下

SELECT 
A.ID,  A.WORKER_ID,  A.WORKER_NAME,.....经纪人表的其他字段
B. LEVEL,  --经纪人等级
B.SUBJECTS_NUM, --完成科目数
B.LOOK_NUM, --带看数
B.DEAL_NUM  --成交数
<span style="white-space:pre">	</span>FROM AGENT_INFO A
LEFT JOIN AGENT_TITLE_INFO B ON A.TITLE_ID=B.ID
WHERE A.ID = #{ID}

所需要的resultMap定义如下

<!--AgentInfo 中是所有经纪人表字段  -->
	<resultMap id="agentExendMap" type="com.kevin.learning.modules.entity.agent.AgentInfoExtend" extends="AgentInfo">
		<result column="LEVEL" property="level" jdbcType="VARCHAR"/>
		<result column="SUBJECTS_NUM" property="subjectsNum" jdbcType="VARCHAR"/>
		<result column="LOOK_NUM" property="lookNum" jdbcType="VARCHAR"/>
		<result column="DEAL_NUM" property="dealNum" jdbcType="VARCHAR"/>
	</resultMap>

我们可以看到上面的 sql 语句并不能复用定义好的t_agent_Base_Column_List 这个节点来引用整个T_AGENT字段,而是重新写了一遍,而且 经纪人详情表也没有复用。

下面来看一下我的一个扩展方案 ,因为我们的sql是要查询 经纪人信息,还有经纪人详情的几个字段 ,分别是 AGEN_INFO 表和 AGENT_TITLE_INFO表,看一下做了扩展的配置文件,其实这也是整篇文章唯一想要实现的效果

	<select id="selectExtendList" resultMap="agentExendMap" parameterType="map">
		select
		<include refid="t_agent_Base_Column_List" prefix="A."/>,
		<include refid="com.kevin.learning.modules.dao.agenttitle.IAgentTitleInfoDAO.t_agent_info_title_Base_Column_List"
				 prefix="B."
				 excludeCols="UPDATE_TIME,INSERT_TIME,STATUS,DESCRIPTION,ID"/>
		FROM AGENT_INFO A
		LEFT JOIN AGENT_TITLE_INFO B ON A.TITLE_ID=B.ID
		WHERE A.ID = #{ID}
	</select>

注:另一个 include标签是另一个mapper文件定义的,mybatis支持 引用其他文件的 sql节点

主要做了扩展的地方有两个

1、为 <include>节点添加了 prefix属性,这样在引用这个节点的字段都会加上这个前缀

2、为<include>节点添加 excludeCols属性,mybatis其实是可以引用另一个mapper文件中定义的sql节点的,我们上面引用了经纪人详情表的 base_column_List(包含了该表的所有字段),这个属性中定义的字段是会被排除的,以逗号分隔

结果:我们的 sql 包含的字段是 agent_info表的全部字段 + ( AGENT_TITLE_INFO 表全部字段 - excludeCols中定义的字段  )

level 和 lookNum 是 经纪人详情中的字段,这样就查出来了,同时被排除的 insert_time和update_time就没有查询

实现方法分析

这个改动主要是对源码码的修改是很少的,就只在myabtis启动加载 解析mapper文件时将自己需要的特性添加进去 , 要修改的类是 XMLIncludeTransformer 的 applyInclude方法

mybatis在解析sql时将 include 解析完成 会替换掉 原来的 include 节点

代码的处理部分很简单,就是将 sql节点中的 sql语句加上 prefix,然后将整个 字符串 设置到 DOM节点中 ,这样扩展就完成了, 对了,还有一个地方要改,那就是要对 mybatis的DTD文件做一个小改动,因为启动时会用DTD对mapper的xml进行验证

时间: 2024-08-26 05:58:34

关于mybatis扩展的一点想法的相关文章

关于UED前端开发的一点想法

5.2 关于UED前端开发的一点想法 5.2.1 目前UED前端代码是一个页面对应一个JS文件,更有甚者一个JS文件的代码会超过万行,这样的代码试想该如何维护?如果在从事前端开发的时候避免这种尴尬的局面,我想最好的方式就是分而治之, 如果分而治之?首先解析页面的一般思路,初始化(init) 事件绑定(event)页面读值(getData)页面写值(setData)重置页面(resetData)页面展示(setView)页面校验(checkData)页面异步加载 (ajax),页面测试(test)

多应用统一开发平台的一点想法

几年工作下来,发现有一个问题一直困扰着我们: 随着项目的越来越完善,功能越来越丰富,单一一个应用已经不能够支撑开发人员的需要.于是我们就需要根据业务分拆成几个相对独立的应用来满足多个开发团队的需求.但是这样也造成了一些问题,多个应用需要公用的基础代码维护起来越来越复杂,导致种种问题.也有很多种方式来解决,比如公共代码放置单独的地方,这样有带来的自动化部署方面的困难.在此,鄙人提出一种解决方法,即多应用统一开发平台的概念.在此以rails应用为例. 标准的rails应用结构如下: Gemfile

对当前网络路由的一点想法

五一小长假,和朋友开车去了浙江,发现了"基于目的地的最短距离算法"的弊端,也许就是这个算法导致了高速公路在某个时间段的定期规律性拥堵!从嘉定出发,G1501一路畅通,但是一旦转到G60沪昆高速,瞬间拥堵起来,实际上,早在G1501上时,就有公告牌,说沪昆高速有施工,可是大家还是全部转到了沪昆高速,留下S19/G15成了被抛弃的摆设...知道原因是什么吗?很简单,因为沪昆高速那条路最近!人们太相信导航,很少有人没事研究地图,所以很多人都上了当,当然这并不包括我.很多导航都是根据Dijks

关于MyBatis sqlSession的一点整理

原文地址:关于MyBatis sqlSession的一点整理 工作中,需要学习一下MyBatis sqlSession的产生过程,翻看了mybatis-spring的源码,阅读了一些mybatis的相关doc,对mybatis sqlSession有了一些认知和理解,这里简单的总结和整理一下. 首先, 通过翻阅源码,我们来整理一下mybatis进行持久化操作时重要的几个类: SqlSessionFactoryBuilder:build方法创建SqlSessionFactory实例. SqlSes

Installshield关于.NET安装时需要重启动的处理办法,以及延伸出的重启后继续安装的安装包的一点想法

原文:Installshield关于.NET安装时需要重启动的处理办法,以及延伸出的重启后继续安装的安装包的一点想法 很多朋友做安装包的时候,所打包的软件需要.NET Framework之类的环境,他们会检测系统是否已经安装了.NET,如果没有,则调用.NET安装包来安装.但是.NET安装完是需要重启动的,一般来说,我们都推荐使用/q/norestart的静默安装函数来使重启动推迟到安装结束时,使用如下:LaunchAppAndWait(SUPPORTDIR^"dotNetFx40_Full_x

关于标签系统的又一点想法。

前段时间,写过一篇<关于标签系统的一点想法.>.但其实没有谈到里面的内容,是有一部分来自与刘鑫老师的聊天,当时他给了我许多肯定,也是让我觉得记录下来很有必要的原因. 前一篇里没有提到,我跟刘老师谈到一个更加深入一点的.关于标签系统的想法.主要原因是因为我尚不肯定这是否也属于标签系统.直到最近disylee 送了一本标签 : 标记系统设计实践给我,里面的一个小节让我为自己的想法找到了理论依据. 很不错的一本书,没有让我失望,解答了我心中的一些困惑.书有点啰嗦,但也正因为此显得"系统&q

Java EE开发平台随手记6——Mybatis扩展4

这篇博客中来说一下对Mybatis动态代理接口方式的扩展,对于Mybatis动态代理接口不熟悉的朋友,可以参考前一篇博客,或者研读Mybatis源码. 扩展11:动态代理接口扩展 我们知道,真正在Mybatis动态代理接口方式背后起作用的是SqlSession接口,类似地,我们的动态代理接口扩展则是基于IDaoTemplate接口,同样的,也需要解决相同的三个基本问题: 问题1:确定需要执行的sqlId 原生用法是根据包名.接口名.方法名去查找,但我们推荐添加一个sqlId的查找策略接口: pu

有点想法系列:借助海尔平台打造智能家居的一点想法

前言:这只是本人做了一个无线通信项目,看了一篇文章,吃了一顿饭,饭桌上和同事讨论了手机行业(原谅京瓷和NEC都做过手机啊,原谅楼主村里人 没见识,感叹惊讶一下),之后加班,胡思乱想产生的个人想法,请不要嘲笑,照顾一下作者的弱小心灵,传播正能量. 物联网专业在我的母校西安理工大学已经开设,(分属计算机学院和自动化学院),最近畅想了一下智能家居,发现物联网这个很火爆的话题和概念,这么 多年了,却是依旧是现实中火不起来,比如海尔张瑞敏说的这么多年的要把海尔互联网化,其实现在海尔却仍是一个制造型企业,今

对创业团队的一点想法

本人 没有强大的技术,没有广阔的人脉,没有超前的远见,只因在创业团队中待过一年,有了一些想法,即记录下来.这里对给我这次机会的公司表示感谢!这里说提互联网及软件方向的创业团队. 1. 不宜过早制度化 当然,对于打卡这样的制度并不排斥.但是对于对上百人团队的管理方法,不宜过早产生.比如详细区分不同部门,部门与部门有专门负责人.做一次软件发布要层层审批,经过同意后,再到发布,已经又有很多问题修复了. 部门与部门之间建立负责人,本意是为了不让沟通变的混乱,但创业团队,每个部门又能有多少人,本来只是找某