对于枚举类型,不能通过org.hibernate.annotations.Type注解来简单的映射对应的数据库字段类型(除非自定义类型)。对此,Hibernate提供了javax.persistence.Enumerated注解,该注解的参数有两种场景:
1.EnumType.STRING:使用该参数时,数据库表中会存储枚举的字符串值;
2.EnumType.ORDINAL:使用该参数时,数据库表中存在的是枚举的int型值;
假如在数据类Movie.java中新增一个type字段,该字段被定义为枚举类型MovieType,用于标识该影视是电影、电视剧还是动漫。枚举MovieType代码如下:
1 package study.hibernate.model;
2
3 public enum MovieType {
4 FILM,
5
6 TV,
7
8 CARTOON,
9
10 VARIETY
11 }
在数据类中对type属性添加@Enumerated注解来配置映射关系:
1 package study.hibernate.model;
2
3 import javax.persistence.Column;
4 import javax.persistence.Convert;
5 import javax.persistence.Entity;
6 import javax.persistence.EnumType;
7 import javax.persistence.Enumerated;
8 import javax.persistence.Id;
9 import javax.persistence.Table;
10
11 import org.hibernate.annotations.Type;
12
13 /**
14 * 电影数据类
15 *
16 */
17 @Entity
18 @Table(name="MOVIE")
19 public class Movie {
20 @Id
21 @Column(name="MOVIE_ID")
22 private int id;
23
24 @Column(name="NAME")
25 @Type(type="string")
26 private String name;
27
28 @Column(name="DESCRIPTION")
29 @Type(type="text")
30 private String description;
31
32 @Column(name="TYPE")
33 @Enumerated(EnumType.ORDINAL)
34 private MovieType type;
35
36 public int getId() {
37 return id;
38 }
39
40 public void setId(int id) {
41 this.id = id;
42 }
43
44 public String getName() {
45 return name;
46 }
47
48 public void setName(String name) {
49 this.name = name;
50 }
51
52 public String getDescription() {
53 return description;
54 }
55
56 public void setDescription(String description) {
57 this.description = description;
58 }
59
60 public MovieType getType() {
61 return type;
62 }
63
64 public void setType(MovieType type) {
65 this.type = type;
66 }
67
68 }
在应用启动时,设置对应的type属性:
Movie movie = new Movie();
movie.setId(1);
movie.setName("速度与激情8");
movie.setDescription("多米尼克(范·迪塞尔 Vin Diesel 饰)与莱蒂(米歇尔·罗德里格兹 Michelle Rodriguez 饰)共度蜜月,布莱恩与米娅退出了赛车界,这支曾环游世界的顶级飞车家族队伍的生活正渐趋平淡。然而,一位神秘女子Cipher(查理兹·塞隆 Charlize T heron 饰)的出现,令整个队伍卷入信任与背叛的危机,面临前所未有的考验。");
movie.setType(MovieType.CARTOON);
运行后,查看数据库,发现movie表中的type字段被赋值2:
mysql> select name, type from movie; +------------------+------+ | name | type | +------------------+------+ | 速度与激情8 | 2 | +------------------+------+ 1 row in set (0.00 sec)
如果@Enumerated注解参数配置的是EnumType.STRING,则数据库中会存放枚举对应的字符串值:
mysql> select name, type from movie; +------------------+---------+ | name | type | +------------------+---------+ | 速度与激情8 | CARTOON | +------------------+---------+ 1 row in set (0.00 sec)
通过@Enumerated存储在数据库中的值是固定的,是不可定制的,假如枚举类MovieType声明如下:
1 package study.hibernate.model;
2
3 public enum MovieType {
4 FILM("电影"),
5
6 TV("连续剧"),
7
8 CARTOON("动漫"),
9
10 VARIETY("综艺");
11
12 private String type;
13
14 private MovieType(String type) {
15 this.type = type;
16 }
17
18 @Override
19 public String toString() {
20 return type;
21 }
22 }
对于如上枚举,希望如果类型为MovieType.CARTOON时,存在数据库中的值为"动漫",如果类型为MovieType.FILM,存在数据库中的值为"电影"。此时@Enumerated的功能是不够的,可以通过指定@Convert注解声明对应的转换类来实现。
@Convert注解用来声明对象在写到数据库的时候怎么转换为数据库可识别的类型,从数据库中读出来的时候怎么反转为对象,可以看作是一个序列化及反序列化的规则。
要使用@Convert注解,首先得定义一个实现了javax.persistence.AttributeConverter<X, Y>接口的类,该接口有两个方法:
javax.persistence.AttributeConverter.convertToDatabaseColumn(X) 用来说明如何把java对象X转换存储在数据库中的数据对象Y;
javax.persistence.AttributeConverter.convertToEntityAttribute(Y) 用来说明如何把数据库中的数据对象Y转换为对应的java对象X;
假如我们的实现类名为MovieTypeConvertor,代码如下:
1 package study.hibernate.model;
2
3 import javax.persistence.AttributeConverter;
4
5 public class MovieTypeConvertor implements AttributeConverter<MovieType, String> {
6
7 public String convertToDatabaseColumn(MovieType attribute) {
8 return String.valueOf(attribute);
9 }
10
11 public MovieType convertToEntityAttribute(String dbData) {
12 return MovieType.valueOf(dbData);
13 }
14
15 }
其次,在数据库Movie.java的type属性上添加@Covert注解
1 @Column(name="TYPE") 2 @Convert(converter=MovieTypeConvertor.class) 3 private MovieType type;
最后,运行程序,查看数据库中的值,发现数据的值已经被设置为”动漫“
mysql> select name, type from movie; +------------------+--------+ | name | type | +------------------+--------+ | 速度与激情8 | 动漫 | +------------------+--------+ 1 row in set (0.00 sec)
@Convert注解并不只能用来匹配注解,它可以用在任何类型的数据上,譬如,可以将一个集合中的内容以空格分隔存在数据库中,读出时以空格分隔重新生成为一个集合等。
本文探讨了在Hibernate中如何有效映射枚举类型至数据库字段,包括使用@Enumerated和@Convert注解的不同场景,以及自定义转换类实现更灵活的枚举映射。
5242

被折叠的 条评论
为什么被折叠?



