MySQL 数据库 下 使用 MyBatis 进行主子表数据查询骚操作
在实际开发过程中经常会碰到 主表、从表 这样的数据库设计,本文将介绍一下 主、从表 查询、删除 的
Sao
操作。其中涉及到了MyBatis
resultMap
标签继承
、复用
、嵌套
的应用;废话不多少,喜欢的深入研究下,详情参考如下代码:
<?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.imis.server.mapper.DemoMapper">
<!--
MyBatis resultMap 标签继承、复用、嵌套
继承: 继承已存在的 resultMap 标签进行扩展
复用: 跨mapper文件引用现存的 resultMap 标签
嵌套: 多层嵌套的JavaBean与 resultMap 映射方法
-->
<!--
@Data // lombok 插件
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class MasterTable implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableField("id")
private Integer departmentType;
/**
* 名称
*/
@TableField("name")
private String departmentName;
}
-->
<resultMap id="Master_BaseResultMap" type="com.imis.server.entity.MasterTable">
<id column="id" property="id" jdbcType="VARCHAR" />
<result column="name" property="name" jdbcType="VARCHAR" />
</resultMap>
<!--
@Data // lombok 插件
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class ChildTable implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
private Integer departmentType;
/**
* 父级 ID
*/
private String parentId;
/**
* 名称
*/
private String departmentName;
}
-->
<resultMap id="Child_BaseResultMap" type="com.imis.server.entity.ChildTable">
<id column="id" property="id" jdbcType="VARCHAR" />
<result column="parent_id" property="parentId" jdbcType="VARCHAR" />
<result column="name" property="name" jdbcType="INTEGER" />
</resultMap>
<!--
@Data // lombok 插件
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class MasterAndChildList implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
private Integer departmentType;
/**
* 子表数据列表
*/
private List<ChildTable> childList;
}
-->
<!--
tip: 复用现存标签时若位于相同mapper文件可直接使用 resultMap 的 id 属性引用,跨文件时需要指定 namespace 属性才可正常引用
extends: 继承,可继承其他 resultMap 并加以扩展
association: 复用现存的 resultMap,适用于对应的属性为 单 JavaBean 时,使用 javaType 指定Java类型
collection: 复用现存的 resultMap,适用于对应的属性为 JavaBean集合 时,使用 ofType 指定Java类型
columnPrefix: 只将该属性指定前缀的属性赋值给当前 resultMap,存在多层嵌套时每进入一层就会将本层前缀截取掉。
如下面的mapper文件中,外层的 fullMemberMap 前缀为 child_,经本次筛选 child_id -> id,
内层的 com.imis.server.mapper.DemoMapper.Child_BaseResultMap 前缀为 child_,经本次筛选 child_id -> id,最终被赋值给 ChildTable.id
所以只有形如 child_id 的字段才会最终进入 com.imis.server.mapper.DemoMapper.Child_BaseResultMap 的取值范围中
若是不复用只是单纯嵌套,则可以直接将三个类写在一个 resultMap 标签内实现
-->
<resultMap id="BaseResultMap" extends="com.imis.server.mapper.DemoMapper.Master_BaseResultMap" type="com.imis.server.entity.MasterAndChildList">
<collection property="childList" javaType="java.util.List" ofType="com.dtqy.server.entity.ChildTable" resultMap="com.imis.server.mapper.DemoMapper.Child_BaseResultMap" columnPrefix="child_"></collection>
</resultMap>
<sql id="Master_Base_Column_List">
master_table.id,
master_table.name
</sql>
<sql id="Child_Base_Column_List">
child_table.id AS child_id,
child_table.parent_id AS child_parent_id,
child_table.name AS child_name
</sql>
<sql id="Master_Example_Where_Clause">
<where>
<trim prefix="" suffix="" prefixOverrides="">
<if test="parameter != null">
<if test="parameter.id != null and parameter.id != ''">
<!-- 主键 -->
AND master_table.id = #{parameter.id, jdbcType=VARCHAR}
</if>
<if test="parameter.name != null and parameter.name != ''">
<!-- 名称 -->
<![CDATA[ AND master_table.name LIKE #{parameter.name, jdbcType=VARCHAR} ||'%' ]]>
</if>
</if>
</trim>
</where>
</sql>
<sql id="Child_Example_Where_Clause">
<where>
<trim prefix="" suffix="" prefixOverrides="">
<if test="parameter != null">
<if test="parameter.childId != null and parameter.childId != ''">
<!-- 主键 -->
AND child_table.id = #{parameter.childId, jdbcType=VARCHAR}
</if>
<if test="parameter.childName != null and parameter.childName != ''">
<!-- 名称 -->
<![CDATA[ AND child_table.name LIKE #{parameter.childName, jdbcType=VARCHAR} ||'%' ]]>
</if>
</if>
</trim>
</where>
</sql>
<!-- 主表统计查询 -->
<select id="count" resultType="java.lang.Integer" parameterType="java.util.Map">
SELECT
COUNT(1)
FROM
master_table
<include refid="Master_Example_Where_Clause" />
</select>
<!-- 主表分页查询 -->
<select id="queryList" resultMap="BaseResultMap" parameterType="java.util.Map">
SELECT
master_table.*,
<include refid="Detail_Base_Column_List" />
FROM
(
SELECT
<include refid="Master_Base_Column_List" />
FROM
master_table
<include refid="Master_Example_Where_Clause" />
<if test="parameter.pageNumber != null ">
LIMIT ${(parameter.pageNumber != 0 ? (parameter.pageNumber - 1) : parameter.pageNumber) * parameter.pageSize}, ${parameter.pageSize}
</if>
)
LEFT JOIN child_table ON master_table.id = child_table.parent_id
<include refid="Child_Example_Where_Clause" />
ORDER BY
master_table.name DESC,
child_table.name ASC
</select>
<!-- 删除主表\从表数据 -->
<delete id="deleteById" parameterType="java.lang.String">
DELETE
master_table, child_table
FROM
master_table LEFT JOIN child_table ON master_table.id = child_table.parent_id
WHERE
master_table.id = #{id, jdbcType=VARCHAR};
</delete>
<!-- ID 查询主表从表数据 -->
<select id="getById" resultMap="BaseResultMap" parameterType="java.lang.String">
SELECT
master_table.*,
<include refid="Detail_Base_Column_List" />
FROM
(
SELECT
<include refid="Master_Base_Column_List" />
FROM
master_table
WHERE
master_table.id = #{id, jdbcType=VARCHAR};
LIMIT 1
)
LEFT JOIN child_table ON master_table.id = child_table.parent_id
ORDER BY
child_table.name ASC
</select>
<!-- 参数查询单条主表数据 -->
<select id="getByParameter" resultMap="BaseResultMap" parameterType="java.util.Map">
SELECT
master_table.*,
<include refid="Detail_Base_Column_List" />
FROM
(
SELECT
<include refid="Master_Base_Column_List" />
FROM
master_table
<include refid="Master_Example_Where_Clause" />
LIMIT 1
)
LEFT JOIN child_table ON master_table.id = child_table.parent_id
<include refid="Child_Example_Where_Clause" />
ORDER BY
child_table.jd_rank ASC
</select>
</mapper>