javascript
Spring Data JPA 从入门到精通~基本注解
?@Entity、@Table、@Id、@GeneratedValue、@Basic、@Column、@Transient、@Lob、@Temporal
先看一個(gè) Blog 的案例其中實(shí)體的配置如下:
@Entity @Table(name = "user_blog", schema = "test") public class UserBlogEntity {@Id@Column(name = "id", nullable = false)@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;@Column(name = "title", nullable = true, length = 200)private String title;@Basic@Column(name = "create_user_id", nullable = true)private Integer createUserId;@Basic@Column(name = "blog_content", nullable = true, length = -1)@Lobprivate String blogContent;@Basic(fetch = FetchType.LAZY)@Column(name = "image", nullable = true)@Lobprivate byte[] image;@Basic@Column(name = "create_time", nullable = true)@Temporal(TemporalType.TIMESTAMP)private Date createTime;@Basic@Column(name = "create_date", nullable = true)@Temporal(TemporalType.DATE)private Date createDate;@Transientprivate String transientSimple; ...... }下面對(duì)上面類(lèi)中用到的注解來(lái)一一解釋一下。
(1)@Entity 用于定義對(duì)象將會(huì)成為被 JPA 管理的實(shí)體,將字段映射到指定的數(shù)據(jù)庫(kù)表中,源碼如下:
public @interface Entity {//可選,默認(rèn)是次實(shí)體類(lèi)的名字,全局唯一。String name() default ""; }(2)@Table 用于指定數(shù)據(jù)庫(kù)的表名:
public @interface Table {//表的名字,可選。如果不填寫(xiě),系統(tǒng)認(rèn)為好實(shí)體的名字一樣為表名。String name() default "";//此表的catalog,可選String catalog() default "";//此表所在schema,可選String schema() default "";//唯一性約束,只有創(chuàng)建表的時(shí)候有用,默認(rèn)不需要。UniqueConstraint[] uniqueConstraints() default { };//索引,只有創(chuàng)建表的時(shí)候使用,默認(rèn)不需要。Index[] indexes() default {}; }(3)@Id 定義屬性為數(shù)據(jù)庫(kù)的主鍵,一個(gè)實(shí)體里面必須有一個(gè),并且必須和 @GeneratedValue 配合使用和成對(duì)出現(xiàn)。
(4)@IdClass 利用外部類(lèi)的聯(lián)合主鍵,源碼:
public @interface IdClass { //聯(lián)合主鍵的類(lèi)Class value(); }作為符合主鍵類(lèi),要滿(mǎn)足以下幾點(diǎn)要求。
- 必須實(shí)現(xiàn) Serializable 接口。
- 必須有默認(rèn)的 public 無(wú)參數(shù)的構(gòu)造方法。
- 必須覆蓋 equals 和 hashCode 方法。equals 方法用于判斷兩個(gè)對(duì)象是否相同,EntityManger 通過(guò) find 方法來(lái)查找 Entity 時(shí),是根據(jù) equals 的返回值來(lái)判斷的。本例中,只有對(duì)象的 name 和 email 值完全相同時(shí)或同一個(gè)對(duì)象時(shí)則返回 true,否則返回 false。hashCode 方法返回當(dāng)前對(duì)象的哈希碼,生成 hashCode 相同的概率越小越好,算法可以進(jìn)行優(yōu)化。
(5)@IdClass 用法
5.1)假設(shè) UserBlog 的聯(lián)合主鍵是 createUserId 和 title,新增一個(gè) UserBlogKey 的類(lèi)。
UserBlogKey.class
import java.io.Serializable; public class UserBlogKey implements Serializable {private String title;private Integer createUserId;public UserBlogKey() {}public UserBlogKey(String title, Integer createUserId) {this.title = title;this.createUserId = createUserId;} .....//get set 方法我們略過(guò) }5.2)UserBlogEntity.java 稍加改動(dòng),實(shí)體類(lèi)上需要加 @IdClass 注解和兩個(gè)主鍵上都得加 @Id 注解,如下。
@Entity @Table(name = "user_blog", schema = "test") @IdClass(value = UserBlogKey.class) public class UserBlogEntity {@Column(name = "id", nullable = false)private Integer id;@Id@Column(name = "title", nullable = true, length = 200)private String title;@Id@Column(name = "create_user_id", nullable = true)private Integer createUserId; ......//不變的部分我們省略 }5.3)UserBlogRepository 我們做的改動(dòng):
public interface UserBlogRepository extends JpaRepository<UserBlogEntity,UserBlogKey>{ }5.4)使用的時(shí)候:
@RequestMapping(path = "/blog/{title}/{createUserId}") @ResponseBody public Optional<UserBlogEntity> showBlogs(@PathVariable(value = "createUserId") Integer createUserId,@PathVariable("title") String title) {return userBlogRepository.findById(new UserBlogKey(title,createUserId)); }(6)@GeneratedValue 主鍵生成策略:
public @interface GeneratedValue {//Id的生成策略GenerationType strategy() default AUTO;//通過(guò)Sequences生成Id,常見(jiàn)的是Orcale數(shù)據(jù)庫(kù)ID生成規(guī)則,這個(gè)時(shí)候需要配合@SequenceGenerator使用String generator() default ""; }GenerationType 一共有以下四個(gè)值:
public enum GenerationType {//通過(guò)表產(chǎn)生主鍵,框架借由表模擬序列產(chǎn)生主鍵,使用該策略可以使應(yīng)用更易于數(shù)據(jù)庫(kù)移植。TABLE,//通過(guò)序列產(chǎn)生主鍵,通過(guò) @SequenceGenerator 注解指定序列名, MySql 不支持這種方式;SEQUENCE,//采用數(shù)據(jù)庫(kù)ID自增長(zhǎng), 一般用于mysql數(shù)據(jù)庫(kù)IDENTITY, //JPA 自動(dòng)選擇合適的策略,是默認(rèn)選項(xiàng);AUTO }(7)@Basic 表示屬性是到數(shù)據(jù)庫(kù)表的字段的映射。如果實(shí)體的字段上沒(méi)有任何注解,默認(rèn)即為 @Basic。
public @interface Basic {//可選,EAGER(默認(rèn)):立即加載;LAZY:延遲加載。(LAZY主要應(yīng)用在大字段上面)FetchType fetch() default EAGER;//可選。這個(gè)字段是否可以為null,默認(rèn)是true。boolean optional() default true; }(8)@Transient 表示該屬性并非一個(gè)到數(shù)據(jù)庫(kù)表的字段的映射,表示非持久化屬性。JPA 映射數(shù)據(jù)庫(kù)的時(shí)候忽略它,與 @Basic 相反的作用。
(9)@Column 定義該屬性對(duì)應(yīng)數(shù)據(jù)庫(kù)中的列名。
public @interface Column {//數(shù)據(jù)庫(kù)中的表的列名;可選,如果不填寫(xiě)認(rèn)為字段名和實(shí)體屬性名一樣。String name() default "";//是否唯一。默認(rèn)flase,可選。boolean unique() default false;//數(shù)據(jù)字段是否允許空。可選,默認(rèn)true。boolean nullable() default true;//執(zhí)行insert操作的時(shí)候是否包含此字段,默認(rèn),true,可選。boolean insertable() default true;//執(zhí)行update的時(shí)候是否包含此字段,默認(rèn),true,可選。boolean updatable() default true;//表示該字段在數(shù)據(jù)庫(kù)中的實(shí)際類(lèi)型。String columnDefinition() default "";//數(shù)據(jù)庫(kù)字段的長(zhǎng)度,可選,默認(rèn)255int length() default 255; }(10)@Temporal 用來(lái)設(shè)置 Date 類(lèi)型的屬性映射到對(duì)應(yīng)精度的字段。
- @Temporal(TemporalType.DATE)映射為日期 // date (只有日期)
- @Temporal(TemporalType.TIME)映射為日期 // time (是有時(shí)間)
- @Temporal(TemporalType.TIMESTAMP)映射為日期 // date time (日期+時(shí)間)
(11)@Enumerated 這個(gè)注解很好用,直接映射 enum 枚舉類(lèi)型的字段。
1)看源碼:
public @interface Enumerated { //枚舉映射的類(lèi)型,默認(rèn)是ORDINAL(即枚舉字段的下標(biāo))。EnumType value() default ORDINAL; } public enum EnumType {//映射枚舉字段的下標(biāo)ORDINAL,//映射枚舉的NameSTRING }2)看例子:
//有一個(gè)枚舉類(lèi),用戶(hù)的性別 public enum Gender {MAIL("男性"), FMAIL("女性");private String value;private Gender(String value) {this.value = value;} } //實(shí)體類(lèi)@Enumerated的寫(xiě)法如下 @Entity @Table(name = "tb_user") public class User implements Serializable {@Enumerated(EnumType.STRING)@Column(name = "user_gender")private Gender gender;....................... }這時(shí)候插入兩條數(shù)據(jù),數(shù)據(jù)庫(kù)里面的值是 MAIL/FMAIL,而不是“男性”/女性。
如果我們用 @Enumerated(EnumType.ORDINAL),這時(shí)候數(shù)據(jù)庫(kù)里面的值是 0,1。但是實(shí)際工作中,不建議用數(shù)字下標(biāo),因?yàn)槊杜e里面的屬性值是會(huì)不斷新增的,如果新增一個(gè),位置變化了就慘了。
(12)@Lob 將屬性映射成數(shù)據(jù)庫(kù)支持的大對(duì)象類(lèi)型,支持以下兩種數(shù)據(jù)庫(kù)類(lèi)型的字段。
- Clob(Character Large Ojects)類(lèi)型是長(zhǎng)字符串類(lèi)型,java.sql.Clob、Character[]、char[] 和 String 將被映射為 Clob 類(lèi)型。
- Blob(Binary Large Objects)類(lèi)型是字節(jié)類(lèi)型,java.sql.Blob、Byte[]、byte[]和實(shí)現(xiàn)了 Serializable 接口的類(lèi)型將被映射為 Blob 類(lèi)型。
- 由于 Clob,Blob 占用內(nèi)存空間較大一般配合 @Basic(fetch=FetchType.LAZY) 將其設(shè)置為延遲加載。
(13)@SqlResultSetMapping、@EntityResult、@ColumnResult 配合 @NamedNativeQuery 一起使用的。
在實(shí)際工作中不建議這樣配置,因?yàn)楸匾员容^少,如果這種配置多了會(huì)把 @entity 用配置 XML 思路??匆粋€(gè)案例簡(jiǎn)單說(shuō)明一下:
@NamedNativeQueries({@NamedNativeQuery(name = "getUsers",query = "select id,username,usertype from t_xfw_operator order by id desc",resultSetMapping = "usersMap") }) @SqlResultSetMappings({@SqlResultSetMapping(name = "usersMap",entities = {},columns = {@ColumnResult(name = "id"),@ColumnResult(name="username"),@ColumnResult(name="usertype")}) }) @Entity @Table(name = "operator") public class Operator { ...... }總結(jié)
以上是生活随笔為你收集整理的Spring Data JPA 从入门到精通~基本注解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 极限编程实践
- 下一篇: feedback.php,feedbac