Multi-table query and update operations based on tk.mybatis.mapper (1)

I. Introduction

    I have been using mybatis for some years. I also have a bit of personal experience with the use of mybatis. Personally, mybatis is more convenient and lighter to use than hibernate, which is one of the reasons why I like to use mybatis. But every time after a period of time, there will be more and more sql statements in the xml file of mybatis, which does not look very beautiful or very convenient. I have also tried to build a general BaseMapper to solve this problem before. Although BaseMapper can solve such a problem, it is by no means a very effective method in my opinion. By accident, I came into contact with tk. The framework of mybatis.mapper is like a fire when dry wood meets fire, and I hit it off with it.

2. Implementation of the first edition

    However, after using the general mapper for a period of time, although the mapper framework has done a good job, I often need to use the left join function and the update function by field in the actual project, which is not in the current mapper framework. support, so I thought of myself to realize its function, so I have the first version shown below:

Key class diagrams of the first edition:


    The picture may not be very clear, let me explain: the main query function is encapsulated in BaseExample and SelectBaseExample extends the functions of order by, group by and query fields, and UpdateBaseExample encapsulates the functions of updated fields and values. The left join function is encapsulated in the MultipartSelectExample class. So here we can create three classes of SelectBaseExample, UpdateBaseExample or MultipartSelectExample according to our needs. You may be wondering why there seems to be nothing in the MultipartUpdateExample class. In fact, when I was designing, I felt that there should be such a class, but after I wrote it, I didn't know what more advanced functions would be used in the update operation, so I left it empty for now, haha, the judges can do it. ignore.

After introducing the important encapsulation classes, let's take a look at the hierarchical structure of Mapper:

The two main classes of these three classes are SelectBaseMapper and UpdateBaseMapper, which have general query and update methods respectively, and BaseExampleMapper is an auxiliary class for collection query and update functions. When using it, you only need to let the business Mapper inherit BaseExampleMapper.

Finally, let's take a look at the implementation of the xml file.

<?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.example.test.mapper.BaseExampleMapper">
	<select id = "getObjectByField" parameterType="com.example.test.example.select.SelectBaseExample" resultType="map">
		select <foreach collection="baseExample.fields" index="index" item="item" separator=",">
		${item}
	</foreach> from  ${baseExample.tableName[0]}
		<if test="baseExample.tableAlias != null ">
			${baseExample.tableAlias[0]}
		</if>
    <!-- Determine if it is MultipartSelectExample and use the left join function -->
 <if test="baseExample instanceof com.example.test.example.select.multipart.MultipartSelectExample and baseExample.leftJoinFlag">
			LEFT JOIN
			<foreach collection="baseExample.tableAlias" item="key" index="index" separator="">
				<if test="index >= 1">
					${baseExample.tableName[1]} ${key}
				</if>
			</foreach>
			ON ${baseExample.leftJoinOn}
		</if>
		<if test="baseExample.equalsWhere != null or baseExample.greaterThanWhere != null or baseExample.lessThanWhere != null or baseExample.notEqualsWhere != null">
			<where>
				<if test="baseExample.equalsWhere != null">
					<foreach collection="baseExample.equalsWhere.keys" item="key" index="index" separator="AND">
						<if test = "baseExample.tableAlias != null">
							${baseExample.tableAlias[0]}.
						</if>
						${key} = #{baseExample.equalsWhere[${key}]}
					</foreach>

					<if test="baseExample.greaterThanWhere != null or baseExample.lessThanWhere != null or baseExample.notEqualsWhere != null">
						AND
					</if>
				</if>
				<if test="baseExample.greaterThanWhere != null">
                                       <!-- Traverse the key of the map -->
                                     <foreach collection="baseExample.greaterThanWhere.keys" item="key" index="index" separator="AND">
						<!-- Get the value corresponding to the key -->
                                                ${key} > #{baseExample.greaterThanWhere[${key}]}
					</foreach>
					<if test="baseExample.lessThanWhere != null or baseExample.notEqualsWhere != null">
						AND
					</if>
				</if>
				<if test="baseExample.lessThanWhere != null">
					<foreach collection="baseExample.lessThanWhere.keys" item="key" index="index" separator="AND">
						${key} < #{baseExample.lessThanWhere[${key}]}
					</foreach>
					<if test="baseExample.notEqualsWhere != null">
						AND
					</if>
				</if>
				<if test ="baseExample.notEqualsWhere != null">
					<foreach collection="baseExample.notEqualsWhere.keys" item="key" index="index" separator="AND">
						${key} != #{baseExample.notEqualsWhere[${key}]}
					</foreach>
				</if>
			</where>
		</if>
		<if test="baseExample.equalsWhere == null and baseExample.greaterThanWhere == null and baseExample.lessThanWhere == null and baseExample.notEqualsWhere == null">
			WHERE 1 = 1
		</if>
		<if test="baseExample.inFields != null and  baseExample.inFields.size() > 0">
			AND
			<foreach collection="baseExample.inFields" item="field" index="index" separator="AND">
				${field} in
				<choose>
					<when test="index == 0">
						<foreach collection="baseExample.inValue1" item="value1" index="index1" separator="," open="(" close=")">
							#{value1}
						</foreach>
					</when>
					<otherwise>
						<foreach collection="baseExample.inValue2" item="value2" index="index2" separator="," open="(" close=")">
							#{value2}
						</foreach>
					</otherwise>
				</choose>
			</foreach>
		</if>
		<if test=" baseExample.likeFields != null">
			<if test="baseExample.inFields != null and  baseExample.inFields.size() > 0">
				AND
			</if>
			<foreach collection="baseExample.likeFields" item="field" index="index" separator="AND">
				${field} LIKE #{baseExample.likeValues[${index}]}
			</foreach>
		</if>

		<!-- Determine if group by -->
		<if test="baseExample.groupBy != null">
			GROUP BY ${baseExample.groupBy}
		</if>

		<!-- Determine whether it contains order by -->
		<if test="baseExample.orderBy != null">
			ORDER BY
			<foreach collection="baseExample.orderBy.keys" item="key" index="index" separator=",">
				${key}
				<choose>
					<when test="baseExample.orderBy[key] == 'DESC'">
						DESC
					</when>
					<otherwise>
						ASC
					</otherwise>
				</choose>
			</foreach>
		</if>

	</select>
</mapper>

The above is the xml implementation of the general query. Although it is a bit much, it is not complicated, and some of the contents are annotated. I believe the watchers can understand it. Next is the updated generic method.

<?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.example.test.mapper.BaseExampleMapper">
	<update id = "updateObject" parameterType="com.example.test.example.update.UpdateBaseExample" >
		UPDATE  ${baseExample.tableName[0]} SET
		<if test="baseExample.updateFields != null">
			<foreach collection="baseExample.updateFields.keys" item="key" index="index" separator=",">
				${key} = #{baseExample.updateFields[${key}]}
			</foreach>
		</if>
		<if test="baseExample.equalsWhere != null or baseExample.greaterThanWhere != null or baseExample.lessThanWhere != null or baseExample.notEqualsWhere != null">
			<where>
				<if test="baseExample.equalsWhere != null">
					<foreach collection="baseExample.equalsWhere.keys" item="key" index="index" separator="AND">
						<if test = "baseExample.tableAlias != null">
							${baseExample.tableAlias[0]}.
						</if>
						${key} = #{baseExample.equalsWhere[${key}]}
					</foreach>

					<if test="baseExample.greaterThanWhere != null or baseExample.lessThanWhere != null or baseExample.notEqualsWhere != null">
						AND
					</if>
				</if>
				<if test="baseExample.greaterThanWhere != null">
					<foreach collection="baseExample.greaterThanWhere.keys" item="key" index="index" separator="AND">
						${key} > #{baseExample.greaterThanWhere[${key}]}
					</foreach>
					<if test="baseExample.lessThanWhere != null or baseExample.notEqualsWhere != null">
						AND
					</if>
				</if>
				<if test="baseExample.lessThanWhere != null">
					<foreach collection="baseExample.lessThanWhere.keys" item="key" index="index" separator="AND">
						${key} < #{baseExample.lessThanWhere[${key}]}
					</foreach>
					<if test="baseExample.notEqualsWhere != null">
						AND
					</if>
				</if>
				<if test ="baseExample.notEqualsWhere != null">
					<foreach collection="baseExample.notEqualsWhere.keys" item="key" index="index" separator="AND">
						${key} != #{baseExample.notEqualsWhere[${key}]}
					</foreach>
				</if>
			</where>
		</if>
					<choose>
						  <when test="baseExample.equalsWhere != null or baseExample.greaterThanWhere != null or baseExample.lessThanWhere != null">
								AND
						  </when>
						<otherwise>
								WHERE
						</otherwise>
					</choose>
					  <if test="baseExample.inFields != null and  baseExample.inFields.size() > 0">
						  <foreach collection="baseExample.inFields" item="field" index="index" separator="AND">
							  ${field} in
							  <choose>
								  <when test="index == 0">
									  <foreach collection="baseExample.inValue1" item="value1" index="index1" separator="," open="(" close=")">
										  #{value1}
									  </foreach>
								  </when>
								  <otherwise>
									  <foreach collection="baseExample.inValue2" item="value2" index="index2" separator="," open="(" close=")">
										  #{value2}
									  </foreach>
								  </otherwise>
							  </choose>
						  </foreach>
					  </if>
							<if test=" baseExample.likeFields.size() > 0">
								<foreach collection="baseExample.likeFields" item="field" index="index" separator="AND">
									${field} LIKE #{baseExample.likeValues[${index}]}
								</foreach>
							</if>
	</update>
</mapper>

The general method of update is similar to the general method of query, so I won't explain it too much again.

Well, the above is the whole content of the first edition. Although the functions are very comprehensive and the performance is not low, I personally think that there is xml, the content is still messy, the code reusability is very poor, and the code is very intrusive. , does not meet my language expectations, so in the next article, I will introduce my 2.0 version. Compared with the 1.0 version, the judges will definitely feel that there are qualitative changes.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325774463&siteId=291194637