javascript
Spring Data JPA 从入门到精通~基本注解
?@Entity、@Table、@Id、@GeneratedValue、@Basic、@Column、@Transient、@Lob、@Temporal
先看一個 Blog 的案例其中實體的配置如下:
@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; ...... }下面對上面類中用到的注解來一一解釋一下。
(1)@Entity 用于定義對象將會成為被 JPA 管理的實體,將字段映射到指定的數據庫表中,源碼如下:
public @interface Entity {//可選,默認是次實體類的名字,全局唯一。String name() default ""; }(2)@Table 用于指定數據庫的表名:
public @interface Table {//表的名字,可選。如果不填寫,系統認為好實體的名字一樣為表名。String name() default "";//此表的catalog,可選String catalog() default "";//此表所在schema,可選String schema() default "";//唯一性約束,只有創建表的時候有用,默認不需要。UniqueConstraint[] uniqueConstraints() default { };//索引,只有創建表的時候使用,默認不需要。Index[] indexes() default {}; }(3)@Id 定義屬性為數據庫的主鍵,一個實體里面必須有一個,并且必須和 @GeneratedValue 配合使用和成對出現。
(4)@IdClass 利用外部類的聯合主鍵,源碼:
public @interface IdClass { //聯合主鍵的類Class value(); }作為符合主鍵類,要滿足以下幾點要求。
- 必須實現 Serializable 接口。
- 必須有默認的 public 無參數的構造方法。
- 必須覆蓋 equals 和 hashCode 方法。equals 方法用于判斷兩個對象是否相同,EntityManger 通過 find 方法來查找 Entity 時,是根據 equals 的返回值來判斷的。本例中,只有對象的 name 和 email 值完全相同時或同一個對象時則返回 true,否則返回 false。hashCode 方法返回當前對象的哈希碼,生成 hashCode 相同的概率越小越好,算法可以進行優化。
(5)@IdClass 用法
5.1)假設 UserBlog 的聯合主鍵是 createUserId 和 title,新增一個 UserBlogKey 的類。
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 方法我們略過 }5.2)UserBlogEntity.java 稍加改動,實體類上需要加 @IdClass 注解和兩個主鍵上都得加 @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 我們做的改動:
public interface UserBlogRepository extends JpaRepository<UserBlogEntity,UserBlogKey>{ }5.4)使用的時候:
@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;//通過Sequences生成Id,常見的是Orcale數據庫ID生成規則,這個時候需要配合@SequenceGenerator使用String generator() default ""; }GenerationType 一共有以下四個值:
public enum GenerationType {//通過表產生主鍵,框架借由表模擬序列產生主鍵,使用該策略可以使應用更易于數據庫移植。TABLE,//通過序列產生主鍵,通過 @SequenceGenerator 注解指定序列名, MySql 不支持這種方式;SEQUENCE,//采用數據庫ID自增長, 一般用于mysql數據庫IDENTITY, //JPA 自動選擇合適的策略,是默認選項;AUTO }(7)@Basic 表示屬性是到數據庫表的字段的映射。如果實體的字段上沒有任何注解,默認即為 @Basic。
public @interface Basic {//可選,EAGER(默認):立即加載;LAZY:延遲加載。(LAZY主要應用在大字段上面)FetchType fetch() default EAGER;//可選。這個字段是否可以為null,默認是true。boolean optional() default true; }(8)@Transient 表示該屬性并非一個到數據庫表的字段的映射,表示非持久化屬性。JPA 映射數據庫的時候忽略它,與 @Basic 相反的作用。
(9)@Column 定義該屬性對應數據庫中的列名。
public @interface Column {//數據庫中的表的列名;可選,如果不填寫認為字段名和實體屬性名一樣。String name() default "";//是否唯一。默認flase,可選。boolean unique() default false;//數據字段是否允許空。可選,默認true。boolean nullable() default true;//執行insert操作的時候是否包含此字段,默認,true,可選。boolean insertable() default true;//執行update的時候是否包含此字段,默認,true,可選。boolean updatable() default true;//表示該字段在數據庫中的實際類型。String columnDefinition() default "";//數據庫字段的長度,可選,默認255int length() default 255; }(10)@Temporal 用來設置 Date 類型的屬性映射到對應精度的字段。
- @Temporal(TemporalType.DATE)映射為日期 // date (只有日期)
- @Temporal(TemporalType.TIME)映射為日期 // time (是有時間)
- @Temporal(TemporalType.TIMESTAMP)映射為日期 // date time (日期+時間)
(11)@Enumerated 這個注解很好用,直接映射 enum 枚舉類型的字段。
1)看源碼:
public @interface Enumerated { //枚舉映射的類型,默認是ORDINAL(即枚舉字段的下標)。EnumType value() default ORDINAL; } public enum EnumType {//映射枚舉字段的下標ORDINAL,//映射枚舉的NameSTRING }2)看例子:
//有一個枚舉類,用戶的性別 public enum Gender {MAIL("男性"), FMAIL("女性");private String value;private Gender(String value) {this.value = value;} } //實體類@Enumerated的寫法如下 @Entity @Table(name = "tb_user") public class User implements Serializable {@Enumerated(EnumType.STRING)@Column(name = "user_gender")private Gender gender;....................... }這時候插入兩條數據,數據庫里面的值是 MAIL/FMAIL,而不是“男性”/女性。
如果我們用 @Enumerated(EnumType.ORDINAL),這時候數據庫里面的值是 0,1。但是實際工作中,不建議用數字下標,因為枚舉里面的屬性值是會不斷新增的,如果新增一個,位置變化了就慘了。
(12)@Lob 將屬性映射成數據庫支持的大對象類型,支持以下兩種數據庫類型的字段。
- Clob(Character Large Ojects)類型是長字符串類型,java.sql.Clob、Character[]、char[] 和 String 將被映射為 Clob 類型。
- Blob(Binary Large Objects)類型是字節類型,java.sql.Blob、Byte[]、byte[]和實現了 Serializable 接口的類型將被映射為 Blob 類型。
- 由于 Clob,Blob 占用內存空間較大一般配合 @Basic(fetch=FetchType.LAZY) 將其設置為延遲加載。
(13)@SqlResultSetMapping、@EntityResult、@ColumnResult 配合 @NamedNativeQuery 一起使用的。
在實際工作中不建議這樣配置,因為必要性比較少,如果這種配置多了會把 @entity 用配置 XML 思路。看一個案例簡單說明一下:
@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 { ...... }總結
以上是生活随笔為你收集整理的Spring Data JPA 从入门到精通~基本注解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 极限编程实践
- 下一篇: Spring Data JPA 从入门到