Hibernate提供了自動生成表結構的功能,只需要配置
hibernate.hbm2ddl.auto
這個參數即可啓用此功能,這裏測試了一下,各種不同配置下的效果:
首先給個錯誤配置,發現:
WARN: Unrecognized hibernate.hbm2ddl.auto value: 'aaa'. Supported values include 'create', 'create-drop', 'create-only', 'drop', 'update', 'none' and 'validate'. Ignoring
此時是不能啓動hibernate的,但是可以看到可選的配置值爲'create', 'create-drop', 'create-only', 'drop', 'update', 'none' and 'validate',或者可以直接忽略此參數
1.忽略此參數
此時就是沒有此功能,則需要手動操作表
2.create
此時的效果爲:
Hibernate:
drop table if exists User
Hibernate:
create table User (
id integer not null,
birthday datetime(6),
logo tinyblob,
name varchar(255),
primary key (id)
) engine=InnoDB
即先保證刪除此表,然後創建表,數據肯定是會清除的,但是最後不會刪除表
3.create-drop
此時的效果爲:
Hibernate:
drop table if exists User
Hibernate:
create table User (
id integer not null,
birthday datetime(6),
logo tinyblob,
name varchar(255),
primary key (id)
) engine=InnoDB
Hibernate:
/* insert czy.demo.jpa.hibernate.crud.User
*/ insert
into
User
(birthday, logo, name, id)
values
(?, ?, ?, ?)
Hibernate:
drop table if exists User
即先保證刪除此表,然後創建表,數據肯定是會清除的,最後還會刪除表,清除所有痕跡
4.create-only
Hibernate:
create table User (
id integer not null,
birthday datetime(6),
logo tinyblob,
name varchar(255),
primary key (id)
) engine=InnoDB
WARN: GenerationTarget encountered exception accepting command : Error executing DDL "
create table User (
id integer not null,
birthday datetime(6),
logo tinyblob,
name varchar(255),
primary key (id)
) engine=InnoDB" via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "
create table User (
id integer not null,
birthday datetime(6),
logo tinyblob,
name varchar(255),
primary key (id)
) engine=InnoDB" via JDBC Statement
at
Caused by: java.sql.SQLSyntaxErrorException: Table 'user' already exists
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:764)
at com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:648)
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54)
... 67 more
此時只會創建表,沒有前置刪除,也沒有後置刪除
5.drop
Hibernate:
/* insert czy.demo.jpa.hibernate.crud.User
*/ insert
into
User
(birthday, logo, name, id)
values
(?, ?, ?, ?)
Hibernate:
/* insert czy.demo.jpa.hibernate.crud.User
*/ insert
into
User
(birthday, logo, name, id)
values
(?, ?, ?, ?)
ERROR: Table 'jpa_demo.user' doesn't exist
可以看到此時,只有前置刪除,很奇怪,這個設置應該就是爲刪庫準備的
6.update
當數據庫表不存在時,會創建表
當數據庫表存在且與當前實體一致時,不會做任何操作
當數據庫表存在且與當前實體不一致時,會修改表,比如:
修改列名:
Hibernate:
alter table User
add column userId integer not null
但是這個有個問題,實際操作是修改了字段名,然後hibernate沒有修改列名,而是直接添加了一列,原有的id列只是不再爲主鍵,但還是非空列,這顯然不是想要的結果,而且修改@Column註解的name屬性,也會導致增加一列而不是修改列名,這說明hibernate應該不能識別列的刪除和修改,也就是無法對一個列做標識,如果它修改了,只能認爲新增了一列
而且還發現hibernate基本不能識別字段名稱的更改,即@Column註解上的一切更改都無法識別
修改實體名稱、表名:
Hibernate:
create table u (
id varchar(255) not null,
birthday datetime(6),
logo tinyblob,
name varchar(255),
primary key (id)
) engine=InnoDB
Hibernate:
/* insert czy.demo.jpa.hibernate.crud.User
*/ insert
into
u
(birthday, logo, name, id)
values
(?, ?, ?, ?)
此時會創建新的表,這種情況下,所有的字段都會爲最新