---
# System prepended metadata

title: Hibernate中Eumn類型的mapping
tags: [Hibernate, Shannon]

---

# Hibernate中Eumn類型的mapping
###### tags: `Shannon`,`Hibernate`

# How?
把Eumn映射到資料庫中有兩種方式:


# 不使用任何annotation @Enumerated
如果不使用@Enumerated，默認情況下是使用`ordinal`屬性，表示Enum會依照Enum中聲明的順序來完成映射

> Employee.java 
```java 
@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Nationalized
    private String name;

    @Column
    private EmployeeSkill skills;
//    private Set<DayOfWeek> daysAvailable;

    public Employee(){}

    public Employee(String name, EmployeeSkill skill){
        this.name = name;
        this.skills = skill;
    }
	// getter and setter

```
> EmployeeSkill.java
```java 
public enum EmployeeSkill {
    PETTING, WALKING, FEEDING, MEDICATING, SHAVING;
}
```

> EmployeeRepository.java
```java 
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
```

> EmployeeService.java
```java 
@Service
public class EmployeeService{
    @Autowired
    EmployeeRepository employeeRepository;

    public void save(Employee employee){
        employeeRepository.save(employee);
    }
}
```

> CritterController.java
```java 
@RestController
public class CritterController {
    @Autowired
    EmployeeService employeeService;

    @GetMapping("/test")
    public String test(){
        employeeService.save(new Employee("Gwan", PETTING));
        employeeService.save(new Employee("Shannon", MEDICATING));
        return "Critter Starter installed successfully";
    }
}
```
> 結果: Console
- 可是會有個問題那就是裡面的Skill裡面的`ordinal`他會顯示的是enum裡面的順序而非名稱
![](https://i.imgur.com/66b90Pc.png)

# 使用@Enumerated註解
> javax.persistence.Enumerated : Specifices that a persistent property or field should be persisted as a enumerated type. The Enumerated annotation may be used in conjuction with the element collection value is of basic type. If the enumerated type is not specified or the Enumerated annotation is not used, the EnumType value is assumed to be ORDINAL.
- 裡面在說如果我們沒有使用Enumerated的標註，就會載用ORINAL的方式來完成，default。

加了@Enumerated跟不使用的最大的差別在哪裡?其實只要將Enumerated的標籤家在enum的欄位就好了
1. 如果使用第一種方式，你可以發現skill type 為int
![](https://i.imgur.com/N8wbrVH.png)
2. 如果使用第二種方式，你可以發現skill's type變成varchar(255)
![](https://i.imgur.com/P7oNept.png)

> 你可以發現不再是數字了
![](https://i.imgur.com/c0q9rC2.png)

# 使用AttributeConverter屬性類型轉換器
* `AttributeConverter<X, Y>`
	* X 是Enum的class
	* Y 是資料庫裡面的類型
	* `Y convertToDatabaseColumn(X)` : 就是將傳入的參數X,也就是enum所在的class轉換成string存進去資料庫
	* `X convertToEntityAttribute(Y)` : 就是將資料庫裏面的Y屬性也轉換成實體屬性X

- 甚麼時候會用到?
	- 如果你的enum實例有name跟value，採用第二種只會顯示name，如果採用第三種就會顯示value
	- 使用`@Enumerated`的話就會只顯示male或是Female
	- 如果使用第三種方法，就能夠顯示`男``女`。
```java 
public enum Gender {
    male("男"),
    female("女");

    private String value;
    private Gender(String value){
        this.value = value;
    }

    public String getValue(){
        return this.value;
    }

    public static Gender fromString(String value){
        Objects.requireNonNull(value, "value can not be null");
        Gender gender = null;
        if("男".equals(value)){
            gender = male;
        }
        else if("女".equals(value)){
            gender = female;
        }
        return gender;
    }
}
```

更多詳情請參考: https://blog.csdn.net/lmy86263/article/details/52650721