常规SSM框架开发中,mybatis遇到的坑是最多的,把以下几点坑记录下来防止以后再遇到同样的情况。
1、mybatis 若果在mapper中返回值没有配置resultMap而是使用resultType直接返回的话,那么当心默认配置中的驼峰匹配规则,参考以下配置文件。该情况适用于bean属性字段和数据库完全一致且字段名带有下划线如(user_menu)这样的字段时
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration PUBLIC "-////DTD Config 3.0//EN" "/dtd/mybatis-3-config.dtd"><configuration><settings><setting name="callSettersOnNulls" value="true"/><setting name="cacheEnabled" value="true"/><setting name="lazyLoadingEnabled" value="true"/><setting name="aggressiveLazyLoading" value="true"/><setting name="multipleResultSetsEnabled" value="true"/><setting name="useColumnLabel" value="false"/><setting name="useGeneratedKeys" value="false"/><setting name="autoMappingBehavior" value="PARTIAL"/><setting name="defaultExecutorType" value="SIMPLE"/><!-- 禁用掉驼峰规则,不然实体类带下划线的都匹配不上 --><setting name="mapUnderscoreToCamelCase" value="false"/><setting name="localCacheScope" value="SESSION"/><setting name="jdbcTypeForNull" value="NULL"/><setting name="autoMappingUnknownColumnBehavior" value="FAILING"/><!--自定义日志类--><setting name="logImpl" value=".log.MyBatisLogImpl" /> </settings><typeAliases><typeAlias alias="Integer" type="java.lang.Integer"/><typeAlias alias="Long" type="java.lang.Long"/><typeAlias alias="String" type="java.lang.String"/><typeAlias alias="HashMap" type="java.util.HashMap"/><typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap"/><typeAlias alias="ArrayList" type="java.util.ArrayList"/><typeAlias alias="LinkedList" type="java.util.LinkedList"/><!-- 自定义实体类 --></typeAliases></configuration>
2、mybatis想要打印sql,如果按照常规配置是无法打印的,
如果这样配置,sql可以打印,但是无法进入文件。
<setting name="logImpl" value="STDOUT_LOGGING " />
或者
<setting name="logImpl" value="SLF4J" />
但是有时候会失效
因为本人使用logback做日志管理,因此也无法用log4j来实现sql的打印。
这时候就需要重写log打印功能
@Component
mybatis 配置
<setting name="logImpl" value="xx.xx.MyBatisLogImpl" />
3、有的时候mybatis需要调用oracle存储过程,而这个存储过程的参数还是一个自定义的oracle类型。
private
这里要注意:1、oracle的自定义类型和自定义列表必须是全局的,不能是pkg里面的,否则不识别。
2、本人没有找到使用Mybatis的自定义typeHandler来进行参数拼接方案,尤其是跨用户执行存储过程的时 候,使用typeHandler往往是匹配不上的,他会莫名其妙把你JDBC的用户名给带上去,所以我暂定的方案是直接拿连接池里面的连接直接操作数据库。
4、JDBC连接池拿到的连接有的时候需要转成oracle的connection或者mysql的connection,如果你直接close转换之后的连接实例是没用的,因为数据连接池的连接并没有关闭掉,而且调用连接池连接的关闭方法也不是真的关闭,而是放回至连接池中,所以如果要做转换,记得分两步,拿到连接池连接实例,操作完之后记得close掉。
5、这个相对大头一些,有的时候(通常是连oracle这种数据库),我们要导出大量数据到excel,如果数据量比较大,比如大概3、4 十万行,每行100多列的这种情况。
如果用常规的导出办法,也就是查到list中再传入poi进行处理,是会报堆溢出的,很明显list里面放那么多数据根本就放不下。那解决办法就是边查边导,这时候需要重写ResultHandler,按照自定义返回值处理的方式进行处理。
个人解决方案是,在service方法中写一个方法域内的全局list,逐条插入数据,当list.size()达到500的时候,将里面的数据用poi导到文档,清空list。往复循环,直到数据全部被插入到excel为止。
这里poi有几个特定的配置强调一下:
1、final SXSSFWorkbook sbook = new SXSSFWorkbook(100);
workboox实例要用SXSSFWorkbook初始化,常规的最大行数就到Integer.MAX_VALUE (65535)了,超过就溢出。
构造方法参数是内存缓存100条,超过就写入临时文件了,如果列超级多的话建议设置小点儿,但是不能不设置,不设置就是不限制了。
2、sbook.setCompressTempFiles(true); //要开启写入临时文件这个功能。
以上就是Mybatis遇到的几个比较大的坑,小来小去的错误就不在这写了,当然也可能有一些更大的坑被遗漏掉了,以后再慢慢捡吧。其实mybatis的本质就是一个常规JDBC的封装,添加了很多易用性的功能,它既是一个框架也可以算作一种规范了,不过不要被它限制死了,要学会使用它而不是被它使用。