幾個常見的Mybatis錯誤

本文首發於公衆號《andyqian》,期待你的關注java

前言mysql

  今天記錄幾個Mybatis常見錯誤。在使用Mybatis時,或多或少的會碰到這些問題。問題自己並不難,解決起來也很是簡單。下面會一一介紹各個問題出現的場景,發生緣由以及解決方案。最後統一說說如何避免這類問題的發生。spring

問題一 (不存在的列)

這個問題在使用Mybatis時,屬於比較常見的低級錯誤。sql

問題描述:數據庫

### Error querying database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'name' in 'field list'
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'name' in 'field list'
; bad SQL grammar []

主要緣由apache

  1. Mybatis XML中的SQL語句查詢的列,不在數據庫中。windows

  2. 新增SQL語句中的列不在數據庫中,或列對應的值,數據類型不一致。跨域

解決辦法: 根據項目實際狀況,一般有如下三種解決辦法:服務器

  1. 修改SQL語句中,將不存在的列從語句中去掉。數據結構

  2. 在數據庫中,新增該不存在的列。

  3. 在新增時,不要使用中文符號的``表示字符串。也就是~符號對應的鍵。

     

注意事項:

  1. 刪除了數據庫中的列。在SQL語句中,沒有同步刪除該字段的。會比較容易出現該問題。

  2. 這裏還有一個比較特殊的場景,會致使上述問題的發生。

     

如下SQL在windows環境下會顯示上述錯誤,不會進行新增操做:

insert into t_base_user(name,created_time,updated_time)values(`name`,now(),now());

但在Linux環境下,其會進行新增操做。可是 name 的值不會進行新增。

問題二 (模棱兩可的字段)

問題描述:

### Error querying database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'oid' in field list is ambiguous
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'oid' in field list is ambiguous
; SQL []; Column 'oid' in field list is ambiguous

主要緣由:鏈接查詢時沒有指定共有字段的所屬表。 也就是說。A表有name字段,B表也有name字段。鏈接查詢時查詢name時。SQL服務器不知道返回哪一個表的name字段致使。

解決方案:明確查詢列的所屬表。

例如

表結構在文章最後,有興趣的童鞋能夠測試。執行如下SQL便可還原上述問題,

select  u.id,name from t_base_user as u RIGHT JOIN
t_base_user_role as r  on u.id = r.user_id

注意事項: 將上述語句中的 u.id 修改成 id 也能正常運行。由於id不是公共字段,只有user表才id字段。

問題三 (不一致的接收對象)

問題描述:

Exception in thread "main" org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 9

主要緣由:在接口中指定單個返回對象。但執行SQL後,有多條符合條件的數據。

解決方案
根據實際的業務場景,一般有如下兩種解決辦法:

  1. 修改接口的返回結果爲集合。

  2. 修改SQL語句使其只返回一個符合條件的結果。

問題四 (重複的方法名)

描述:

Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.lang.RuntimeException: Error parsing Mapper XML. Cause: java.lang.IllegalArgumentException: Mapped Statements collection already contains value for UserDao.getUserByName

緣由: 在UserDao中,有兩個同名方法getUserByName致使。

解決辦法: 重命名其中一個方法名便可。

問題五 (不存在的屬性)

描述:

Error updating database.  Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'username' in 'com.andyqian.user.bean.User'
Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'education' in 'class com.andyqian.user.bean.User'

緣由: SQL中查詢的列,在其實體對象中不存在對應的屬性。

解決辦法: 在對應的實體對象上,添加上缺失的屬性便可。

數據結構

在本文中,全部測試均使用如下表結構。SQL語句以下所示,有興趣的童鞋能夠進行實驗。

create table t_base_user_role(
oid bigint(20) not null primary key auto_increment comment "",
user_id bigint(20) null comment "",
name varchar(50) null comment "",
create_time datetime null comment "",
update_time datetime null comment ""
)

CREATE TABLE `t_base_user` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL,
  `created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `deleted` tinyint(4) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8

最後

  上述幾個都屬於比較常見且容易解決的問題。基本上可以經過描述,就能定位到問題的緣由。之因此可以發生。簡答概括爲如下兩點:

  1. xml文件中的SQL,沒有在數據庫中執行。

  2. 沒有寫單元測試。

     

因而可知,單元測試可以爲咱們排除掉一些比較低級,甚至是手誤帶來的bug。也能爲咱們節省很多時間來解決更復雜,更有挑戰性的問題。

 

推薦閱讀:

說說Java單元測試  

CORS 跨域實踐

Git 經常使用命令以及常見錯誤

說說Java日誌

 

這裏寫圖片描述

 掃碼關注,一塊兒進步

我的博客: http://www.andyqian.com

相關文章
相關標籤/搜索