我们在本地作开发时,经常会定义好实体,继而在相应的数据库中建表。而这样建表继烦琐,浪费时间,又容易出错。而Hibernate的hibernate.hbm2ddl.auto
会帮助我们根据定义好的实体,自动创建,更新,验证数据库表。hibernate.hbm2ddl.auto
有好几个选项,接下来我们依次介绍。
hibernate.hbm2ddl.auto
选项none(默认)
在Hiberante启动时,不会执行任何操作。
create-only
在Hibernate启动时,对实体仅会执行建表语句,即使实体对应的表已经存在了,也会重复执行建表语句。
情景一
存在如下实体
@Entity
public class Event {
@Id
@Column(name = "EVENT_ID")
private Long id;
private String title;
@Column(name = "EVENT_DATE")
private Date date;
private int version;
// 省略getter setter
}
Hibernate在启动时,不管实体对应的表存不存在,都会执行建表语句
create table Event (
EVENT_ID bigint not null,
EVENT_DATE datetime(6),
title varchar(255),
version integer not null,
primary key (EVENT_ID)
) engine=InnoDB
drop
在Hiberante启动时,对实体对应的表执行删除语句,即使实体不存在对应的表,都会执行表删除语句。
情景一
存在如下实体
@Entity
public class Event {
@Id
@Column(name = "EVENT_ID")
private Long id;
private String title;
@Column(name = "EVENT_DATE")
private Date date;
private int version;
// 省略getter setter
}
Hibernate在启动时,不管对应的表存不存在,都会执行删除语句。
drop table if exists Event
create
在Hiberante启动时,对实体对应的表执行删除语句,然后再执行建表语句。
情景一
存在如下实体
@Entity
public class Event {
@Id
@Column(name = "EVENT_ID")
private Long id;
private String title;
@Column(name = "EVENT_DATE")
private Date date;
private int version;
// 省略getter setter
}
在Hibernate启动时,不管数据库中对应的表存不存在
都要先执行删除语句
drop table if exists Event
在执行建表语句
create table Event (
EVENT_ID bigint not null,
EVENT_DATE datetime(6),
title varchar(255),
version integer not null,
primary key (EVENT_ID)
) engine=InnoDB
create-drop
在Hibernate启动时,对实体对应的表执行删除语句,然后执行建表语句。在Hibernate关闭时,实体对应的表执行删除语句。
情景一
存在如下实体
@Entity
public class Event {
@Id
@Column(name = "EVENT_ID")
private Long id;
private String title;
@Column(name = "EVENT_DATE")
private Date date;
private int version;
// 省略getter setter
}
Hibernate在启动时会先删除对应的表
drop table if exists Event
重新创建对应的表
create table Event (
EVENT_ID bigint not null,
EVENT_DATE datetime(6),
title varchar(255),
version integer not null,
primary key (EVENT_ID)
) engine=InnoDB
在Hibernate关闭时,会删除对应的表
drop table if exists Event
validate
对实体和对应的表进行校验。
情景一
如果实体中的属性在对应的数据库表中不存在,则会抛出异常。
如对应的实体如下:
@Entity
public class Event {
@Id
@Column(name = "EVENT_ID")
private Long id;
private String title;
@Column(name = "EVENT_DATE")
private Date date;
private int version;
// 省略getter setter
}
数据库中对应的表如下:
CREATE TABLE `EVENTS` (
`EVENT_ID` bigint(20) NOT NULL,
`EVENT_DATE` date DEFAULT NULL,
`title` varchar(255) DEFAULT NULL,
PRIMARY KEY (`EVENT_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
表中缺少了version字段,Hibernate在启动时则会抛出异常。
org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing column [version] in table [EVENT]
情景二
如对应的实体如下:
@Entity
public class Event {
@Id
@Column(name = "EVENT_ID")
private Long id;
private String title;
@Column(name = "EVENT_DATE")
private Date date;
private int version;
// 省略getter setter
}
但是在数据库不存在对应的表,Hibernate在启动时则会抛出如下异常:
org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [Event]
update
实体对应的表如果不存在则会创建。如果实体中新增加了字段,会在相应的表中增加一列。
情景一
存在如下实体
@Entity
public class Event {
@Id
@Column(name = "EVENT_ID")
private Long id;
private String title;
@Column(name = "EVENT_DATE")
private Date date;
private int version;
// 省略getter setter
}
在数据库中不存在对应的表,Hibernate在启动时则会执行建表语句。
create table EVENT (
EVENT_ID bigint not null,
EVENT_DATE date,
title varchar(255),
version integer,
primary key (EVENT_ID)
) engine=InnoDB
情况二
存在如下实体
@Entity
public class Event {
@Id
@Column(name = "EVENT_ID")
private Long id;
private String title;
@Column(name = "EVENT_DATE")
private Date date;
private int version;
// 省略getter setter
}
在数据库中存在对应的表,但是缺失了version字段。
CREATE TABLE `EVENT` (
`EVENT_ID` bigint(20) NOT NULL,
`EVENT_DATE` date DEFAULT NULL,
`title` varchar(255) DEFAULT NULL,
PRIMARY KEY (`EVENT_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Hibernate在启动时则会执行update语句。
alter table hibernate4.EVENT
add column version integer
create, create-drop选项要谨慎使用,因为其会执行删表语句。
validate 一般适用于线上环境,用于校验实体与数据库中的字段是否对应
update 一般用于本地快速开发,定义好实体后,Hibernate会自动创建和更新表,省去了手动更新数据库表的麻烦。