mybatis xml 配置中,jdbcType=VARCHAR 的作用

    @Select("""
            <script>
                select u.id,username,realname,usetype,ci1.ConstantName usetypeName,
                	doctitleId,ci.ConstantName AS docTitle,
                	isscheduling,deptid,d.DeptName dept,
                	registLeID,r.RegistName registLe
                from
                	USER u
                	INNER JOIN constantitem ci1 ON u.usetype = ci1.ID
                    INNER JOIN constantitem ci ON u.DocTitleID = ci.ID
                    INNER JOIN department d ON u.DeptID = d.ID
                    INNER JOIN registlevel r ON u.RegistLeID = r.ID
                    <where>
                        and u.DelMark=1
                        <if test='userType != null and userType!=""' >
                            and `usetype`=#{userType}
                        </if>
                        <if test='dept != null and dept!=""' >
                            and u.deptid=#{dept}
                        </if>
                        <if test='docType != null and docType!=""' >
                            and u.doctitleId=#{docType}
                        </if>
                        <if test='keyword != null and keyword!=""'>
                            and `username` like CONCAT(CONCAT('%', #{keyword,jdbcType=VARCHAR}), '%')
                            or `realname` like CONCAT(CONCAT('%', #{keyword,jdbcType=VARCHAR}), '%')
                        </if>
                    </where>
            </script>
            """)
    Page<UserVo> selectPage(Page<UserVo> page, String keyword, String userType, String dept, String docType);

jdbcType=VARCHAR 的作用与意义

在 MyBatis 中,jdbcType=VARCHAR 是一种参数类型映射配置,主要用于解决 Java 类型 与 JDBC 类型 之间的转换问题。具体解释如下:

一、为什么需要 jdbcType

  1. Java 与数据库类型不匹配
    例如,Java 中的 String 类型在数据库中可能对应 VARCHARCHARTEXT 等多种类型。MyBatis 需要明确知道如何将 Java 对象转换为 JDBC 类型,以便正确地传递给数据库。

  2. 处理 NULL 值
    当参数为 NULL 时,MyBatis 需要知道用哪种 JDBC 类型的 NULL 来处理。例如,NULL 可能是 VARCHAR 类型的 NULL,也可能是 INTEGER 类型的 NULL

二、jdbcType=VARCHAR 的具体作用

set password=#{newPwd,jdbcType=VARCHAR}

  • 明确参数类型:告诉 MyBatis 将 newPwd 参数作为 JDBC 的 VARCHAR 类型 传递给数据库。
  • 防止类型转换错误:确保密码字符串正确地映射到数据库的 VARCHAR 字段,避免因类型不匹配导致的 SQL 错误。
  • 处理 NULL 值:如果 newPwd 为 null,MyBatis 会将其转换为 JDBCType.NULL,并标记为 VARCHAR 类型的 NULL

三、常见的 JDBC 类型映射

MyBatis 支持的部分 jdbcType 取值:

JDBC 类型对应 Java 类型
VARCHARString
INTEGERIntegerint
DECIMALBigDecimal
DATEjava.util.Date
TIMESTAMPjava.sql.Timestamp
NULLnull 值

四、实际应用场景

  1. 必填字段
    对于数据库中不允许为 NULL 的字段(如 NOT NULL 约束),建议显式指定 jdbcType,避免因 NULL 值处理不当导致的 SQL 异常。

  2. 特殊类型
    对于 ENUMJSON 等特殊数据库类型,需要通过 jdbcType 明确指定,例如:

    #{jsonData, jdbcType=VARCHAR}  <!-- 假设 JSON 存储为 VARCHAR -->
    
  3. 防止 SQL 注入
    虽然 MyBatis 默认使用预编译语句(PreparedStatement),但明确 jdbcType 可以进一步确保参数类型安全。

五、在现代 MyBatis 中的使用建议

  • 简化配置:在大多数情况下,MyBatis 可以自动推断参数类型,因此 jdbcType 通常可以省略。例如:

    set password=#{newPwd}  <!-- 省略 jdbcType 也可以正常工作 -->
    
  • 显式指定的场景

    • 处理 NULL 值时(特别是数据库字段不允许为 NULL)。
    • 与存储过程交互时。
    • 使用特殊数据库类型(如 JSONARRAY)时。
我用的是mybatis,<?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.smics.apps.iw.gv.mapper.ohsapp.IwAppGvVisitInfoMapper"> <sql id="allField"> SELECT v.ID as "id", v.CASE_NO as "caseNo", v.VISIT_TYPE as "visitType", v.VISIT_TOPIC as "visitTopic", v.VISIT_COMPANY as "visitCompany", v.VISIT_TIME as "visitTime", v.CONTACT as "contact", v.GREETER as "greeter", v.CREATE_DATE as "createDate", v.UPDATE_TIME as "updateTime", v.UPDATE_BY as "updateBy", v.STATUS as "status", v.CREATE_BY as "createBy", v.SUBMIT_BY as "submitBy", v.SUBMIT_TIME as "submitTime", v.CHANGE_STEP_TIME as "changeStepTime", v.GATHER_LOC as "gatherLoc", v.INSPECTION_LOC as "inspectionLoc", v.DETAIL_DESC as "detailDesc", v.INLINE_INSPECTION as "inlineInspection", v.OFFLINE_INSPECTION as "offlineInspection", v.ATTENDEE as "attendee", v.INVOLVED_GROUP as "involvedGroup", v.PHONE as "phone" </sql> <select id="getVisitInfoList" resultType="com.smics.apps.iw.gv.entity.IwAppGvVisitInfo"> <include refid="allField"></include> FROM IW_APP_GV_VISIT_INFO v <where> <if test="cm.caseNo != null and cm.caseNo != ''"> and v.CASE_NO like '%${cm.caseNo}%' </if> <if test="cm.loginEmpNo != null and cm.loginEmpNo != ''"> and (select count(*) from IW_APP_GV_SIGN_STATUS s where s.FORM_ID = v.ID and s.EMP_NO = #{cm.loginEmpNo})> 0 </if> <if test="cm.statusList != null"> and v.STATUS in ( <foreach collection="cm.statusList" item="item" separator=","> #{item} </foreach> ) </if> </where> order by v.CREATE_DATE desc </select> <select id="getVisitInfoById" resultType="com.smics.apps.iw.gv.entity.IwAppGvVisitInfo"> <include refid="allField"></include> FROM IW_APP_GV_VISIT_INFO v where v.ID = #{id} order by v.CREATE_DATE desc </select> <select id="getDistinctVisitCompanyList" resultType="java.lang.String"> select distinct VISIT_COMPANY FROM IW_APP_GV_VISIT_INFO </select> <select id="getCaseNoList" resultType="java.lang.String"> select CASE_NO FROM IW_APP_GV_VISIT_INFO where CASE_NO like '${caseNoPre}%' order by CASE_NO desc </select> <insert id="insert" parameterType="com.smics.apps.iw.gv.entity.IwAppGvVisitInfo"> <selectKey keyProperty="cm.id" resultType="long" order="BEFORE"> SELECT hibernate_sequence.nextval FROM dual </selectKey> INSERT INTO IW_APP_GV_VISIT_INFO (ID, CASE_NO, VISIT_TYPE, VISIT_TOPIC, VISIT_COMPANY, VISIT_TIME, CONTACT, GREETER, CREATE_DATE, UPDATE_TIME, UPDATE_BY,STATUS,CREATE_BY,SUBMIT_BY,SUBMIT_TIME,CHANGE_STEP_TIME,GATHER_LOC,INSPECTION_LOC, DETAIL_DESC, INLINE_INSPECTION, OFFLINE_INSPECTION, ATTENDEE,INVOLVED_GROUP,PHONE) VALUES (#{cm.id,jdbcType=NUMERIC}, #{cm.caseNo,jdbcType=VARCHAR}, #{cm.visitType,jdbcType=VARCHAR}, #{cm.visitTopic,jdbcType=VARCHAR},#{cm.visitCompany,jdbcType=VARCHAR},#{cm.visitTime,jdbcType=VARCHAR}, #{cm.contact,jdbcType=VARCHAR}, #{cm.greeter,jdbcType=VARCHAR}, #{cm.createDate,jdbcType=DATE}, #{cm.updateTime,jdbcType=DATE}, #{cm.updateBy,jdbcType=VARCHAR},#{cm.status,jdbcType=VARCHAR}, #{cm.createBy,jdbcType=VARCHAR},#{cm.submitBy,jdbcType=VARCHAR},#{cm.submitTime,jdbcType=DATE}, #{cm.changeStepTime,jdbcType=DATE},#{cm.gatherLoc,jdbcType=VARCHAR},#{cm.inspectionLoc,jdbcType=VARCHAR},#{cm.detailDesc,jdbcType=VARCHAR}, #{cm.inlineInspection,jdbcType=VARCHAR},#{cm.offlineInspection,jdbcType=VARCHAR},#{cm.attendee,jdbcType=VARCHAR}, #{cm.involvedGroup,jdbcType=VARCHAR},#{cm.phone,jdbcType=VARCHAR}) </insert> <update id="updateById"> UPDATE IW_APP_GV_VISIT_INFO SET CASE_NO = #{cm.caseNo,jdbcType=VARCHAR} , VISIT_TYPE= #{cm.visitType,jdbcType=VARCHAR} , VISIT_TOPIC= #{cm.visitTopic,jdbcType=VARCHAR} , VISIT_COMPANY= #{cm.visitCompany,jdbcType=VARCHAR} , CONTACT=#{cm.contact,jdbcType=VARCHAR} , UPDATE_TIME=#{cm.updateTime,jdbcType=DATE} , UPDATE_BY= #{cm.updateBy,jdbcType=VARCHAR} , STATUS= #{cm.status,jdbcType=VARCHAR} , SUBMIT_BY = #{cm.submitBy,jdbcType=VARCHAR} , SUBMIT_TIME = #{cm.submitTime,jdbcType=DATE} , CHANGE_STEP_TIME = #{cm.changeStepTime,jdbcType=DATE} , GATHER_LOC = #{cm.gatherLoc,jdbcType=VARCHAR} , VISIT_TIME = #{cm.visitTime,jdbcType=VARCHAR} , INSPECTION_LOC = #{cm.inspectionLoc,jdbcType=VARCHAR} , DETAIL_DESC = #{cm.detailDesc,jdbcType=VARCHAR} , INLINE_INSPECTION = #{cm.inlineInspection,jdbcType=VARCHAR} , OFFLINE_INSPECTION = #{cm.offlineInspection,jdbcType=VARCHAR} , ATTENDEE = #{cm.attendee,jdbcType=VARCHAR} , INVOLVED_GROUP = #{cm.involvedGroup,jdbcType=VARCHAR} , PHONE = #{cm.phone,jdbcType=VARCHAR} where ID = #{cm.id,jdbcType=NUMERIC} </update> <update id="ignoreUpdateById"> UPDATE IW_APP_GV_VISIT_INFO SET VISIT_TYPE= COALESCE(#{cm.visitType,jdbcType=VARCHAR}, VISIT_TYPE), VISIT_TOPIC= COALESCE(#{cm.visitTopic,jdbcType=VARCHAR}, VISIT_TOPIC), VISIT_COMPANY= COALESCE(#{cm.visitCompany,jdbcType=VARCHAR}, VISIT_COMPANY), VISIT_TIME=COALESCE(#{cm.visitTime,jdbcType=VARCHAR}, VISIT_TIME), CONTACT=COALESCE(#{cm.contact,jdbcType=VARCHAR}, CONTACT), GREETER=#{cm.greeter,jdbcType=VARCHAR}, CREATE_DATE=COALESCE(#{cm.createDate,jdbcType=DATE}, CREATE_DATE), UPDATE_TIME=COALESCE(#{cm.updateTime,jdbcType=DATE}, UPDATE_TIME), UPDATE_BY= COALESCE(#{cm.updateBy,jdbcType=VARCHAR}, UPDATE_BY), STATUS= COALESCE(#{cm.status,jdbcType=VARCHAR}, STATUS), SUBMIT_BY = COALESCE(#{cm.submitBy,jdbcType=VARCHAR}, SUBMIT_BY), SUBMIT_TIME =COALESCE(#{cm.submitTime,jdbcType=DATE}, SUBMIT_TIME), CHANGE_STEP_TIME = COALESCE(#{cm.changeStepTime,jdbcType=DATE}, CHANGE_STEP_TIME), GATHER_LOC = COALESCE(#{cm.gatherLoc,jdbcType=VARCHAR}, GATHER_LOC), INSPECTION_LOC= COALESCE(#{cm.inspectionLoc,jdbcType=VARCHAR}, INSPECTION_LOC), DETAIL_DESC= COALESCE(#{cm.detailDesc,jdbcType=VARCHAR}, DETAIL_DESC), INLINE_INSPECTION= COALESCE(#{cm.inlineInspection,jdbcType=VARCHAR}, INLINE_INSPECTION), OFFLINE_INSPECTION= COALESCE(#{cm.offlineInspection,jdbcType=VARCHAR}, OFFLINE_INSPECTION), ATTENDEE= COALESCE(#{cm.attendee,jdbcType=VARCHAR}, ATTENDEE), INVOLVED_GROUP = COALESCE(#{cm.involvedGroup,jdbcType=VARCHAR}, INVOLVED_GROUP), PHONE = COALESCE(#{cm.phone,jdbcType=VARCHAR}, PHONE) where ID = #{cm.id,jdbcType=NUMERIC} </update> <delete id="deleteById"> delete from IW_APP_GV_VISIT_INFO where ID = #{id} </delete> </mapper>
09-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值