$ 与 # 的区别
# 会当做参数处理,有安全检查,可有效防止恶意攻击,而 $ 则是直接替换。
Table Configuration apiCallLog matched more than one table
MyBatis Generator 生成器把其他数据库的同名表也生成的问题。
在 jdbc 连接配置添加属性:<property name="nullCatalogMeansCurrent" value="true"/>
,如下:1
2
3
4
5
6
7<!--数据库链接地址账号密码-->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/apg?useSSL=false&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&autoReconnect=true&failOverReadOnly=false&socketTimeout=20000&serverTimezone=Hongkong"
userId="admin"
password="password">
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
参考:http://www.mybatis.org/generator/usage/mysql.html
MyBatis 查询某一整形字段,如果没有记录,返回什么?
返回 null
而且函数返回值应该是 Integer,如果是 int 则会引发转换异常。1
2select sms_remain_amount from rt_biz
where biz_id = #{sellerID,jdbcType=BIGINT}
mapper.xml 配置的包名如果不对,会提示相关的类找不到
1 | Caused by: java.lang.ClassNotFoundException: Cannot find class: mis.api.biz.dal.fin.request.FinanceNewStudentRequest |
原因是在 mapper.xml 里对应的 pojo 的包名改了,xml 没有同步修改。
将 xml 文件放到源码(src)下
1 | 2019-06-19 10:12:11.592 ERROR 10756 --- [p-nio-90-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : |
解决
在项目的 pom 文件中添加:1
2
3
4
5
6
7
8
9
10
11<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
还有以下可能的情况导致 not found 的异常
- mapper.xml中没有加入namespace
- mapper.xml中的方法和接口mapper的方法不对应
- mapper.xml没有加入到mybatis-config.xml中(即总的配置文件),例外:配置了mapper文件的包路径的除外
- mapper.xml文件名和所写的mapper名称不相同。
后台任务,在查询相关任务表时,需要查询满足条件的限定行数而不是满足条件的全部记录
后台任务一般每次查询固定的行数来处理数据,可以借助Example类和分页插件快速写出查询代码来,但是这样会牺牲性能,因为分页插件会去查询一次汇总。
所以,还是要自己写一个扩展来查询,如:1
2
3
4
5
6
7
8
9
10
11
12
13<select id="getTradeListForMemberSummarizing" parameterType="crm.model.view.in.TradeSearchView" resultType="crm.model.entity.CrmTrade">
select
<include refid="Base_Column_List" />
from crmTrade
<where>
countStatus = #{countStatus,jdbcType=INTEGER}
and tradeStatus in
<foreach item="tradeStatus" index="index" collection="tradeStatusList" open="(" separator="," close=")">
#{tradeStatus,jdbcType=BIGINT}
</foreach>
</where>
limit 0, #{limitCount,jdbcType=INTEGER}
</select>
MyBatis xml 文件里的条件判断
单个的字符要写到双引号里面才行,改为<if test='takeWay == "1"'>
或者改为<if test="takeWay == '1'.toString() ">
把<if test="takeWay == '1' and workday != null ">
改为<if test='takeWay == "1" and workday != null '>
或改为<if test="takeWay == '1'.toString() and workday != null ">
即可。
原因是:mybatis是用OGNL表达式来解析的,在OGNL的表达式中,‘1’会被解析成字符,java是强类型的,char 和 一个string 会导致不等,所以if标签中的sql不会被解析。
总结下使用方法:单个的字符要写到双引号里面或者使用.toString()
才行!
MyBatis if test=验证的时候发生 There is no getter for property named 'parentID' in 'class java.lang.Integer'
parameterType=”java.lang.Integer”1
2
3<if test="parentID > 0">
and parentID=#{parentID,jdbcType=INTEGER}
</if>
换成:1
2
3<if test="_parameter > 0">
and parentID=#{parentID,jdbcType=INTEGER}
</if>
如果 parameterType 对应的是 pojo 并且设置了 getter 即可正常访问属性。
mybatis 插件开发
- (快速入门)MyBatis Generator源码分析修改和自定义插件
- MyBatis Generator 基础扩展
- MyBatis Generator 1.3.4 扩展,可以设置 Mapper(Dao)后缀
mybatis 日志级别
ERROR, WARN, INFO, DEBUG or TRACE
解决mybatis动态传入order by 参数的时候不生效的问题
字符串替换
默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:
ORDER BY ${columnName}
这里MyBatis不会修改或转义字符串。
重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。
总的来说,就是order by 传参的时候要用$符号,用#不生效(尽管你在控制台看到的生成语句是正确的,但是结果就是不对!!^_^,这个记住就好了。)。
PageHelper
- PageHelper 方法使用了静态的 ThreadLocal 参数,分页参数和线程是绑定的。
- ThreadLocal 在分库分表中也有用到。
1 | PageInfo pageInfo = (PageInfo) studentQueryResponseList; |
报错:1
java.lang.ClassCastException: class com.github.pagehelper.Page cannot be cast to class com.github.pagehelper.PageInfo (com.github.pagehelper.Page and com.github.pagehelper.PageInfo are in unnamed module of loader 'app')
换一种姿势就对了~~:1
PageInfo pageInfo = new PageInfo(studentQueryResponseList);