還在 MySQL 中使用枚舉?這些陷阱一定要注意!
閱讀本文大概需要 2.8 分鐘。
來(lái)自:blog.csdn.net/u011442682/article/details/79078199
枚舉類型使用陷阱
解釋1: 你會(huì)混淆,因?yàn)閑num可以通過(guò)角標(biāo)取值,但它的角標(biāo)是從1開始,對(duì)于不熟悉這個(gè)字段的人這里會(huì)出錯(cuò) 解釋2: enum類型的字段對(duì)于0與‘0’有非常大的區(qū)別,如果你是用0當(dāng)角標(biāo)做操作,因它沒(méi)有這個(gè)角標(biāo),所要會(huì)報(bào)錯(cuò);如果你使用‘0’這個(gè)值去取枚舉值,并做插入操作,你會(huì)發(fā)現(xiàn)它竟然會(huì)成功,但是插入的結(jié)果是一個(gè)“空”(不是null) 解釋3: enum類型對(duì)于php等弱語(yǔ)言類型的支持很差,弱語(yǔ)言類型打引號(hào)和不打引號(hào)的值可能是同一類型,但是對(duì)于mysql中enum類型的字段來(lái)說(shuō),那就不一定是一回事了
結(jié)論:總之,不要拿mysql的enum類型取存一些數(shù)字;如果你一定要使用這個(gè)字段去存數(shù)字,請(qǐng)把這個(gè)字段定義為int,然后在java代碼中使用枚舉類做一個(gè)對(duì)于這個(gè)字段值范圍的一個(gè)限定!(后面有代碼)
Caused by: java.sql.SQLException: Data truncated for column 'Color' at row 1 ;Jpa默認(rèn)使用整數(shù)順序值持久化枚舉類型;
Mysql中枚舉類型Color定義取值的順序是
RED、GREEN、BLUE,因此,當(dāng)這三個(gè)取值持久化到數(shù)據(jù)庫(kù)表時(shí),取值分別是0、1、2;意思就是我們這里存往數(shù)據(jù)庫(kù)的數(shù)據(jù)是0、1、2這樣的數(shù)字,而不是
RED、GREEN、BLUE字符串,但是Mysql數(shù)據(jù)庫(kù)中定義的是RED、GREEN、BLUE,并沒(méi)有其它值所以報(bào)錯(cuò)
解決:在entity中使用 @Enumerated(EnumType.STRING)標(biāo)注你的枚舉類型屬性,如果標(biāo)注,默認(rèn)是integer
使用例子
CREATE TABLE test4 (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
brand VARCHAR(255) NOT NULL,
color ENUM('RED','GREEN','BLUE')
) ENGINE = InnoDB;
public enum Color {
RED,
GREEN,
BLUE
}
@Entity
@Table(name="test4")
public class ClothesRight {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Enumerated(EnumType.STRING)
private Color color;
private String brand;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public ClothesRight(Long id, Color color, String brand) {
super();
this.id = id;
this.color = color;
this.brand = brand;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public ClothesRight() {
super();
}
}
public interface Test4RightRepository extends JpaRepository<ClothesRight, Long>{
}
@Autowired
private Test4RightRepository t4R;
/**
* 使用@Enumrated()標(biāo)注字段為枚舉的數(shù)據(jù)
* 結(jié)果 正確插入RED
*/
@GetMapping(value="/addclothesright")
public void GetTest4Right(){
List<ClothesRight> entities = new ArrayList<>();
ClothesRight clothes = new ClothesRight();
//clothes.setId(1L);
clothes.setBrand("佐丹奴");
clothes.setColor(Color.RED);
entities.add(clothes);
t4R.save(entities);
}

插入數(shù)字例子(不推薦)
CREATE TABLE test5num (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
used int(11) DEFAULT NULL COMMENT '0:沒(méi)用過(guò) 1:已用過(guò) 2:不能用'
)ENGINE = InnoDB;
@Entity
@Table(name="test5num")
public class Test5Num {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private Used used;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Used getUsed() {
return used;
}
public void setUsed(Used used) {
this.used = used;
}
public Test5Num() {
super();
}
public Test5Num(Long id, Used used) {
super();
this.id = id;
this.used = used;
}
}
/**
*枚舉類
*/
public enum Used {
UNUSED(0,"沒(méi)用過(guò)"),
USED(1,"已用過(guò)"),
FORBIDDEN(2,"不能用");
private Integer code;
private String discribe;
public Integer getCode() {
return code;
}
public String getDiscribe() {
return discribe;
}
private Used(Integer code, String discribe) {
this.code = code;
this.discribe = discribe;
}
}
/**
* dao層
*/
public interface Test5NumRepository extends JpaRepository<Test5Num, Long>{
}
@Autowired
private Test5NumRepository t5N;
/**
* mysql枚舉的字段類型不宜插入數(shù)字,但是需求就是要用數(shù)字,怎么辦?
* 解決:mysql數(shù)據(jù)類型定義為int,枚舉限定在java代碼中解決
*
*/
@GetMapping("/test5insert")
public void insertT5(){
Test5Num t5 = new Test5Num();
t5.setUsed(Used.USED);
List<Test5Num> list = new ArrayList<Test5Num>();
list.add(t5);
t5N.save(list);
}

抖音服務(wù)器帶寬有多大,才能供上億人同時(shí)刷?
互聯(lián)網(wǎng)初中高級(jí)大廠面試題(9個(gè)G) 內(nèi)容包含Java基礎(chǔ)、JavaWeb、MySQL性能優(yōu)化、JVM、鎖、百萬(wàn)并發(fā)、消息隊(duì)列、高性能緩存、反射、Spring全家桶原理、微服務(wù)、Zookeeper......等技術(shù)棧!
?戳閱讀原文領(lǐng)取! 朕已閱
評(píng)論
圖片
表情


