CRUD簡述
寫業務代碼我們免不了會一直圍繞着CRUD轉,這是基礎,也是根本,把CRUD做好了也是一件不簡單的事情,讓我們紮紮實實地去做好這件事。
插入
批量插入:
insert into test_table
(`name`,`age`)
values
<foreach collection="list" item="item" separator=",">
(
#{item.name},
#{item.age}
)
</foreach>
注意:如果dao層傳入的集合參數使用了@Param(value=“xxxList”),則語法要調整:
insert into test_table
(`name`,`age`)
values
<foreach collection="xxxList" item="item" separator=",">
(
#{item.name},
#{item.age}
)
</foreach>
批量插入更新
假設name是唯一主鍵,插入時可能會存在衝突
insert into test_table
(`name`,`age`)
values
<foreach collection="xxxList" item="item" separator=",">
(
#{item.name},
#{item.age}
)
</foreach>
ON DUPLICATE KEY UPDATE age=values(age)
foreach各參數說明:
1.collection:映射Mpper接口方法參數的集合名稱,如果Mapper接口方法參數使用了@Param(value=“xxx”)指定了名稱,則這裏使用xxx,反之則使用默認值”list”
2.item:集合中單個元素的別名
3.index:迭代次數,從0開始
4.open:循環sql開始符號
5.close:循環sql結束符號
6.separator:每次迭次之間的分隔符
查詢
模糊查詢
- 如果傳入的模糊字段是字符串,建議先進行trim()
- 如果數據庫有相關字段且建立了索引,可以在數據庫層使用like進行模糊查詢,注意mybatis like用法-LIKE CONCAT(’%’,#{searchItem},’%’)
- 如果有些字段數據庫中沒有,則可以通過代碼來實現,使用排除法,如果需求場景是這樣:前端傳入的一個模糊字段匹配多個後端字段,僞代碼如下:
List<T> result = new ArrayList();
if(fuzzyItem != null) {
// 匹配字段item1
if(item1.contains(fuzzyItem)) {
// 滿足要求,對應的對象數據加入返回結果中
result.add(item1);
continue;
}
// 匹配字段item2
if(item2.contains(fuzzyItem)) {
// 滿足要求,對應的對象數據加入返回結果中
result.add(item2);
continue;
}
// 沒有命中,則繼續下一輪遍歷
continue;
}
分頁查詢
- 使用github分頁器,PageHelper.startPage(pageNum, pageSize);
- 如果是對外部接口返回的全量數據進行分頁,可以參考如下方法:
public static <T> List<T> readByPage(List<T> srcList, int pageNum, int pageSize) {
if (CollectionUtils.isEmpty(srcList)) {
return new ArrayList<>();
}
int fromIndex = pageNum > 0 ? (pageNum - 1) * pageSize : 0;
int toIndex = pageNum * pageSize;
int size = srcList.size();
if (size <= fromIndex) {
return new ArrayList<>();
} else if (size > fromIndex && size < toIndex) {
return srcList.subList(fromIndex, size);
} else {
return srcList.subList(fromIndex, toIndex);
}
}
- 如果是接口做了查詢數量限制,比如:一次查詢100的用戶id對應的用戶數據,可以參考如下方法:
public static <T, R> List<R> readByPage(List<T> params, int limit, Function<List<T>, List<R>> readFunction) {
if (CollectionUtils.isEmpty(params)) {
return new ArrayList<>();
}
if (params.size() <= limit) {
return readFunction.apply(params);
} else {
// 不能用subList,會報併發修改異常
List<T> tmpParams = new ArrayList<>();
for (int i = 0; i < limit; i++) {
tmpParams.add(params.get(i));
}
List<R> totalResult = readFunction.apply(tmpParams);
int total = params.size();
List<T> leftParams = new ArrayList<>();
// for循環去填充參數,當limit較小,總的size較大時,會比較耗性能
for (int i = limit; i < total; i++) {
leftParams.add(params.get(i));
}
List<R> tmpResult = readByPage(leftParams, limit, readFunction);
if (totalResult != null && tmpResult != null) {
totalResult.addAll(tmpResult);
}
return totalResult;
}
}
多字段排序
- 使用數據order by實現多字段排序:oder by filed1 desc, filed2 desc
- 使用流排序:stream().sorted(Comparator.comparing(Function1).thenComparing(Function2).thenComparing(Function3))
- 使用集合工具排序:
Collections.sort(srcList,Comparator.comparing().thenComparing().thenComparing())
修改
批量修改
- 使用mybatis-foreach語法組裝sql,注意這種方式需要在mysql連接配置中加:&allowMultiQueries=true屬性
<foreach collection="list" item="item" index="index" open="" close="" separator=";">
update test_table
<set>
<if test="item.name != null">
clazz_id = #{item.name,jdbcType=VARCHAR},
</if>
<if test="item.age != null">
teacher_id = #{item.age,jdbcType=BIGINT},
</if>
</set>
where id = #{item.id,jdbcType=BIGINT}
</foreach>
“allowMultiQueries=true”的作用:
1.可以在sql語句後攜帶分號,實現多語句執行。
2.可以執行批處理,同時發出多個SQL語句
多字段修改
- 修改單條記錄多字段注意不能使用and連接符合,and符號在這裏是邏輯與操作
刪除
- 業務相關的數據儘量使用邏輯刪除
- 刪除操作儘量要做權限驗證,表設計中要設計operator_id、create_date、update_date,記錄操作者、創建時間、更新時間