Mybatis容易遇到的问题

本文围绕MyBatis展开,介绍了#和$的区别、编程步骤,分析了JDBC编程不足及MyBatis的解决办法,阐述了Mapper接口调用要求,讲解了一级和二级缓存机制及数据更新机制,还说明了在MySQL和Oracle中insert插入数据操作返回主键ID的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.MyBatis中#和$的区别?

 1.使用#的原理是?占位符,而$的原理为直接字符串拼接方式

    2.$方式一般使用在写数据库中的固定字段时候才会使用例如表名或者列名(select * from user order by xxx)这个中的xxx可以使用$

 3.#可以防止注入,$不能防止sql注入

 4.一般情况下能使用#就不适用$.

2.MyBatis的编程步骤是什么样的?

  1.创建SqlSessionFactory

  2.通过sqlSessionFactory创建SqlSession

  3.通过sqlSession执行数据库操作.

  4.调用session.commit()提交事务

  5.调用sessioin.close()关闭会话

3.JDBC编程有那些不足之处,NyBatis是如何解决的?

1.数据库的创建,释放频繁造成系统资源浪费从而影响性能,如果使用数据库连接池可解决此问题.

  解决:在Sqlmapconfig.xml中配置数据连接池,使用连接池管理数据库连接

2.sql语句写在代码中造成代码不易维护,实际用sql变化大,sql变动需要改变java代码

  解决:将sql语句配置在xxxmapper.xml文件中与java代码分离.

3.向sql语句传参麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应.

  解决:mybatis自动将java对象映射至sql语句.

4.对结果即解析麻烦,sql变化导致解析代码变化,且解析前需要进行遍历,如果能将数据库记录封装成pojo对象解析还比较方便.

  解决:mybatis自动将sql执行结果映射至java对象

4.使用mybatis的mapper接口调用时有那些要求?

  1.Mapper.xml文件中的namespace即是mapper接口的类路径

  2.Mapper接口方法名和mapper.xml中定义的每个sql的id相同

  3.Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同.

  4.Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同.

MyBatis中一级缓存和二级缓存?

1.一级缓存:基于perpetualCache的HashMap本地缓存,其存储作用域为session,当session flush或者close()之后,该session中的所有cache将清空.

2.二级缓存和一级缓存其机制相同,默认也是采用PerpetualCache,HashMap存储,不同在于其存储作用域为Mapper(NameSpace),并且可自定义存储源,如Ehcache.作用域为namespace是指该namespace对应的配置文件中所有的select操作结果都缓存,这样不同于线程之间就可以共用二级缓存,启动二级缓存:在mapper配置文件中<cache/>

  二级缓存可以设置返回的缓存对象策略:<cache readOnly="true">.当readOnly="true"时,表示二级缓存返回给所有调用者同一个缓存对象实例,调用者可以update获取的缓存实例,但是这样可能造成其他调用者出现数据不一致的情况(因为所有调用的是同一个实例).当readOnly=false时,返回给调用者的是二级缓存总缓存对象的拷贝,即不同调用者获取的是缓存对象的不同实例,这样调用者对各自的缓存对象的修改不会影响到其他的调用者,即是安全的,所以默认是readOnly="false"

3.对于缓存数据更新机制,当某一个作用域(一级缓存session/二级缓存namespaces)的进行了cud操作后,默认该作用域下所有select中的缓存将被clear'

6.Mybstis在insert插入数据操作时返回主键ID?

数据库为mysql时:

  

<insert id="insertUser" parameterType="com.qingmu.pojo.User" useGeneratedKeys="true" keyProperty="id">
        <!--<selectKey keyProperty="id" order="AFTER" resultType="int">-->
            <!--select LAST_INSERT_ID()-->
        <!--</selectKey>-->
        insert into USER VALUES (#{id},#{username},#{sex},#{birthday},#{address})
    </insert>

keyproperty表示返回的id要保存到对象的那个属性中,useGeneratedKeys表示主键id为自增长模式.Mysql中做上配置就可以了.

数据库为Oracle时"

"

 

 由于Oracle没有自增长这一说,只有序列这种模仿自增的形式,所以不能再使用UserGeneratedKeys属性,而是使用selectKey将Id获取并赋值到对象的属性中,insert插入操作时正常插入id

 

转载于:https://www.cnblogs.com/qingmuchuanqi48/p/10921019.html

<think>好的,我现在需要帮用户解决MyBatis中字符串判断的问题,用户还提到了用法和常见问题的解决方案。首先,我得回忆一下MyBatis的动态SQL处理,特别是和字符串相关的部分。 根据用户提供的引用,特别是引用[3]和[4],看来常见的问题包括动态SQL中的条件判断、字符串拼接导致的SQL注入风险,以及参数替换时的转义问题。用户可能遇到的情况比如在判断字符串是否为空、如何处理传入的字符串参数,或者在排序、动态字段中出现的错误。 首先,MyBatis的动态SQL标签,比如<if>、<choose>、<when>、<otherwise>,这些都是处理条件判断的关键。用户可能想知道如何在XML映射文件中正确使用这些标签来判断字符串的值。比如,如何判断一个字符串参数是否等于某个特定值,或者是否为空。 然后,常见问题可能涉及字符串比较时的转义问题,比如在引用[4]中提到,使用#{}会导致MyBatis对字符串进行转义,可能影响排序字段的处理。这时候可能需要使用${}来直接替换,但又有SQL注入的风险。需要权衡两者的使用场景。 另外,用户提到的字符串判断还可能包括处理空字符串和null值。MyBatis提供了<isNull>、<isNotNull>、<isEmpty>、<isNotEmpty>这些标签,但需要注意它们的区别。比如,<isNotEmpty>会检查字符串是否为null且长度大于零,而用户可能需要正确使用这些标签来避免逻辑错误。 还可能遇到的问题是,当使用OGNL表达式判断字符串时,单引号和双引号的使用。例如,在test条件中,判断字符串参数是否等于某个值,可能需要写成test='param == "value"',这里的引号嵌套容易出错,需要特别注意。 此外,用户可能遇到动态SQL拼接后的SQL语句不符合预期,比如参数被错误地添加了引号,导致SQL语法错误。比如在排序时,如果使用#{}传入字段名,会被转义成字符串,导致ORDER BY 'loginName' DESC,这显然是错误的。这时候需要改用${},但要注意防止SQL注入。 解决方案方面,需要指导用户正确使用动态SQL标签,区分#{}和${}的适用场景,处理空值和空字符串,以及如何防止SQL注入。比如,在需要动态字段名或排序方式时,使用${}但要严格校验参数,避免用户输入恶意内容。 可能还需要提到自定义类型处理器,如引用[3]中的示例,处理特殊字符串的情况,或者使用函数来处理字符串,比如trim、concat等,避免SQL注入。 总结下来,回答的结构应该包括基本用法(条件判断、空值处理)、常见问题(转义问题、SQL注入、空值判断错误)以及解决方案(正确使用标签、选择参数替换方式、校验输入)。同时,引用提供的资料中的例子,比如示例中的<if>和<choose>标签,以及引用[4]中的参数处理问题,来增强回答的可信度。</think>### MyBatis字符串判断用法及常见问题解决方案 #### 一、基本用法 1. **条件判断** 使用`<if>`、`<choose>`等标签进行字符串判断,需注意**OGNL表达式语法**: ```xml <select id="selectUser"> SELECT * FROM user <where> <if test="name != null and name != ''"> AND name = #{name} </if> <choose> <when test="role == 'admin'"> AND level > 10 </when> <otherwise> AND level <= 10 </otherwise> </choose> </where> </select> ``` - `test`属性中的字符串比较需用单引号包裹:`test='role == "admin"'`[^3]。 - `name != ''`表示过滤空字符串。 2. **空值判断** 使用`<isNull>`、`<isNotEmpty>`等标签: ```xml <if test="param != null"> <!-- 检查参数是否为null --> <isNotEmpty property="param"> <!-- 检查参数非null且非空字符串 --> ``` --- #### 二、常见问题与解决方案 1. **字符串转义问题** - **现象**:使用`#{}`传递排序字段时,SQL变为`ORDER BY 'loginName' DESC`,导致语法错误[^4]。 - **原因**:`#{}`会对字符串添加引号,适用于值传递,但字段名需直接替换。 - **解决**:改用`${param}`,但需严格校验参数防止SQL注入。 ```xml ORDER BY ${sortField} ${sortOrder} ``` 2. **空字符串与NULL混淆** - **现象**:`<if test="param != null">`未生效,因参数可能为空字符串。 - **解决**:联合判断: ```xml <if test="param != null and param != ''"> ``` 3. **SQL注入风险** - **场景**:动态拼接字段名时使用`${}`。 - **方案**: - 白名单校验:仅允许预定义的字段名(如`loginName`、`createTime`)。 - 使用`@Param`注解明确参数类型: ```java List<User> selectByField(@Param("field") String field); ``` 4. **特殊字符处理** - **问题**:字符串包含`<`、`>`等符号导致XML解析错误。 - **方案**: - 使用CDATA包裹: ```xml <![CDATA[ AND content LIKE '%<test>%' ]]> ``` - 自定义类型处理器转义特殊字符。 --- #### 三、实战技巧 1. **动态SQL优化** - 使用`<bind>`预处理字符串: ```xml <bind name="pattern" value="'%' + keyword + '%'" /> SELECT * FROM table WHERE name LIKE #{pattern} ``` 2. **函数处理字符串** - 在SQL中调用数据库函数(如`CONCAT`、`TRIM`): ```xml <if test="name != null"> AND TRIM(name) = #{name} </if> ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值