當前位置: 妍妍網 > 碼農

還在 MySQL 中使用列舉?小心有坑~

2024-04-19碼農

為什麽使用列舉

限定值的取值範圍,比如性別(男,女,未知)等。

列舉型別使用陷阱

1.超級不推薦在mysql中設定某一欄位型別為enum,但是存的值為數位,比如‘0’,‘1’,‘2’;

  • 解釋1: 你會混淆,因為enum可以透過角標取值,但它的角標是從1開始,對於不熟悉這個欄位的人這裏會出錯

  • 解釋2: enum型別的欄位對於0與‘0’有非常大的區別,如果你是用0當角標做操作,因它沒有這個角標,所要會報錯;如果你使用‘0’這個值去取列舉值,並做插入操作,你會發現它竟然會成功,但是插入的結果是一個「空」(不是null)

  • 解釋3: enum型別對於php等弱語言型別的支持很差,弱語言型別打引號和不打引號的值可能是同一型別,但是對於mysql中enum型別的欄位來說,那就不一定是一回事了

  • 結論:總之,不要拿mysql的enum型別取存一些數位;如果你一定要使用這個欄位去存數位,請把這個欄位定義為int,然後在java程式碼中使用列舉類做一個對於這個欄位值範圍的一個限定!(後面有程式碼)

    2.你可能會報這個錯—— Caused by: java.sql.SQLException: Data truncated for column 'Color' at row 1 ;

    原因:

  • Jpa預設使用整數順序值持久化列舉型別;

  • Mysql中列舉型別Color定義取值的順序是 RED、GREEN、BLUE ,因此,當這三個取值持久化到資料庫表時,取值分別是0、1、2;

  • 意思就是我們這裏存往資料庫的數據是0、1、2這樣的數位,而不是 RED、GREEN、BLUE 字串,但是Mysql資料庫中定義的是 RED、GREEN、BLUE ,並沒有其它值所以報錯

  • 解決:在entity中使用 @Enumerated(EnumType.STRING) 標註你的列舉型別內容,如果標註,預設是integer

    使用例子

    建表語句為

    CREATETABLE test4 (
    idBIGINTUNSIGNED PRIMARY KEY AUTO_INCREMENT,
    brand VARCHAR(255NOTNULL,
    color ENUM('RED','GREEN','BLUE')
    ENGINE = InnoDB

    Java程式碼中,列舉類

    publicenum Color {
    RED,
    GREEN,
    BLUE
    }

    Java程式碼中,Javabean

    @Entity
    @Table(name="test4"
    public classClothesRight{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Enumerated(EnumType.STRING)
    private Color color;
    private String brand;
    public Long getId(){
    return id;
     }
    publicvoidsetId(Long id){
    this.id = id;
     }
    public String getBrand(){
    return brand;
     }
    publicvoidsetBrand(String brand){
    this.brand = brand;
     }
    publicClothesRight(Long id, Color color, String brand){
    super();
    this.id = id;
    this.color = color;
    this.brand = brand;
     }
    public Color getColor(){
    return color;
     }
    publicvoidsetColor(Color color){
    this.color = color;
     }
    publicClothesRight(){
    super();
     }
    }









    簡單使用:

    publicinterfaceTest4RightRepositoryextendsJpaRepository<ClothesRightLong>{
    }
    @Autowired
    private Test4RightRepository t4R;
    /**
    * 使用@Enumrated()標註欄位為列舉的數據
    * 結果 正確插入RED
    */

    @GetMapping(value="/addclothesright")
    publicvoidGetTest4Right(){
    List<ClothesRight> entities = new ArrayList<>();
    ClothesRight clothes = new ClothesRight();
    //clothes.setId(1L);
    clothes.setBrand("佐丹奴");
    clothes.setColor(Color.RED); 
    entities.add(clothes);
    t4R.save(entities);
     }

    結果為:

    插入數位例子(不推薦)

    建表

    CREATETABLE test5num (
    idBIGINTUNSIGNED PRIMARY KEY AUTO_INCREMENT,
    used int(11DEFAULTNULLCOMMENT'0:沒用過 1:已用過 2:不能用'
     )ENGINE = InnoDB

    Java程式碼為:

    @Entity
    @Table(name="test5num")
    public classTest5Num{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
    private Used used;
    public Long getId(){
    return id;
     }
    publicvoidsetId(Long id){
    this.id = id;
     }
    public Used getUsed(){
    return used;
     }
    publicvoidsetUsed(Used used){
    this.used = used;
     }
    publicTest5Num(){
    super();
     }
    publicTest5Num(Long id, Used used){
    super();
    this.id = id;
    this.used = used;
     }
    }
    /**
    *列舉類
    */

    publicenum Used {
     UNUSED(0,"沒用過"),
     USED(1,"已用過"),
     FORBIDDEN(2,"不能用");
    private Integer code;
    private String discribe;
    public Integer getCode(){
    return code;
     }
    public String getDiscribe(){
    return discribe;
     }
    privateUsed(Integer code, String discribe){
    this.code = code;
    this.discribe = discribe;
     }
    }
    /**
     * dao層
     */

    publicinterfaceTest5NumRepositoryextendsJpaRepository<Test5NumLong>{
    }
    @Autowired
    private Test5NumRepository t5N;
    /**
     * mysql列舉的欄位型別不宜插入數位,但是需求就是要用數位,怎麽辦?
     * 解決:mysql數據型別定義為int,列舉限定在java程式碼中解決
     * 
     */

    @GetMapping("/test5insert")
    publicvoidinsertT5(){
     Test5Num t5 = new Test5Num();
     t5.setUsed(Used.USED);
     List<Test5Num> list = new ArrayList<Test5Num>();
     list.add(t5);
     t5N.save(list);
    }








    結果:

    來源:blog.csdn.net/u011442682/

    article/details/79078199

    >>

    END

    精品資料,超贊福利,免費領

    微信掃碼/長按辨識 添加【技術交流群

    群內每天分享精品學習資料

    最近開發整理了一個用於速刷面試題的小程式;其中收錄了上千道常見面試題及答案(包含基礎並行JVMMySQLRedisSpringSpringMVCSpringBootSpringCloud訊息佇列等多個型別),歡迎您的使用。

    👇👇

    👇點選"閱讀原文",獲取更多資料(持續更新中