复杂数据类型的映射之枚举

枚举

枚举类型规定了取值的数量和内容,这对于需要限定取值的属性非常有帮助。比如性别有三种,男、女、未知,是否打印有两种,是,否。

package com.gxz.entities;

public enum Color {
	RED,
	GREEN,
	BLUE
}

数据库表

CREATE TABLE MyClothes (
	MyClothesId BIGINT UNSIGNED  PRIMARY KEY AUTO_INCREMENT,
    Brand VARCHAR(255) NOT NULL,
    Colour ENUM('RED','GREEN','BLUE'),
    INDEX MyClothesBrand(Brand)
) ENGINE = InnoDB;

DBMS使用MySQL,字段Colour是枚举类型,只能取值‘RED‘,‘GREEN‘,‘BLUE‘,若是插入其他值,报出异常。

Operation failed: There was an error while applying the SQL script to the database.
Executing:
INSERT INTO `entitymappings`.`myclothes` (`MyClothesId`, `Brand`, `Colour`) VALUES ('1', '佐丹奴', 'BLANK');

ERROR 1265: 1265: Data truncated for column 'Colour' at row 1
SQL Statement:
INSERT INTO `entitymappings`.`myclothes` (`MyClothesId`, `Brand`, `Colour`) VALUES ('1', '佐丹奴', 'BLANK')

实体类

package com.gxz.entities;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="myclothes")
public class Clothes {
	private long id;
	private Colour  colour;
	private String brand;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "MyClothesId")
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public Colour getColour() {
		return colour;
	}
	public void setColour(Colour colour) {
		this.colour = colour;
	}
	public String getBrand() {
		return brand;
	}
	public void setBrand(String brand) {
		this.brand = brand;
	}

}

默认持久化

Clothes clothes = new Clothes();
clothes.setBrand("佐丹奴");
clothes.setColour(Colour.RED);

manager.persist(clothes);

此时,报出异常。

javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not execute statement
Caused by: org.hibernate.exception.GenericJDBCException: could not execute statement
Caused by: java.sql.SQLException: Data truncated for column 'Colour' at row 1

默认情况,JPA实现者使用整数顺序值持久化枚举类型。枚举类型Colour定义取值的顺序是RED、GREEN、BLUE,因此,当这三个取值持久化到数据库表时,取值分别是0、1、2。然而,MySQL数据库表字段Colour是个枚举ENUM类型,只允许存放数值RED、GREEN、BLUE。所以持久化时,就会报出异常。为了印证以上的阐述,修改数据库表,让字段Colour的类型修改为varchar(1),此时,该字段可以存放数值1、2、3。

CREATE TABLE MyClothes (
	MyClothesId BIGINT UNSIGNED  PRIMARY KEY AUTO_INCREMENT,
    Brand VARCHAR(255) NOT NULL,
    Colour VARCHAR(1) NOT NULL,
    INDEX MyClothesBrand(Brand)
) ENGINE = InnoDB;

执行持久化。

Clothes clothes = new Clothes();
clothes.setBrand("佐丹奴");
clothes.setColour(Colour.RED);

manager.persist(clothes);

Clothes clothes2 = new Clothes();
clothes2.setBrand("真维斯");
clothes2.setColour(Colour.GREEN);

manager.persist(clothes2);

Clothes clothes3 = new Clothes();
clothes3.setBrand("以纯");
clothes3.setColour(Colour.BLUE);

manager.persist(clothes3);

查看数据库表myclothes,如下所述。

调整枚举类型Colour取值的定义顺序,刚开始时RED、GREEN、BLUE,现在调整为BLUE、GREEN、RED。

package com.gxz.entities;

public enum Colour {
	BLUE,
	GREEN,
	RED
}

清空数据库表myclothes,执行持久化,查看数据,如下所述。

如果按照JPA实现者的默认行为执行持久化枚举类型,会有以下问题。

1.我们希望存入数据库的数值是枚举类型的原始数据,比如RED、GREEN、BLUE,而不是0、1、2。

2.如果数据库字段定义是枚举类型,比如Colour ENUM(‘RED‘,‘GREEN‘,‘BLUE‘),持久化会有异常。

3.如果枚举定义后,修改了取值的顺序,比如刚开始时RED、GREEN、BLUE,后来修改为BLUE、GREEN、RED,持久化到数据库的整数顺序值也会相应的改变,这使得整数顺序值的意义非常混乱。刚开始存放在数据库的整数值,修改枚举的取值顺序后,这些历史数据成了错误的数据。

@Enumerated持久化

注解javax.persistence.Enumerated有唯一的一个属性javax.persistence.EnumType,该属性有两个值,分别是STRING、ORDINAL,意义分别是使用字符类型持久化枚举,使用默认行为持久化枚举。若选择STRING,JPA提供者将使用枚举的原始类型,即常量,持久化枚举,这正是我们希望看到的。

首先,我们把数据库表MyClothes的字段Colour修改回枚举型,接着,使用注解@Enumerated定义实体类。

package com.gxz.entities;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="myclothes")
public class Clothes {
	private long id;
	private Colour  colour;
	private String brand;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "MyClothesId")
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	@Enumerated(EnumType.STRING)
	public Colour getColour() {
		return colour;
	}
	public void setColour(Colour colour) {
		this.colour = colour;
	}
	public String getBrand() {
		return brand;
	}
	public void setBrand(String brand) {
		this.brand = brand;
	}

}

执行持久化,查询数据库表MyClothes,结果如下所述。

时间: 2024-08-23 23:29:14

复杂数据类型的映射之枚举的相关文章

PostgreSQL、SQL Server数据库中的数据类型的映射关系

PostgreSQL 8.1 轰动发布,我也打算将原来使用 SQL Server 的一些应用迁移到 PostgreSQL 上,首先需要迁移的是表,那么这就必须要先搞清楚这两个数据库中的数据类型的映射关系.查了下 PostgreSQL 文档特制作如下对应表格,以飨各位. 注意:PostgreSQL 中的 money(货币)数据类型现在已经废弃,用 numeric 或 decimal 以及和 to_char 函数一起使用就可以取代它. SQL Server 中的 datetime.smalldate

JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系

转载请注明出处:http://blog.csdn.net/xyang81/article/details/42047899 当我们在调用一个Java native方法的时候,方法中的参数是如何传递给C/C++本地函数中的呢?Java方法中的参数与C/C++函数中的参数,它们之间是怎么转换的呢?我猜你应该也有相关的疑虑吧,咱们先来看一个例子,还是以HelloWorld为例: HelloWorld.java: package com.study.jnilearn; class MyClass {}

C#的数据类型,strut和枚举的使用方法

using System; namespace Holle_World{ class Program { //enum枚举 enum Week{ Monday, Tuesday, Wenesday, Thursday, Friday, Saturday, Sunday }; // struct ,可自定义类型 struct Person { public string name; private bool sex; internal int age; //protected string x;

JDBC的ResultSet游标转spark的DataFrame,数据类型的映射以TeraData数据库为例

1.编写给ResultSet添加spark的schema成员及DF(DataFrame)成员 /* spark.sc对象因为是全局的,没有导入,需自行定义 teradata的字段类型转换成spark的数据类型 */ import java.sql.{ResultSet, ResultSetMetaData} import org.apache.spark.sql.types._ import org.apache.spark.sql.{DataFrame, Row} object addData

jdbc中java与mysql数据类型的映射

注:这种类型匹配不是强制性标准,特定的JDBC厂商可能会改变这种类型匹配.例如Oracle中的DATE类型是包含时分秒,而java.sql.Date仅仅支持年月日.

Python爬取CSDN博客文章

之前解析出问题,刚刚看到,这次仔细审查了 0 url :http://blog.csdn.net/youyou1543724847/article/details/52818339Redis一点基础的东西目录 1.基础底层数据结构 2.windows下环境搭建 3.java里连接redis数据库 4.关于认证 5.redis高级功能总结1.基础底层数据结构1.1.简单动态字符串SDS定义: ...47分钟前1 url :http://blog.csdn.net/youyou1543724847/

SQL Server 与 ADO.NET 数据类型映射

SQL Server 数据类型映射 .NET Framework 4.5 SQL Server 和 .NET Framework 基于不同的类型系统. Decimal structure has a maximum scale of 28, whereas the SQL Server decimal and numeric data types have a maximum scale of 38.' data-guid="5192ddd1b197626d65c842bb2463470b&qu

SQL Server 数据类型映射 (ADO.NET)

http://msdn.microsoft.com/zh-cn/library/cc716729(VS.90).aspx   SQL Server 数据类型映射 (ADO.NET) .NET Framework 3.5 其他版本 3(共 3)对本文的评价是有帮助 - 评价此主题 更新:November 2007 SQL Server 和 .NET Framework 基于不同的类型系统.例如,.NET Framework Decimal 结构的最大小数位数为 28,而 SQL Server 的

C语言之枚举数据类型

枚举数据类型概述:1.枚举类型是C语言的一种构造类型.它用于声明一组命名的常数,2.当一个变量有几种可能的取值时,可以将它定义为枚举类型.3.枚举类型是由用户自定义的由多个命名枚举常量构成的类型,其声明形式为: 示例:enum tagDAYS {MON, TUE , WED, THU, FRI , SAT, SUN};1.enum tagDAYS是枚举类型,MON等是命名枚举常量.2.默认时枚举常量总是从0开始,后续的枚举常量总是前一个的枚举常量加一.3.如MON为0,TUE为1, .....