常規SSM框架開發中,mybatis遇到的坑是最多的,把以下幾點坑記錄下來防止以后再遇到同樣的情況。
1、mybatis 若果在mapper中返回值沒有配置resultMap而是使用resultType直接返回的話,那么當心默認配置中的駝峰匹配規則,參考以下配置文件。該情況適用于bean屬性字段和數據庫完全一致且字段名帶有下劃線如(user_menu)這樣的字段時
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/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="main.com.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的封裝,添加了很多易用性的功能,它既是一個框架也可以算作一種規范了,不過不要被它限制死了,要學會使用它而不是被它使用。