只是遇到了才记录一下,主要是备忘。

$ 与 # 的区别

# 会当做参数处理,有安全检查,可有效防止恶意攻击,而 $ 则是直接替换。

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&amp;useUnicode=true&amp;characterEncoding=utf8&amp;allowMultiQueries=true&amp;autoReconnect=true&amp;failOverReadOnly=false&amp;socketTimeout=20000&amp;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
2
select sms_remain_amount from rt_biz
where biz_id = #{sellerID,jdbcType=BIGINT}

mapper.xml 配置的包名如果不对,会提示相关的类找不到

1
2
Caused by: java.lang.ClassNotFoundException: Cannot find class: mis.api.biz.dal.fin.request.FinanceNewStudentRequest
Caused by: org.apache.ibatis.type.TypeException: Could not resolve type alias 'mis.api.biz.dal.fin.request.FinanceNewStudentRequest'. Cause: java.lang.ClassNotFoundException: Cannot find class: mis.api.biz.dal.fin.request.FinanceNewStudentRequest

原因是在 mapper.xml 里对应的 pojo 的包名改了,xml 没有同步修改。

将 xml 文件放到源码(src)下

1
2
3
4
5
2019-06-19 10:12:11.592 ERROR 10756 --- [p-nio-90-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : 
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): demo.domain.dal.mapper.original.SysDeptMapper.selectByExample] with root cause

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): demo.domain.dal.mapper.original.SysDeptMapper.selectByExample
at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235) ~[mybatis-3.5.1.jar:3.5.1]

解决

在项目的 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 的异常

  1. mapper.xml中没有加入namespace
  2. mapper.xml中的方法和接口mapper的方法不对应
  3. mapper.xml没有加入到mybatis-config.xml中(即总的配置文件),例外:配置了mapper文件的包路径的除外
  4. 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 日志级别

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);