转载请注明http://www.cnblogs.com/majianming/p/8553217.html
在项目中,经常会出现这样的情况,一个实体的字段名是枚举类型的
我们在把它存放到数据库中是需要将其映射为字符串或者其他类型
1 public enum Color{ 2 3 RED(1, "RED"), 4 ORANGE(2, "ORANGE"); 5 6 private Integer rainbowIndex;//在彩虹中的序号 7 private String name; 8 9 Type(Integer rainbowIndex, String name) { 10 this.rainbowIndex= rainbowIndex; 11 this.name= name; 12 } 13 14 public Integer getRainbowIndex() { 15 return rainbowIndex; 16 } 17 18 public String getName() { 19 return name; 20 }
21 22 public static Type getTypeFromName(String name){ 23 for (Type type : Type.values()) { 24 if (type.getName().equals(name)){ 25 return type; 26 } 27 } 28 return null; 29 } 30 }
@Entity @Table(name = "tb_paper") public class Paper { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long no; private Color color; public Long getNo() { return no; } public void setNo(Long no) { this.no= no; } public Color getColor() { return type; } public void setColor(Color type) { this.type = type; } }
如果这样直接写,会怎样?
在保存到数据库时没有错误信息,它帮我们生成一张表,而且还把其中一个字段rainbowIndex映射到了数据表tb_paper上的color字段(从参数类型上可以看出),
CREATE TABLE `tb_paper` ( `no` bigint(20) NOT NULL AUTO_INCREMENT, `color` int(11) DEFAULT NULL, PRIMARY KEY (`no`) ) DEFAULT CHARSET=utf8;
那我两个参数在实体中都是String类型的,框架会帮我如何选择?
1 public enum Color{ 2 3 RED("1", "RED"), 4 ORANGE("2", "ORANGE"); 5 6 private String rainbowIndex;//在彩虹中的序号 我们这里改成String类型 虽然使用数值类型比较恰当 7 private String name; 8 9 Type(String rainbowIndex, String name) { 10 this.rainbowIndex= rainbowIndex; 11 this.name= name; 12 } 13 14 public String getRainbowIndex() { 15 return rainbowIndex; 16 } 17 18 public String getName() { 19 return name; 20 }
21 22 public static Type getTypeFromName(String name){ 23 for (Type type : Type.values()) { 24 if (type.getName().equals(name)){ 25 return type; 26 } 27 } 28 return null; 29 } 30 }
发现数据库还是 `color` int(11) DEFAULT NULL ,这就肯定不对了
那么这里出现了两个问题
- 映射的类型错误
- 映射的字段不能指定
我们使用jpa2.1规范里面的属性转换器
1 @Converter(autoApply = true) 2 public class ColorConverter implements AttributeConverter<Color, String> {//泛型指的是你在实体用的类型,第二个是指需要映射到数据库的类型对应的java中的类型 3 4 @Override 5 public String convertToDatabaseColumn(Color attribute) { 6 return attribute.getName(); 7 } 8 9 @Override 10 public Color convertToEntityAttribute(String dbData) { 11 return Color.getColorFromName(dbData); 12 } 13 }
看下数据库表 `color` varchar(255) DEFAULT NULL ,字段映射对了,需要注意的是如果上面注解@Converter的没有(autoApply = true),(默认)表示在所有用到Color类型的实体映射是将默认映射为Integer类型,其实就是不生效,如果需要全局生效,加上(autoApply = true)就可以了,如果需要对于一个实体的一个属性单独处理的话,在需要的属性加上@Convert(converter = ColorConverter.class)
参考
http://hantsy.blogspot.com/2013/12/jpa-21-attribute-converter.html
https://www.thoughts-on-java.org/jpa-21-how-to-implement-type-converter/
转载请注明http://www.cnblogs.com/majianming/p/8553217.html