JPA使用-實體類上常用註解
- 2019 年 12 月 19 日
- 筆記
@SQLDelete
場景描述
JPA中提供了簡單的CRUD操作,其中刪除操作是物理刪除,但是實際應用中,系統中的數據是一種資源,不能直接刪除,應該做到邏輯刪除,JPA中刪除操作是不可取的。
場景示例
調用JPA的刪除方法,如下程式碼所示:
@Testpublic void testJpaDelete() { //此處根據id刪除角色資訊 roleRepository.deleteById(1);}
執行上面的測試方法,數據表中主鍵為1的數據,已經被刪除掉,看下JPA的執行SQL如下所示:
delete from role where id=?
此語句為JPA刪除操作的默認執行語句。
解決方案
JPA的默認刪除方法,並不可取,可以在Role實體上加上@SQLDelete註解,並寫SQL語句,如下所示:
@SQLDelete(sql = "update role set is_deleted = 1 where id = ?")
上面的註解代表著,只要執行JPA的刪除操作,執行的SQL語句為我們自己定義的SQL語句。
測試一下
@Testpublic void testJpaDelete() { roleRepository.deleteById(2);}
結果列印的SQL執行語句,如下所示
update role set is_deleted = 1 where id = ?
@DynamicInsert
場景描述
在JPA中添加/更新都是使用save()方法,一般情況下,創建數據表的時候,會給某些欄位設置默認的值,避免在插入的時候手動賦值,如創建時間,是否刪除等等。
save方法會把沒有值的對象,默認賦空值,造成,原數據表的默認值失效。
場景示例
添加一個角色,如下所求
@Testpublic void testJpaAdd() { Role role = new Role(); role.setRoleName("小碼農薛堯"); roleRepository.save(role);}
RoleAddDto對象
/** * @description: * @author: Simon.Xue * @date: 2019-02-17 22:15 **/@Datapublic class RoleAddDto implements Serializable { /** * 角色名 */ private String roleName;}
Role數據表的結構為
create table role( id int not null auto_increment, role_name varchar(32) not null comment '角色名', create_time timestamp default current_timestamp comment '創建時間', update_time timestamp default current_timestamp on update current_timestamp comment '更新時間', is_deleted int default 0 comment '是否刪除', primary key (id)) character set utf8mb4 comment '角色表';
從上面數據表的定義語句,我們可以看出來,是否刪除是有默認值0的,但是我們實現執行後的結果為

附:執行sql語句如下
insert into role (create_time, is_deleted, role_name, update_time) values (?, ?, ?, ?)
解決方案
在Role實體類上加上@DynamicUpdate註解,告訴JPA沒有值的屬性不用賦NULL值,重新添加角色如下圖所示

附:執行sql語句如下
insert into role (role_name) values (?)
@DynamicUpdate
場景描述
在JPA的使用過程中,我們常遇到更新資料庫中記錄的數據,一般情況下,我們只會把更新的值傳給save()方法,但是該方法會把沒有更新的值全部覆蓋掉。
場景示例
更新上個例子中id為8的數據,把角色名改成小明的秘密,如下所示
@Testpublic void testJpaUpdate() { Role role = new Role(); role.setId(8); role.setRoleName("小明的秘密"); roleRepository.save(role);}

上面第8條數據更新後,is_deleted的值被賦值為NULL
附:執行sql的語句如下:
update role set create_time=?, is_deleted=?, role_name=?, update_time=? where id=?
解決方案
在Role實體上添加@DynamicUpdate註解,重新更新第8條記錄,執行的sql語句如下
update role set create_time=?, update_time=? where id=?
@ Where
場景描述
一般情況下,查詢語句都是要帶上查詢條件,如過濾掉刪除的數據,把沒有刪除的數據查詢出來,但是JPA默認是沒有帶有任何條件。
解決方案
在實體上添加@Where註解,如下所示
@Data@Table(name = "role")@SQLDelete(sql = "update role set is_deleted = 1 where id = ?")@Entity@Accessors(chain = true)@DynamicInsert@DynamicUpdate@Where(clause = "is_deleted = 0")public class Role implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String roleName; private LocalDateTime createTime; private LocalDateTime updateTime; private Integer isDeleted;}
只要JPA調用任何Role的查詢條件都會默認帶上is_deleted = 0,如下圖所示
