bigint 有無符號對應java的Long和BigInteger

bigint 有無符號對應java的Long和BigInteger

這個問題是在實際工作中遇到的,是一個小的問題,但是如果不注意的話,造成的後續問題是比較嚴重的。下面就來重現一下這個問題。

首先我們先創建一張數據表,名爲t_order. 位於test庫中。

在這裏插入圖片描述

CREATE TABLE `t_order` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `tid` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

SQL語句如上,字段tid上是正常的bigint 類型,無其他限制條件。

下面使用SpringBoot+Mybatis來測試數據查詢單獨tid列。

在這裏插入圖片描述

通過Debug可以看到allTids的數據是Long類型的。下面我們將數據庫表修改一下。

CREATE TABLE `t_order` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `tid` bigint(20) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

此時表的SQL如上,即在tid列上加上了無符號限制。我們重新運行測試代碼:

在這裏插入圖片描述

測試結果如上,可以看出,測試的tid類型就變成了BigInteger類型。當然在我們的控制檯直接輸出是不會出現問題的,但是將測試代碼換成下面的:

在這裏插入圖片描述

通過測試結果可以看出,無法將相應的Long類型的數據剔除掉。

當然,這個問題如果在Mybatis中使用泛型限制的話,也不會出現自動映射爲BigInteger的情況。

public interface OrderMapper {
    List findAllTids();
    List<Long> findAllLongTids();
    List<Map<String,Object>> findAll();
}

在這裏插入圖片描述

通過上面的截圖可以看出,由於查詢的時候使用了泛型進行相應的類型限制,可以看出即使在數據庫表中設置了tid的類型爲無符號,也可以自動轉爲Long類型。這種情況下是不會出現問題的。

但是公司的DAO層比較多樣化,有一部分DAO層是基於apache的DBUtils進行封裝的,對於切換數據源比較方便,所以使用時偏向於這個,但是在查詢單列的id時,遇到了上述情況,加了泛型也是無法轉換,我進入源碼並且看到這樣一段代碼:

public abstract class AbstractListHandler<T> implements ResultSetHandler<List<T>> {
    public AbstractListHandler() {}
    public List<T> handle(ResultSet rs) throws SQLException {
        ArrayList rows = new ArrayList();
        while(rs.next()) {
            rows.add(this.handleRow(rs));
        }
        return rows;
    }
    protected abstract T handleRow(ResultSet var1) throws SQLException;
}
// 單列的數據處理
public class ColumnListHandler<T> extends AbstractListHandler<T> {}

可以看出,在DBUtilsAbstractListHandler類中,在處理時,並沒有進行類型限制,只是在方法聲明的地方添加了T,其實沒什麼用,查詢出來該是BigInteger還是這個,不會自動轉爲泛型設置的類型。(這裏是個坑),但是使用Mybatis可以避免了。

說明:如果是有符號的 Bigint(20) 取值範圍是-9223372036854775808~9223372036854775807,與 Java中的java.lang.Long的取值範圍是一致的,而如果是無符號的Bigint(20),其取值範圍是0 ~ 18446744073709551615,其中一般超出了Long的取值範圍,會被映射爲BigInteger。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章