我們使用一個新的框架難免會遇到各種問題,當然使用這款國產的優秀的Mybatis-Plus框架也不例外,下面我就給大家列舉一下使用Mybatis-Plus可能遇到的一些問題,並做一下一一的解答。
1:如何排除非表的欄位(這個問題一定要注意,我們Java中寫的Entity類的屬性是和表的欄位一一對應的,如果屬性在資料庫中沒有對應欄位程式就會出錯。當然表中可以有多的欄位)。
使用一些三種方法都可以:(開發中我們經常使用第三者方式)
使用 transient 修飾:
private transient String noColumn;
使用 static 修飾 :
private static String noColumn;
使用 TableField 註解:
@TableField(exist=false)
private String noColumn;
不要懷疑,正視自己,這個異常肯定是你插入的姿勢不對……
檢查是不是引入 jar 衝突
檢查 Mapper.java 的掃描路徑
方法一:在 Configuration 類上使用註解 MapperScan
@Configuration @MapperScan("com.yourpackage.*.mapper") public class YourConfigClass{ ... }
方法二:在Configuration類裡面,設定MapperScannerConfigurer
@Bean public MapperScannerConfigurer mapperScannerConfigurer(){ MapperScannerConfigurer scannerConfigurer = new MapperScannerConfigurer(); //可以通過環境變數獲取你的mapper路徑,這樣mapper掃描可以通過組態檔設定了 scannerConfigurer.setBasePackage("com.yourpackage.*.mapper"); return scannerConfigurer; }
檢查是否指定了主鍵?如未指定,則會導致 selectById 相關 ID 無法操作,請用註解 @TableId 註解表 ID 主鍵。當然 @TableId 註解可以沒有!但是你的主鍵必須叫 id(忽略大小寫)
SqlSessionFactory不要使用原生的,請使用MybatisSqlSessionFactory
檢查是否自定義了SqlInjector,是否複寫了getMethodList()方法,該方法裡是否注入了你需要的方法(可參考DefaultSqlInjector)
IDEA 預設的 build 步驟可能會引起 mapper 檔案無法正常編譯到對應的 resources 資料夾中,請檢查 build 之後相關資原始檔夾是否有對應的 xml 檔案,如果沒有,請調整 IDEA 的 build 設定,推薦調整為 Maven 或 Gradle 的 build。
問題描述:指在 XML 中裡面自定義 SQL,卻無法呼叫。本功能同 MyBatis 一樣需要設定 XML 掃描路徑:
Spring MVC 設定
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="typeAliasesPackage" value="xxx.entity" /> <property name="mapperLocations" value="classpath*:/mybatis/*/*.xml"/> ... </bean>
Spring Boot 設定
mybatis-plus: mapper-locations: classpath*:/mapper/**/*.xml
對於IDEA系列編輯器,XML 檔案是不能放在 java 資料夾中的,IDEA 預設不會編譯原始碼資料夾中的 XML 檔案,可以參照以下方式解決:
1:將組態檔放在 resource 資料夾中
2:對於 Maven 專案,可指定 POM 檔案的 resource
<build> <resources> <resource> <!-- xml放在java目錄下--> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <!--指定資源的位置(xml放在resources下,可以不用指定)--> <resource> <directory>src/main/resources</directory> </resource> </resources> </build>
提示 注意!
Maven 多模組專案的掃描路徑需以 classpath*: 開頭 (即載入多個 jar 包下的 XML 檔案)
4:關於 Long 型主鍵填充不生效的問題
檢查是不是用了long而不是Long!
提示
long型別預設值為 0,而 MP 只會判斷是否為 null
JavaScript 無法處理 Java 的長整型 Long 導致精度丟失,具體表現為主鍵最後兩位永遠為 0,解決思路:Long 轉為 String 返回。
FastJson 處理方式
@Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter(); FastJsonConfig fjc = new FastJsonConfig(); // 設定序列化策略 fjc.setSerializerFeatures(SerializerFeature.BrowserCompatible); fastJsonConverter.setFastJsonConfig(fjc); converters.add(fastJsonConverter); }
JackJson 處理方式
方式一
/ 註解 處理,這裡可以設定公共 baseEntity 處理 @JsonSerialize(using=ToStringSerializer.class) public long getId() { return id; }
方式二
/ 全域性設定序列化返回 JSON 處理 final ObjectMapper objectMapper = new ObjectMapper(); SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(Long.class, ToStringSerializer.instance); objectMapper.registerModule(simpleModule);
FieldStrategy 有以下策略:
方式一:調整欄位驗證註解
根據具體情況,在需要更新的欄位中調整驗證註解,如驗證非空:
@TableField(strategy=FieldStrategy.NOT_EMPTY)
方式二:使用 UpdateWrapper (3.x)
使用以下方法來進行更新或插入操作:
//updateAllColumnById(entity) // 全部欄位更新: 3.0已經移除 mapper.update( new User().setName("mp").setAge(3), Wrappers.<User>lambdaUpdate() .set(User::getEmail, null) //把email設定成null .eq(User::getId, 2) ); //也可以參考下面這種寫法 mapper.update( null, Wrappers.<User>lambdaUpdate() .set(User::getAge, 3) .set(User::getName, "mp") .set(User::getEmail, null) //把email設定成null .eq(User::getId, 2) );
預設mysql驅動會把tinyint(1)欄位對映為boolean: 0=false, 非0=true。MyBatis 是不會自動處理該對映,如果不想把tinyint(1)對映為boolean型別:
修改型別tinyint(1)為tinyint(2)或者int。
需要修改請求連線新增引數 tinyInt1isBit=false,如下:
jdbc:mysql://127.0.0.1:3306/mp?tinyInt1isBit=false
EntityWrapper.sqlSelect 設定你想要查詢的欄位
//2.x EntityWrapper<H2User> ew = new EntityWrapper<>(); ew.setSqlSelect("test_id as id, name, age");//只查詢3個欄位 List<H2User> list = userService.selectList(ew); for(H2User u:list){ Assert.assertNotNull(u.getId()); Assert.assertNotNull(u.getName()); Assert.assertNull(u.getPrice()); // 這個欄位沒有查詢出來 } //3.x mapper.selectList( Wrappers.<User>lambdaQuery() .select(User::getId, User::getName) ); //或者使用QueryWrapper mapper.selectList( new QueryWrapper<User>() .select("id","name") );
設定 jdbcTypeForNull=NULL Spring Bean 設定方式:
MybatisConfiguration configuration = new MybatisConfiguration(); configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class); configuration.setJdbcTypeForNull(JdbcType.NULL); configuration.setMapUnderscoreToCamelCase(true);//開啟下劃線轉駝峰 sqlSessionFactory.setConfiguration(configuration);
yml 設定
mybatis-plus: configuration: jdbc-type-for-null: 'null'
SQL 長度有限制海量資料量單條 SQL 無法執行,就算可執行也容易引起記憶體洩露 JDBC 連線超時等
不同資料庫對於單條 SQL 批次語法不一樣不利於通用
目前的解決方案:迴圈預處理批次提交,雖然效能比單 SQL 慢但是可以解決以上問題。
10:啟動 mybatis 本身的 log 紀錄檔
# 方式一 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 方式二 application.yml 中增加設定,指定 mapper 檔案所在的包 logging: level: com.baomidou.example.mapper: debug
這些問題都是摘自Mybatis-Plus的官方網站地址如下:
https://www.baomidou.com/pages/f84a74/
如果想看更多的問題請存取上面的網址,當然更多的問題也可以存取Mybatis-Plus的github地址那裡面有很多人提的issue。很多開發中遇到的問題都可以在issue裡面找到答案,我也是常常去看那裡的issue從裡面獲取答案獲取靈感。歡迎大家關注我的微信公眾號,繼續為大家推出好的文章。
晚霞和微風是真的很美。