文章目錄
- 多記錄操作
- 邏輯删除
- 問題引入
- 實作步驟
- 步驟1:修改資料庫表添加`deleted`列
- 步驟2:實體類添加屬性
- 步驟3:運作删除方法
- 知識點:@TableLogic
多記錄操作
先來看下問題:

之前添加了很多商品到購物車,過了幾天發現這些東西又不想要了,該怎麼辦呢?
很簡單删除掉,但是一個個删除的話還是比較慢和費事的,是以一般會給使用者一個批量操作,也就是前面有一個複選框,使用者一次可以勾選多個也可以進行全選,然後删一次就可以将購物車清空,這個就需要用到
批量删除
的操作了。
具體該如何實作多條删除,我們找找對應的API方法
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
翻譯方法的字面意思為:删除(根據ID 批量删除),參數是一個集合,可以存放多個id值。
需求:根據傳入的id集合将資料庫表中的資料删除掉。
@SpringBootTest
class Mybatisplus03DqlApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testDelete(){
//删除指定多條資料
List<Long> list = new ArrayList<>();
list.add(1402551342481838081L);
list.add(1402553134049501186L);
list.add(1402553619611430913L);
userDao.deleteBatchIds(list);
}
}
執行成功後,資料庫表中的資料就會按照指定的id進行删除。
除了按照id集合進行批量删除,也可以按照id集合進行批量查詢,還是先來看下API
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
方法名稱翻譯為:查詢(根據ID 批量查詢),參數是一個集合,可以存放多個id值。
需求:根據傳入的ID集合查詢使用者資訊
@SpringBootTest
class Mybatisplus03DqlApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testGetByIds(){
//查詢指定多條資料
List<Long> list = new ArrayList<>();
list.add(1L);
list.add(3L);
list.add(4L);
userDao.selectBatchIds(list);
}
}
查詢結果就會按照指定傳入的id值進行查詢
邏輯删除
問題引入
先來分析下問題:
- 這是一個員工和其所簽的合同表,關系是一個員工可以簽多個合同,是一個一(員工)對多(合同)的表
- 員工ID為1的張業績,總共簽了三個合同,如果此時他離職了,我們需要将員工表中的資料進行删除,會執行delete操作
- 如果表在設計的時候有主外鍵關系,那麼同時也得将合同表中的前三條資料也删除掉
- 後期要統計所簽合同的總金額,就會發現對不上,原因是已經将員工1簽的合同資訊删除掉了
- 如果隻删除員工不删除合同表資料,那麼合同的員工編号對應的員工資訊不存在,那麼就會出現垃圾資料,就會出現無主合同,根本不知道有張業績這個人的存在
- 是以經過分析,我們不應該将表中的資料删除掉,而是需要進行保留,但是又得把離職的人和在職的人進行區分,這樣就解決了上述問題,如:
- 區分的方式,就是在員工表中添加一列資料
,如果為0說明在職員工,如果離職則将其改完1,(0和1所代表的含義是可以自定義的)deleted
是以對于删除操作業務問題來說有:
- 實體删除:業務資料從資料庫中丢棄,執行的是delete操作
- 邏輯删除:為資料設定是否可用狀态字段,删除時設定狀态字段為不可用狀态,資料保留在資料庫中,執行的是update操作
MP中邏輯删除具體該如何實作?
實作步驟
步驟1:修改資料庫表添加 deleted
列
deleted
字段名可以任意,内容也可以自定義,比如
0
代表正常,
1
代表删除,可以在添加列的同時設定其預設值為
0
正常。
步驟2:實體類添加屬性
(1)添加與資料庫表的列對應的一個屬性名,名稱可以任意,如果和資料表列名對不上,可以使用@TableField進行關系映射,如果一緻,則會自動對應。
(2)辨別新增的字段為邏輯删除字段,使用
@TableLogic
@Data
//@TableName("tbl_user") 可以不寫是因為配置了全局配置
public class User {
@TableId(type = IdType.ASSIGN_UUID)
private String id;
private String name;
@TableField(value="pwd",select=false)
private String password;
private Integer age;
private String tel;
@TableField(exist=false)
private Integer online;
@TableLogic(value="0",delval="1")
//value為正常資料的值,delval為删除資料的值
private Integer deleted;
}
步驟3:運作删除方法
@SpringBootTest
class Mybatisplus03DqlApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testDelete(){
userDao.deleteById(1L);
}
}
從測試結果來看,邏輯删除最後走的是update操作,會将指定的字段修改成删除狀态對應的值。
思考
邏輯删除,對查詢有沒有影響呢?
- 執行查詢操作
@SpringBootTest
class Mybatisplus03DqlApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testFind(){
System.out.println(userDao.selectList(null));
}
}
運作測試,會發現列印出來的sql語句中會多一個查詢條件,如:
可想而知,MP的邏輯删除會将所有的查詢都添加一個未被删除的條件,也就是已經被删除的資料是不應該被查詢出來的。
- 如果還是想把已經删除的資料都查詢出來該如何實作呢?
@Mapper
public interface UserDao extends BaseMapper<User> {
//查詢所有資料包含已經被删除的資料
@Select("select * from tbl_user")
public List<User> selectAll();
}
- 如果每個表都要有邏輯删除,那麼就需要在每個模型類的屬性上添加
@TableLogic
注解,如何優化?
在配置檔案中添加全局配置,如下:
mybatis-plus:
global-config:
db-config:
# 邏輯删除字段名
logic-delete-field: deleted
# 邏輯删除字面值:未删除為0
logic-not-delete-value: 0
# 邏輯删除字面值:删除為1
logic-delete-value: 1
介紹完邏輯删除,邏輯删除的本質為:
邏輯删除的本質其實是修改操作。如果加了邏輯删除字段,查詢資料時也會自動帶上邏輯删除字段。
執行的SQL語句為:
UPDATE tbl_user SET deleted=1 where id = ? AND deleted=0
執行資料結果為:
知識點:@TableLogic
名稱 | @TableLogic |
類型 | 屬性注解 |
位置 | 模型類中用于表示删除字段的屬性定義上方 |
作用 | 辨別該字段為進行邏輯删除的字段 |
相關屬性 |