mybatis:传入参数为一个实体类时,<if test="">怎么获取其属性

本文详细解析了在使用MyBatis框架时,如何正确地绑定实体类参数到SQL语句中,避免因参数绑定失败导致的错误。重点介绍了在&lt;if&gt;标签中直接使用对象属性而非#{}

接口方法:绑定一个实体类作为参数

对应的xml:

<if>标签里不用写#{},但要对象名.属性,如果没有对象名会报错

报的是参数绑定失败错误:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'countryIsoCode' not found

因此要 对象名.属性

<think>我们注意到用户希望使用类似<trim>标签来动态处理字段和值的插入,特别是处理可能为null的字段,避免插入NULL值。 但是观察用户提供的示例,它是在字段列表和值列表部分都使用了<trim>,并且使用了prefixOverrides=","来去除开头可能多余的逗号。 然而,原语句中在字段列表和值列表的开头都使用了逗号,这会导致语法错误(因为INSERT语句中字段列表开头不应有逗号)。 因此,我们需要调整策略:使用<trim>的prefix="(" suffix=")" prefixOverrides=","来包裹整个字段列表和值列表,这样可以在生成去掉开头的逗号。 但是,用户提供的示例写法存在缺陷:字段列表和值列表的<trim>标签内部每个条件判断都以逗号开头,这样当第一个条件不满足,第二个条件满足就会以逗号开头,然后被prefixOverrides去除,从而保证语法正确。 因此,我们将按照以下方式重写: 原INSERT语句结构: INSERT INTO 表名 (<trim prefixOverrides=",">...</trim>) VALUES (<trim prefixOverrides=",">...</trim>) 注意:在<trim>内部,每个字段或值都以逗号开头,这样当第一个字段不存在,第二个字段前的逗号会被当作前缀覆盖掉(即被去掉)。 然而,用户要求的是类似这种的,所以我们按照同样的方式处理。 但是,用户之前给出的表结构是POS_FUND_CONVERSION_HIS,但并没有给出具体字段类型,我们只能按照示例中的字段名来写。 不过,在之前的对话中,用户要求的是生成POS_SUYIN_TRADE_APPLY表的插入语句,现在又换成了另一个表。这里我们假设用户希望我们按照他提供的示例格式(即使用<trim>动态插入)来写POS_SUYIN_TRADE_APPLY表的插入语句。 但是,请注意:用户这次并没有提供表结构,所以我们无法确定哪些字段需要动态插入。不过,我们可以参考之前他提供的POS_SUYIN_TRADE_APPLY表的字段,但要注意,之前那个表中有一些固定值(如'system', sysdate)以及非字符串类型的字段。 然而,用户要求的是“改成有trim标签的”,但之前的语句中我们已经用了TRIM函数,而这里用户又给出了一个使用<trim>标签动态插入字段的示例。所以我们需要明确:用户到底想要哪种trim? 从上下文看,用户这次提供的示例是使用MyBatis的动态SQL标签<trim>来避免插入NULL值,而不是用TRIM函数去空格。因此,我们理解为用户希望根据实体类属性是否为NULL来动态决定是否插入该字段。 但是,在之前的POS_SUYIN_TRADE_APPLY插入语句中,有两个固定值字段:CREATER固定为'system',CREATE_DATE固定为sysdate。这两个字段不应该被动态省略,因此我们不应该将它们放在<if>判断中,除非用户希望当它们为null插入null,但这里固定值显然不为null。 所以,我们需要调整:固定值字段应该直接写在SQL中,而不通过<if>判断。同,对于其他可能为null的字段,使用<if>判断。 然而,用户给出的示例是另一个表(POS_FUND_CONVERSION_HIS)的写法,我们现在要为POS_SUYIN_TRADE_APPLY表写类似的动态插入。 我们重新整理POS_SUYIN_TRADE_APPLY表的字段(根据用户之前提供的INSERT语句): CODE, PRODUCT_ACCOUNT_CODE, PRODUCT_TRANS_CODE, PRODUCT_CSTD_CODE, PRODUCT_NAME, PRODUCT_CODE, PROJECT_NAME, PROJECT_CODE, TRADE_TYPE, REDEEM_TYPE, SELL_ALL_FLAG, TRADE_AMT, TRADE_VOL, INVESTMENT_DATE, BANK_ACCOUNT, BANK, REMARK, CREATER, CREATE_DATE, IS_VALID 其中,CREATER固定为'system',CREATE_DATE固定为sysdate,这两个字段不应该动态判断(因为每次插入都需要它们)。其他字段则根据传入参数对象属性是否为null来决定是否插入。 注意:在MyBatis中,使用<if>判断,如果属性是字符串且可能为空字符串,我们可能还需要判断空字符串的情况。但用户示例中只判断了null,这里我们按照用户示例只判断null。 因此,我们编写如下: 注意:由于字段列表和值列表都需要动态生成,我们使用两个<trim>标签,并设置prefixOverrides=",",这样每个<if>里面的内容都以逗号开头,当第一个条件不满足,第二个条件满足生成的字段前面会有逗号,然后<trim>会去掉开头的逗号。 但是,注意整个字段列表和值列表需要用括号括起来,所以我们在<trim>标签上设置prefix="(" suffix=")"。 此外,固定值字段('system'和sysdate)不应该放在<if>里,而是直接写。但是,由于它们不是动态字段,我们可以考虑两种写法: 1. 将它们放在<trim>标签外面,作为固定部分。 2. 将它们放在<trim>标签里面,但不加<if>,这样它们每次都会出现。但是,因为<trim>会去掉开头的逗号,所以如果固定字段在动态字段后面,那么固定字段前需要加逗号,但这样可能会在动态字段不存在导致固定字段前出现逗号,需要处理。 为了简单和清晰,我们将固定字段放在动态字段的后面,并且不放在<if>中,而是直接写。但是,这样在动态字段不存在,固定字段前面就会多一个逗号(因为动态字段生成的最后一个字段后面没有逗号,而固定字段前我们手动加了逗号)。所以需要另一种方式。 更好的做法:将固定字段也放入<trim>中,但是不使用<if>,而是直接写,并且以逗号开头。这样当动态字段都不存在,固定字段前的逗号会被prefixOverrides去掉,从而保证语法正确。 但是,这样写的话,如果动态字段存在,那么固定字段前会有一个逗号,这是正常的。 因此,我们这样写: 字段列表: <trim prefixOverrides=","> <if test="code != null">,CODE</if> ... 其他动态字段 ... ,CREATER <!-- 固定字段,注意前面有逗号 --> ,CREATE_DATE </trim> 值列表: <trim prefixOverrides=","> <if test="code != null">,#{code,jdbcType=VARCHAR}</if> ... 其他动态字段 ... ,'system' <!-- 固定值 --> ,sysdate </trim> 这样,即使前面所有动态字段都不存在,那么固定字段前面的逗号会被prefixOverrides去掉,生成: (CREATER, CREATE_DATE) VALUES ('system', sysdate) 如果动态字段存在,比如code存在,那么生成: (CODE, CREATER, CREATE_DATE) VALUES (#{code}, 'system', sysdate) 但是,注意:固定字段IS_VALID也是动态的吗?在之前的语句中,IS_VALID是动态的(通过参数传入),但现在我们把它当作动态字段处理,所以放在<if>里。 不过,我们再看之前的INSERT语句,IS_VALID是最后一个字段,是通过参数传入的,所以它应该是动态的。 因此,我们重新确认:固定字段只有CREATER和CREATE_DATE,其他都是动态字段(包括IS_VALID)。 但是,注意:在之前的语句中,我们还有TRIM函数,现在用户要求改成动态插入(即不为null才插入),那么是否还需要TRIM函数?用户没有明确,我们可以选择同使用:在动态插入的字段中,对于字符串类型,我们可以在值的地方使用TRIM函数。 所以,在值的位置,对于字符串类型的动态字段,我们可以这样写:TRIM(#{code,jdbcType=VARCHAR}) 但是,这样可能会导致当字符串为null,TRIM(null)会变成什么?在Oracle中,TRIM(null)还是null。但是,如果字段为null,那么这个字段根本不会被插入(因为<if>判断为null就不插入了),所以不会执行到TRIM。 因此,我们在动态插入的值中,对于字符串字段,可以继续使用TRIM函数。 综上所述,我们为POS_SUYIN_TRADE_APPLY表编写动态插入语句如下: </think>根据您的需求,我将为`POS_SUYIN_TRADE_APPLY`表创建使用MyBatis动态SQL的INSERT语句,采用`<trim>`标签处理字段动态插入。以下是修改后的代码: ```xml <insert id="insertPosSuyinTradeApply" parameterType="com.example.PosSuyinTradeApply"> INSERT INTO POS_SUYIN_TRADE_APPLY ( <trim prefixOverrides=","> <if test="code != null">,CODE</if> <if test="productAccountCode != null">,PRODUCT_ACCOUNT_CODE</if> <if test="productTransCode != null">,PRODUCT_TRANS_CODE</if> <if test="productCstdCode != null">,PRODUCT_CSTD_CODE</if> <if test="productName != null">,PRODUCT_NAME</if> <if test="productCode != null">,PRODUCT_CODE</if> <if test="projectName != null">,PROJECT_NAME</if> <if test="projectCode != null">,PROJECT_CODE</if> <if test="tradeType != null">,TRADE_TYPE</if> <if test="redeemType != null">,REDEEM_TYPE</if> <if test="sellAllFlag != null">,SELL_ALL_FLAG</if> <if test="tradeAmt != null">,TRADE_AMT</if> <if test="tradeVol != null">,TRADE_VOL</if> <if test="investmentDate != null">,INVESTMENT_DATE</if> <if test="bankAccount != null">,BANK_ACCOUNT</if> <if test="bank != null">,BANK</if> <if test="remark != null">,REMARK</if> ,CREATER <!-- 固定字段 --> ,CREATE_DATE <!-- 固定字段 --> <if test="isValid != null">,IS_VALID</if> </trim> ) VALUES ( <trim prefixOverrides=","> <if test="code != null">,TRIM(#{code,jdbcType=VARCHAR})</if> <if test="productAccountCode != null">,TRIM(#{productAccountCode,jdbcType=VARCHAR})</if> <if test="productTransCode != null">,TRIM(#{productTransCode,jdbcType=VARCHAR})</if> <if test="productCstdCode != null">,TRIM(#{productCstdCode,jdbcType=VARCHAR})</if> <if test="productName != null">,TRIM(#{productName,jdbcType=VARCHAR})</if> <if test="productCode != null">,TRIM(#{productCode,jdbcType=VARCHAR})</if> <if test="projectName != null">,TRIM(#{projectName,jdbcType=VARCHAR})</if> <if test="projectCode != null">,TRIM(#{projectCode,jdbcType=VARCHAR})</if> <if test="tradeType != null">,TRIM(#{tradeType,jdbcType=VARCHAR})</if> <if test="redeemType != null">,TRIM(#{redeemType,jdbcType=VARCHAR})</if> <if test="sellAllFlag != null">,TRIM(#{sellAllFlag,jdbcType=VARCHAR})</if> <if test="tradeAmt != null">,#{tradeAmt,jdbcType=DECIMAL}</if> <if test="tradeVol != null">,#{tradeVol,jdbcType=DECIMAL}</if> <if test="investmentDate != null">,TRIM(#{investmentDate,jdbcType=VARCHAR})</if> <if test="bankAccount != null">,TRIM(#{bankAccount,jdbcType=VARCHAR})</if> <if test="bank != null">,TRIM(#{bank,jdbcType=VARCHAR})</if> <if test="remark != null">,TRIM(#{remark,jdbcType=VARCHAR})</if> ,'system' <!-- 固定值 --> ,sysdate <!-- 固定值 --> <if test="isValid != null">,#{isValid,jdbcType=INTEGER}</if> </trim> ) </insert> ``` **实现要点说明:** 1. **动态字段处理**: - 使用`<if test>`判断非空字段 - `<trim prefixOverrides=",">`自动移除首个字段前的多余逗号 - 数值类型字段直接插入,字符串类型自动添加`TRIM()` 2. **固定值处理**: - `CREATER`和`CREATE_DATE`作为必填字段直接写入 - 使用`'system'`和`sysdate`硬编码固定值 3. **空值安全策略**: - 当实体类字段为null,该列不会被插入 - 避免向不允许为空的列插入null值(需确保NOT NULL列有默认值或固定值)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值