Bootstrap

详细分析 MyBatis 参数映射与使用(附Demo)

前言

对于Java的基本知识推荐阅读:

  1. java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
  2. 【Java项目】实战CRUD的功能整理(持续更新)

原先写过xml的动态Sql,基本知识推荐阅读:详细分析Mybatis中的动态Sql(附Demo)

以下是在实战中遇到某个Bug,对应进行科普了解

1. 基本知识

  • 参数传递方式
    对象属性:使用对象作为参数,通过对象的属性进行查询
    简单属性:直接将参数作为方法参数,使用时引用参数名

  • 使用场景
    对象属性:适合多个相关属性传递的情况
    简单属性:适合少数参数的情况,特别是不相关联的参数

传递方式描述示例代码
对象属性使用对象作为参数#{deviceChargeHist.deviceName}
简单属性直接传递参数#{startTime}
使用场景多个相关属性DeviceChargeHistVO
使用场景少数不相关的参数Date startTime, Date endTime

2. Demo

基本的Demo示例如下:

对象属性查询示例

public List<DeviceChargeHistVO> selectDeviceChargeHistPage(IPage page, DeviceChargeHistVO deviceChargeHist) {
    return baseMapper.selectDeviceChargeHistPage(page, deviceChargeHist);
}
<select id="selectDeviceChargeHistPage" resultMap="deviceChargeHistResultMap">
    <where>
        <if test="deviceChargeHist.deviceName != null and deviceChargeHist.deviceName != ''">
            DEVICE_NAME = #{deviceChargeHist.deviceName}
        </if>
        <if test="deviceChargeHist.startTime != null">
            and CREATE_TIME &gt; #{deviceChargeHist.startTime}
        </if>
    </where>
</select>

简单属性查询示例

public List<DeviceChargeHist> selectAllDeviceChargeHistPage(Date startTime, Date endTime) {
    return baseMapper.selectAllDeviceChargeHistPage(startTime, endTime);
}
<select id="selectAllDeviceChargeHistPage" resultMap="deviceChargeHistResultMap">
    <where>
        <if test="startTime != null">
            and CREATE_TIME &gt; #{startTime}
        </if>
    </where>
</select>

以上很常用,但是在实战中遇到这种场景需要变通一下

3. 拓展

对应的类定义如下:

@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "DeviceChargeHistVO对象", description = "设备运行历史")
public class DeviceChargeHistVO extends DeviceChargeHist {
@Data
@TableName("E_DEVICE_CHARGE_HIST")
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "DeviceChargeHist对象", description = "设备充电历史")
public class DeviceChargeHist extends BaseEntity {

如果在接口中使用如下:

  • 使用DeviceChargeHist作为返回值,那么xml查询字段如果有来自DeviceChargeHistVO 的类,可能不可跨级别,不可直接使用DeviceChargeHistVO的各个属性
  • 如果使用DeviceChargeHistVO作为返回值,那么xml查询字段可以使用DeviceChargeHistVO的所有字段,因为他继承了实体类

下面的方式都是配合使用:

方案一:

public interface DeviceChargeHistMapper extends BaseMapper<DeviceChargeHist> {

	List<DeviceChargeHist> selectAllDeviceChargeHistPage(DeviceChargeHistVO deviceChargeHist);

}

其中xml如下:

<select id="selectAllDeviceChargeHistPage" resultMap="deviceChargeHistResultMap">
    select DEVICE_ID, DEVICE_NAME, STATUS, BEGIN_CAPACITY, END_CAPACITY, BEGIN_MILEAGE, END_MILEAGE, CHARGE_CAPACITY, BATTERY_CAPACITY, CHARGE_START_TIME, CHARGE_END_TIME, LAT, LON, CREATE_TIME, CREATE_USER, UPDATE_TIME, UPDATE_USER from E_DEVICE_CHARGE_HIST
    <where>
        <if test="deviceName != null and deviceName != ''">
            DEVICE_NAME = #{deviceName}
        </if>
        <if test="startTime != null">
            and CREATE_TIME &gt; #{startTime}
        </if>
        <if test="endTime != null" >
            and CREATE_TIME &lt;= #{endTime}
        </if>
    </where>
    order by CREATE_TIME DESC
</select>

方案二:

public interface DeviceChargeHistMapper extends BaseMapper<DeviceChargeHist> {
	
	// 修改返回值
	List<DeviceChargeHistVO> selectAllDeviceChargeHistPage(DeviceChargeHistVO deviceChargeHist);

}

其中xml如下:

<select id="selectAllDeviceChargeHistPage" resultMap="deviceChargeHistResultMap">
    select DEVICE_ID, DEVICE_NAME, STATUS, BEGIN_CAPACITY, END_CAPACITY, BEGIN_MILEAGE, END_MILEAGE, CHARGE_CAPACITY, BATTERY_CAPACITY, CHARGE_START_TIME, CHARGE_END_TIME, LAT, LON, CREATE_TIME, CREATE_USER, UPDATE_TIME, UPDATE_USER from E_DEVICE_CHARGE_HIST
    <where>
        <if test="deviceChargeHist.deviceName != null and deviceChargeHist.deviceName != ''">
         DEVICE_NAME = #{deviceChargeHist.deviceName}
        </if>
        <if test="deviceChargeHist.startTime != null">
            and CREATE_TIME &gt; #{deviceChargeHist.startTime}
        </if>
        <if test="deviceChargeHist.endTime != null" >
            and CREATE_TIME &lt;= #{deviceChargeHist.endTime}
        </if>
    </where>
    order by CREATE_TIME DESC
</select>

注意甄别这种用法!

;