JPA @Table 注解


@Table 是類級別的注解,用於聲明實體映射到數據庫中的具體的表。

參數 類型 描述
name String 表的名稱,默認為實體名稱(參考 @Entity 注解的 name 參數說明),因此如果實體名稱與映射的表名稱一致時,@Table 注解常常可以省略。
catalog String 默認為數據庫系統缺省的 catalog。
schema String 默認為用戶缺省的 schema。
uniqueConstraints UniqueConstraint[] 表的唯一約束(除了由 @Column 和 @JoinColumn 注解指定的約束以及主鍵的約束之外的約束),通過使用 @UniqueConstraint 注解來聲明,僅在允許自動更新數據庫表結構的場景中起到作用,默認沒有其他額外的約束條件。
indexes Index[] 表的索引,通過使用 @Index 注解來聲明,僅在允許自動更新數據庫表結構的場景中起到作用,默認沒有其他額外的索引。

1 catalog 和 schema 的區別

catalog 和 schema 主要用來解決數據庫系統命名沖突的問題。一個數據庫系統可以包含多個 catalog,每個 catalog 可以包含多個 schema,而每個 schema 又可以包含多個數據庫對象(表、視圖等)。不同的數據庫系統對 catalog 和 schema 的支持方式有所不同,常見的數據庫系統:

數據庫系統 catalog schema
MySQL 不支持 數據庫名
Oracle 不支持 用戶 ID
SQLServer 數據庫名 對象屬主名
DB2 指定數據庫對象時,Catalog 可以省略 Catalog 屬主名
Sybase 數據庫名 數據庫屬主名

2 唯一約束和索引的區別

唯一約束是用來確保數據的正確性,它不允許表中存在重復的數據,若新插入的數據在表中已經存在,則更新操作失敗。在數據庫系統中,創建一個唯一約束的同時,也會為該約束所指定的所有列創建一個唯一索引,即約束包含索引。

索引是用來優化數據庫表數據的檢索性能的。通常,出現在查詢 SQL 的 WHERE 子句和 JOIN 子句中的列可以考慮為其建立索引。

3. @UniqueConstraint

用於聲明表的唯一約束,這些僅在允許自動更新數據庫表結構的場景中起到作用。

參數 類型 描述
name String 約束名稱,如果不指定,默認使用數據庫提供商所生成的值。
columnNames String[] 約束的列名稱

4. @Index

用於聲明表的索引,這些僅在允許自動更新數據庫表結構的場景中起到作用。另外,不需要為表的主鍵指定索引,因為主鍵索引會自動被創建。

參數 類型 描述
name String 索引名稱,如果不指定,默認使用數據庫提供商所生成的值。
columnList String 要包含在索引中的列名稱。
unique boolean 索引是否唯一,默認為 false。

5. @Table

5.1 唯一約束

name 列、mail 列的值必須是唯一的,不允許出現重復的值:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

 

@Entity(name = "person")

@Table(uniqueConstraints = {

@UniqueConstraint(name = "unique_name", columnNames = "name"),

@UniqueConstraint(name = "unique_mail", columnNames = "mail")

})

public class Person implements Serializable {

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

private Long id;

private String name;

private String mail;

// getters and setters

}

產生的 DDL 語句(MySQL):

 

1

2

3

4

5

6

7

8

 

CREATE TABLE `person` (

`id` bigint(20) NOT NULL AUTO_INCREMENT,

`mail` varchar(255) DEFAULT NULL,

`name` varchar(255) DEFAULT NULL,

PRIMARY KEY (`id`),

UNIQUE KEY `unique_name` (`name`),

UNIQUE KEY `unique_mail` (`mail`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

5.2 聯合唯一約束

多列聯合唯一約束,name 列和 mail 列不能同時出現相同的值:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

 

@Entity(name = "person")

@Table(uniqueConstraints = @UniqueConstraint(name = "unique_name_mail", columnNames = {"name", "mail"}))

public class Person implements Serializable {

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

private Long id;

private String name;

private String mail;

// getters and setters

}

產生的 DDL 語句(MySQL):

 

1

2

3

4

5

6

7

 

CREATE TABLE `person` (

`id` bigint(20) NOT NULL AUTO_INCREMENT,

`mail` varchar(255) DEFAULT NULL,

`name` varchar(255) DEFAULT NULL,

PRIMARY KEY (`id`),

UNIQUE KEY `unique_name_mail` (`name`,`mail`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

5.3 單列索引

為 name 列和 mail 列分別建立索引:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

 

@Entity(name = "person")

@Table(indexes = {

@Index(name = "index_name", columnList = "name"),

@Index(name = "index_mail", columnList = "mail")

})

public class Person implements Serializable {

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

private Long id;

private String name;

private String mail;

// getters and setters

}

產生的 DDL 語句(MySQL):

 

1

2

3

4

5

6

7

8

 

CREATE TABLE `person` (

`id` bigint(20) NOT NULL AUTO_INCREMENT,

`mail` varchar(255) DEFAULT NULL,

`name` varchar(255) DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `index_name` (`name`),

KEY `index_mail` (`mail`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

5.4 多列索引

為 name 列和 mail 列建立多列索引:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

 

@Entity(name = "person")

@Table(indexes = @Index(name = "index_name_mail", columnList = "name,mail"))

public class Person implements Serializable {

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

private Long id;

private String name;

private String mail;

// getters and setters

}

產生的 DDL 語句(MySQL):

 

1

2

3

4

5

6

7

 

CREATE TABLE `person` (

`id` bigint(20) NOT NULL AUTO_INCREMENT,

`mail` varchar(255) DEFAULT NULL,

`name` varchar(255) DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `index_name_mail` (`name`,`mail`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

5.5 單列索引和多列索引的區別

當 SQL 查詢條件中包含 name 和 mail 時:

 

1

 

SELECT * FROM PERSON WHERE NAME = 'U79028' AND MAIL = '79029@163.com'

如果為 name 和 mail 列分別建立索引,當執行查詢時,MySQL 只能使用一個索引。如果發現有多個單列索引可用,MySQL 會試圖選擇一個限制最嚴格的索引來檢索,而其他索引則利用不上。

使用分析器分析查詢 SQL:

 

1

 

EXPLAIN SELECT * FROM PERSON WHERE NAME = 'U79028' AND MAIL = '79029@163.com'

結果如下:

 

1

2

3

4

5

 

+----+-------------+--------+------+-----------------------+------------+---------+-------+------+-------------+

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

+----+-------------+--------+------+-----------------------+------------+---------+-------+------+-------------+

| 1 | SIMPLE | PERSON | ref | index_name,index_mail | index_mail | 768 | const | 1 | Using where |

+----+-------------+--------+------+-----------------------+------------+---------+-------+------+-------------+

MySQL 優化器如果發現可以使用多個索引查找后的交集/並集定位數據,那么 MySQL 優化器就會嘗試使用 index merge(索引合並)的方式來查詢:

 

1

 

EXPLAIN SELECT * FROM PERSON WHERE NAME = 'U79028' AND MAIL = '79028@163.com'

結果如下:

 

1

2

3

4

5

 

+----+-------------+--------+-------------+-----------------------+-----------------------+---------+------+------+------------------------------------------------------------------+

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

+----+-------------+--------+-------------+-----------------------+-----------------------+---------+------+------+------------------------------------------------------------------+

| 1 | SIMPLE | PERSON | index_merge | index_name,index_mail | index_name,index_mail | 768,768 | NULL | 1 | Using intersect(index_name,index_mail); Using where; Using index |

+----+-------------+--------+-------------+-----------------------+-----------------------+---------+------+------+------------------------------------------------------------------+

對於多列索引,由於索引文件以B樹的數據結構存儲,MySQL 能夠快速轉到合適的 name,然后再轉到合適的 mail。在建立多列索引時,應該將嚴格的索引放在前面,這樣篩選數據的時候力度會更大,效率更高。

使用分析器分析查詢 SQL:

 

1

 

EXPLAIN SELECT * FROM PERSON WHERE NAME = 'U79028' AND MAIL = '79028@163.com'

結果如下:

 

1

2

3

4

5

 

+----+-------------+--------+------+-----------------+-----------------+---------+-------------+------+--------------------------+

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

+----+-------------+--------+------+-----------------+-----------------+---------+-------------+------+--------------------------+

| 1 | SIMPLE | PERSON | ref | index_name_mail | index_name_mail | 1536 | const,const | 2 | Using where; Using index |

+----+-------------+--------+------+-----------------+-------------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM