1. 程式人生 > >(四)springboot + mybatis plus詳細拆解CRUD

(四)springboot + mybatis plus詳細拆解CRUD

吐槽 : mmp…, 誰能理解我現在的心情,這篇文章是第三次寫了,吐槽一,谷歌最新版和搜狗輸入法衝突導致瀏覽器崩潰的問題。真的mmp文章寫到一半瀏覽器蹦了,再次恢復的時候文章沒了。。。重寫。吐槽二,csdn的Markdown編輯器為什麼不自動儲存。。。mmp第二遍重寫。這是第三遍md。廢話不說了開始說正事

註明 : 本篇文章將介紹springboot+mybatis-plus通過AutoGenerator自動生成entrty、controller、service、dao、mapper後對於基本的CRUD的操作和注意事項。

初始化專案搭建

初始化專案我就不在一一闡述了,如果有不知道的童鞋可以看我的

上篇博文來做專案的初始化搭建,也可以去Gitee下載原始碼
原始碼地址 Gitee

層級程式碼展示

在這裡插入圖片描述

上圖為自動生成後的層級展示,那麼下面就開始我們的測試之路

在測試之前我們需要注意一些要點,如下放程式碼所示我們需要在yml配置檔案中加入下面的程式碼塊。這樣在我們測試的時候會在控制檯列印sql語句供我們參考

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

例項測試

 /**
     * <p>
     *     insert 插入測試
     * </p>
     */
    @Test
    public void insertLoads() {
        User user = new User();
        user.setEmail("
[email protected]
"); user.setAge(12); Integer insert = mapper.insert(user); System.out.println("return insert value = " + insert); }

sql執行和列印結果

==>  Preparing: INSERT INTO user ( id, age, email ) VALUES ( ?, ?, ? ) 
==> Parameters: 1046280811781570561(Long), 12(Integer), 
[email protected]
(String) <== Updates: 1 return insert value = 1

上面的結果我們可以看到inset操作正常添加了,插入的也只有三個欄位,其他沒有填寫的欄位是不會新增,在看自動生成的id是一個Long型別的設定。這裡需要注意的是如果你想要一個主鍵自增的id那麼你需要進行id主鍵自增的設定

   @TableId(value = "id", type = IdType.AUTO)
    private Long id;

IdType.AUTO這個就是主鍵自增的標識,如果你在建立資料表的時候設定了主鍵自增在自動生成的時候註解就會自動新增的。在2.X的版本中還存在insertAllColumn現在的3.0版本已經不存在了就不做介紹了。

/**
     *<P>
     *     通過id更新資訊
     *</P>
     */
    @Test
    public void updateByIdLoads() {
        User user = new User();
        user.setAge(123);
        user.setEmail("[email protected]");
        user.setId(1L);

        Integer insert = mapper.updateById(user);
        System.out.println("return insert value = " + insert);
    }

sql執行和列印結果

==>  Preparing: UPDATE user SET age=?, email=? WHERE id=? 
==> Parameters: 123(Integer), [email protected](String), 1(Long)
<==    Updates: 1
return insert value = 1

這裡我就不多說了相信大家都懂

/**
     * <P>
     *     deleteBatchIds 根據id批量刪除
     * </P>
     */
    @Test
    public void deleteLoads() {
        List<Long> list = new ArrayList<>();
        list.add(1L);
        list.add(2L);
        list.add(3L);

        Integer insert = mapper.deleteBatchIds(list);
        System.out.println("return deleteBatchIds value = " + insert);
    }

sql執行和列印結果

==>  Preparing: DELETE FROM user WHERE id IN ( ? , ? , ? ) 
==> Parameters: 1(Long), 2(Long), 3(Long)
<==    Updates: 3
return deleteBatchIds value = 3

看上面的結果可以看出批量刪除的操作其實是id in返回結構是刪除成功的條數

  /**
     * <P>
     *     deleteById 根據id刪除
     * </P>
     */
    @Test
    public void deleteByIdLoads() {
        Integer deleteById = mapper.deleteById(4L);
        System.out.println("return deleteById value = " + deleteById);
    }

這個就是通過id刪除一條資料

/**
     * <p>
     * deleteByMap 根據map條件進行刪除
     * </P>
     */
    @Test
    public void deleteByMapsLoads() {
        HashMap<String, Object> map = new HashMap<>(16);
        map.put("email", "[email protected]");
        map.put("age", 12);

        Integer insert = mapper.deleteByMap(map);
        System.out.println("return deleteByMap value = " + insert);
    }

這個就是通過map條件進行刪除操作,條件查詢到多少條刪除多少,這裡需要注意的是,map中的key對應的是資料庫欄位例如資料庫user_id,實體類是userId這是在作為map key的時候需要填寫user_id。

sql執行和列印結果

==>  Preparing: DELETE FROM user WHERE email = ? AND age = ? 
==> Parameters: [email protected](String), 12(Integer)
<==    Updates: 6
return deleteByMap value = 6
 /**
     * <p>
     * 通過id查詢物件
     * </P>
     */
    @Test
    public void selectByIdLoads() {
        User user = mapper.selectById(4L);
        System.out.println("return insert value = " + user);
    }

這裡是通過id進行查詢返回單個實體物件

/**
     * <p>
     * 通過多個id進行查詢
     * </P>
     */
    @Test
    public void selectBatchIdsLoads() {
        List<Long> list = new ArrayList<>();
        list.add(1L);
        list.add(2L);
        list.add(3L);
        List<User> list1 = mapper.selectBatchIds(list);
        System.out.println("return selectBatchIds value = " + list1);
    }

通過多個id進行查詢返回list集合

/**
     * <p>
     * 通過條件進行實體list查詢
     * </P>
     */
    @Test
    public void selectByMapLoads() {
        HashMap<String, Object> map = new HashMap<>(16);
        map.put("email", "[email protected]");
        map.put("age", 12);
        List<User> list = mapper.selectByMap(map);
        System.out.println("return selectByMap value = " + list);
    }

通過多個條件進行實體list查詢

 /**
     * <p>
     * 分頁查詢
     * </P>
     */
    @Test
    public void selectPageLoads() {
        Page<User> page = new Page<>(1,5);
        IPage<User> lstUser = mapper.selectPage(page, null);
        System.out.println("return selectPageLoads value = " + lstUser);
    }

上面的查詢是分頁查詢,page中的1代表當前頁,5代表每頁條數。要想實現mybatis-plus分頁首先需要確定配置了分頁外掛配置方法如下,null代表的是條件構造器這個我在後面會講,

/**
     * 分頁外掛
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

在配置類或啟動類中增加上面的bean就可以使用了,如不不新增分頁不成功查詢所有內容

分頁後sql列印

==>  Preparing: SELECT COUNT(1) FROM user 
==> Parameters: 
<==    Columns: COUNT(1)
<==        Row: 11
==>  Preparing: SELECT id,name,age,email,status FROM user LIMIT 0,5 
==> Parameters: 
<==    Columns: id, name, age, email, status
<==        Row: 1046282328366391307, null, 12, [email protected], null
<==        Row: 1046282328366391308, null, 12, [email protected], null
<==        Row: 1046282328366391309, null, 12, [email protected], null
<==        Row: 1046282328366391310, null, 12, [email protected], null
<==        Row: 1046282328366391311, null, 12, [email protected], null
<==      Total: 5

上方的所有測試就是springboot + mybatis-plus自動生成後的所有簡單CRUD操作查詢。

我們來看一下mapper中的BaseMapper<>原始碼

/*
 * Copyright (c) 2011-2020, hubin ([email protected]).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.baomidou.mybatisplus.core.mapper;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Param;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;

/**
 * <p>
 * Mapper 繼承該介面後,無需編寫 mapper.xml 檔案,即可獲得CRUD功能
 * </p>
 * <p>
 * 這個 Mapper 支援 id 泛型
 * </p>
 *
 * @author hubin
 * @since 2016-01-23
 */
public interface BaseMapper<T> {

    /**
     * <p>
     * 插入一條記錄
     * </p>
     *
     * @param entity 實體物件
     */
    int insert(T entity);

    /**
     * <p>
     * 根據 ID 刪除
     * </p>
     *
     * @param id 主鍵ID
     */
    int deleteById(Serializable id);

    /**
     * <p>
     * 根據 columnMap 條件,刪除記錄
     * </p>
     *
     * @param columnMap 表字段 map 物件
     */
    int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * <p>
     * 根據 entity 條件,刪除記錄
     * </p>
     *
     * @param queryWrapper 實體物件封裝操作類(可以為 null)
     */
    int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 刪除(根據ID 批量刪除)
     * </p>
     *
     * @param idList 主鍵ID列表(不能為 null 以及 empty)
     */
    int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /**
     * <p>
     * 根據 ID 修改
     * </p>
     *
     * @param entity 實體物件
     */
    int updateById(@Param(Constants.ENTITY) T entity);

    /**
     * <p>
     * 根據 whereEntity 條件,更新記錄
     * </p>
     *
     * @param entity        實體物件 (set 條件值,不能為 null)
     * @param updateWrapper 實體物件封裝操作類(可以為 null,裡面的 entity 用於生成 where 語句)
     */
    int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

    /**
     * <p>
     * 根據 ID 查詢
     * </p>
     *
     * @param id 主鍵ID
     */
    T selectById(Serializable id);

    /**
     * <p>
     * 查詢(根據ID 批量查詢)
     * </p>
     *
     * @param idList 主鍵ID列表(不能為 null 以及 empty)
     */
    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /**
     * <p>
     * 查詢(根據 columnMap 條件)
     * </p>
     *
     * @param columnMap 表字段 map 物件
     */
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * <p>
     * 根據 entity 條件,查詢一條記錄
     * </p>
     *
     * @param queryWrapper 實體物件
     */
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 根據 Wrapper 條件,查詢總記錄數
     * </p>
     *
     * @param queryWrapper 實體物件
     */
    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 根據 entity 條件,查詢全部記錄
     * </p>
     *
     * @param queryWrapper 實體物件封裝操作類(可以為 null)
     */
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 根據 Wrapper 條件,查詢全部記錄
     * </p>
     *
     * @param queryWrapper 實體物件封裝操作類(可以為 null)
     */
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 根據 Wrapper 條件,查詢全部記錄
     * 注意: 只返回第一個欄位的值
     * </p>
     *
     * @param queryWrapper 實體物件封裝操作類(可以為 null)
     */
    List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 根據 entity 條件,查詢全部記錄(並翻頁)
     * </p>
     *
     * @param page         分頁查詢條件(可以為 RowBounds.DEFAULT)
     * @param queryWrapper 實體物件封裝操作類(可以為 null)
     */
    IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 根據 Wrapper 條件,查詢全部記錄(並翻頁)
     * </p>
     *
     * @param page         分頁查詢條件
     * @param queryWrapper 實體物件封裝操作類
     */
    IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}

通過看上面的baseMapper大家肯定會說你裡面有很多沒有說啊!是的,在這裡介紹的都是基本的CRUD沒有涉及到條件構造器的,我將在下篇為大家詳細的講解條件構造器,並將上面沒有說到的方法一併解決。