首頁>技術>

前言

官網:

https://baomidou.com/

建立資料庫

資料庫名為mybatis_plus

建立表

建立user表

DROP TABLE IF EXISTS user;CREATE TABLE user(id BIGINT(20) NOT NULL COMMENT '主鍵ID',name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',age INT(11) NULL DEFAULT NULL COMMENT '年齡',email VARCHAR(50) NULL DEFAULT NULL COMMENT '郵箱',PRIMARY KEY (id));INSERT INTO user (id, name, age, email) VALUES(1, 'Jone', 18, '[email protected]'),(2, 'Jack', 20, '[email protected]'),(3, 'Tom', 28, '[email protected]'),(4, 'Sandy', 21, '[email protected]'),(5, 'Billie', 24, '[email protected]');

注意:-- 真實開發中往往都會有這四個欄位,version(樂觀鎖)、deleted(邏輯刪除)、gmt_create(建立時間)、gmt_modified(修改時間)

初始化專案

使用SpringBoot器 初始化!

連線資料庫

建立application.yml

spring:  profiles:    active: dev  datasource:# 驅動不同 mysql 5  com.mysql.jdbc.Driver#         mysql 8  com.mysql.cj.jdbc.Driver、需要增加時區的配置serverTimezone=GMT%2B8    url: jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8    driver-class-name: com.mysql.cj.jdbc.Driver    username: root    password: root
業務程式碼

實體類

@Data@AllArgsConstructor@NoArgsConstructorpublic class User {  private Long id;  private String name;  private Integer age;  private String email;} 

mapper介面

import com.baomidou.mybatisplus.core.mapper.BaseMapper;import com.kuang.pojo.User;import org.springframework.stereotype.Repository;// 在對應的Mapper上面繼承基本的類 BaseMapper@Repository // 代表持久層public interface UserMapper extends BaseMapper<User> {  // 所有的CRUD操作都已經編寫完成了}

注意點,我們需要在主啟動類上去掃描我們的mapper包下的所有介面 @MapperScan(“com.kwhua.mapper”)

測試
@SpringBootTestclass MybatisPlusApplicationTests {  // 繼承了BaseMapper,所有的方法都來自己父類  // 我們也可以編寫自己的擴充套件方法!  @Autowired  private UserMapper userMapper;  @Test  void contextLoads() {    // 引數是一個 Wrapper ,條件構造器,這裡我們先設定條件為空,查詢所有。    List<User> users = userMapper.selectList(null);    users.forEach(System.out::println); }} 

所有資料輸出

配置日誌

我們所有的sql現在是不可見的,我們希望知道它是怎麼執行的,所有我們要配置日誌的輸出 application.yml檔案新增日誌配置

#配置日誌mybatis-plus:  configuration:    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

檢視執行sql的日誌資訊

三.Mybatis-plus的CRUD插入操作
// 測試插入    @Test    public void testInsert(){        User user = new User();        user.setName("kwhua_mybatis-plus_insertTest");        user.setAge(15);        user.setEmail("[email protected]");        int result = userMapper.insert(user); // 幫我們自動生成id        System.out.println(result); // 受影響的行數        System.out.println(user); // 看到id會自動填充。    }  

看到id會自動填充。資料庫插入的id的預設值為:全域性的唯一id

主鍵生成策略

1)主鍵自增

1、實體類欄位上 @TableId(type = IdType.AUTO)

2、資料庫id欄位設定為自增!

3、再次測試(可以看到id值比上次插入的大1)id的生成策略原始碼解釋

public enum IdType {  AUTO(0), // 資料庫id自增  NONE(1), // 未設定主鍵  INPUT(2), // 手動輸入  ID_WORKER(3), // 預設的方式,全域性唯一id  UUID(4), // 全域性唯一id uuid  ID_WORKER_STR(5); //ID_WORKER 字串表示法}

以上不再逐一測試。

更新操作
 @Test    public void testUpdate(){        User user = new User();        // 透過條件自動拼接動態sql        user.setId(1302223874217295874L);        user.setName("kwhua_mybatis-plus_updateTest");        user.setAge(20);        // 注意:updateById 但是引數是一個物件!        int i = userMapper.updateById(user);        System.out.println(i);    }
自動填充

建立時間、修改時間!這兩個欄位操作都是自動化完成的,我們不希望手動更新!阿里巴巴開發手冊:所有的資料庫表都要配置上gmt_create、gmt_modified!而且需要自動化!

方式一:資料庫級別(工作中一般不用)

1、在表中新增欄位 gmt_create, gmt_modified

2、把實體類同步

private Date gmtCreate;private Date gmtModified;

3、再次檢視

2、實體類欄位屬性上需要增加註解

    // 欄位新增填充內容    @TableField(fill = FieldFill.INSERT)    private Date gmt_create;    @TableField(fill = FieldFill.INSERT_UPDATE)    private Date gmt_modified;

3、編寫處理器來處理這個註解即可!

@Slf4j@Component // 一定不要忘記把處理器加到IOC容器中!public class MyMetaObjectHandler implements MetaObjectHandler {    // 插入時的填充策略    @Override    public void insertFill(MetaObject metaObject) {        log.info("start insert fill.....");        // setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject        this.setFieldValByName("gmt_create",new Date(),metaObject);        this.setFieldValByName("gmt_modified",new Date(),metaObject);    }    // 更新時的填充策略    @Override    public void updateFill(MetaObject metaObject) {        log.info("start update fill.....");        this.setFieldValByName("gmt_modified",new Date(),metaObject);    }}

4、測試插入和更新,檢查時間變化。

樂觀鎖

樂觀鎖 : 顧名思義,十分樂觀,它總是認為不會出現問題,無論幹什麼不去上鎖!如果出現了問題, 再次更新值測試 悲觀鎖:顧名思義,十分悲觀,它總是認為總是出現問題,無論幹什麼都會上鎖!再去操作!

樂觀鎖實現方式:

取出記錄時,獲取當前version 更新時,帶上這個version 執行更新時, set version = newVersion where version = oldVersion 如果version不對,就更新失敗

樂觀鎖:1、先查詢,獲得版本號 version = 1

-- Aupdate user set name = "kwhua", version = version + 1where id = 2 and version = 1-- B 執行緒搶先完成,這個時候 version = 2,會導致 A 修改失敗!update user set name = "kwhua", version = version + 1where id = 2 and version = 1

樂觀鎖測試

1、給資料庫中增加version欄位!

2、實體類加對應的欄位

    @Version //樂觀鎖Version註解    private Integer version;

3、註冊元件

// 掃描我們的 mapper 資料夾@MapperScan("com.kwhua.mapper")@EnableTransactionManagement@Configuration // 配置類public class MyBatisPlusConfig {    // 註冊樂觀鎖外掛    @Bean    public OptimisticLockerInterceptor optimisticLockerInterceptor() {        return new OptimisticLockerInterceptor();    }   }

4、測試

// 測試樂觀鎖成功!    @Test    public void testOptimisticLocker(){        // 1、查詢使用者資訊        User user = userMapper.selectById(1L);        // 2、修改使用者資訊        user.setName("kwhua");        user.setEmail("[email protected]");        // 3、執行更新操作        userMapper.updateById(user);    }

version欄位已經由1變成了2

// 測試樂觀鎖失敗!多執行緒下    @Test    public void testOptimisticLocker2(){        // 執行緒 1        User user = userMapper.selectById(1L);        user.setName("kwhua111");        user.setEmail("[email protected]");        // 模擬另外一個執行緒執行了插隊操作        User user2 = userMapper.selectById(1L);        user2.setName("kwhua222");        user2.setEmail("[email protected]");        userMapper.updateById(user2);        // 自旋鎖來多次嘗試提交!        userMapper.updateById(user); // 如果沒有樂觀鎖就會覆蓋插隊執行緒的值!    }

可以看到執行緒1執行更新失敗

查詢操作
// 測試查詢    @Test    public void testSelectById(){        User user = userMapper.selectById(1L);        System.out.println(user);    }    // 測試批次查詢!    @Test    public void testSelectByBatchId(){        List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));        users.forEach(System.out::println);    }    // 按條件查詢之一使用map操作    @Test    public void testSelectByBatchIds(){        HashMap<String, Object> map = new HashMap<>();        // 自定義要查詢        map.put("name","kwhua");        map.put("age",15);        List<User> users = userMapper.selectByMap(map);        users.forEach(System.out::println);    }

1、配置攔截器元件

// 分頁外掛@Beanpublic PaginationInterceptor paginationInterceptor() {  return  new PaginationInterceptor();}

2、直接使用Page物件即可!

// 測試分頁查詢@Testpublic void testPage(){  // 引數一:當前頁  // 引數二:頁面大小  Page<User> page = new Page<>(2,5);  userMapper.selectPage(page,null);  page.getRecords().forEach(System.out::println);  System.out.println(page.getTotal());}
物理刪除
// 測試刪除    @Test    public void testDeleteById(){        userMapper.deleteById(1L);    }    // 透過id批次刪除    @Test    public void testDeleteBatchId(){        userMapper.deleteBatchIds(Arrays.asList(2L,3L));    }    // 透過map刪除    @Test    public void testDeleteMap(){        HashMap<String, Object> map = new HashMap<>();        map.put("name","kwhua");        userMapper.deleteByMap(map);    }
邏輯刪除

物理刪除 :從資料庫中直接移除 邏輯刪除 :在資料庫中沒有被移除,而是透過一個變數來讓它失效!deleted = 0 => deleted = 1 管理員可以檢視被刪除的記錄!防止資料的丟失,類似於回收站!

1、在資料表中增加一個 deleted 欄位

2、實體類中增加屬性

// 邏輯刪除元件!    @Bean    public ISqlInjector sqlInjector() {        return new LogicSqlInjector();    }

配置檔案配置

 global-config:    db-config:      logic-delete-value: 1      logic-not-delete-value: 0

4、測試 測試刪除

欄位值也從0修改成了1測試查詢

效能分析外掛

作用:效能分析攔截器,用於輸出每條 SQL 語句及其執行時間 MP也提供效能分析外掛,如果超過這個時間就停止執行!

1、匯入外掛

   /**     * SQL執行效率外掛     */    @Bean    @Profile({"dev","test"})// 設定 dev test 環境開啟,保證我們的效率    public PerformanceInterceptor performanceInterceptor() {        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();        performanceInterceptor.setMaxTime(100); //ms 設定sql執行的最大時間,如果超過了則不執行        performanceInterceptor.setFormat(true);        return performanceInterceptor;    }
條件構造器(Wrapper)

isNotNull .gt

@Test    void contextLoads() {        // 查詢name不為空的使用者,並且郵箱不為空的使用者,年齡大於等於12        QueryWrapper<User> wrapper = new QueryWrapper<>();        wrapper                .isNotNull("name") //不為空                .isNotNull("email")                .ge("age",18);        userMapper.selectList(wrapper).forEach(System.out::println); // 和我們剛才學習的map對比一下    }

.eq

 @Test    void test2(){        // 查詢名字kwhua        QueryWrapper<User> wrapper = new QueryWrapper<>();        wrapper.eq("name","kwhua");        User user = userMapper.selectOne(wrapper); // 查詢一個數據用selectOne,查詢多個結果使用List 或者 Map        System.out.println(user);    }

其他方法可以自己測試...

程式碼自動生成器
// 程式碼自動生成器public class generateCode {   public static void main(String[] args) {    // 需要構建一個 程式碼自動生成器 物件    AutoGenerator mpg = new AutoGenerator();    // 配置策略    // 1、全域性配置    GlobalConfig gc = new GlobalConfig();    String projectPath = System.getProperty("user.dir");    gc.setOutputDir(projectPath+"/src/main/java");    gc.setAuthor("kwhua");//作者名稱    gc.setOpen(false);    gc.setFileOverride(false); // 是否覆蓋    gc.setIdType(IdType.ID_WORKER);    gc.setDateType(DateType.ONLY_DATE);    gc.setSwagger2(true);//實體屬性 Swagger2 註解    // 自定義檔案命名,注意 %s 會自動填充表實體屬性!    gc.setServiceName("%sService");     gc.setControllerName("%sController");    gc.setServiceName("%sService");    gc.setServiceImplName("%sServiceImpl");    gc.setMapperName("%sMapper");    gc.setXmlName("%sMapper");    mpg.setGlobalConfig(gc);    //2、設定資料來源    DataSourceConfig dsc = new DataSourceConfig();    dsc.setUrl("jdbc:mysql://localhost:3306/kwhua_test?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");    dsc.setDriverName("com.mysql.cj.jdbc.Driver");    // dsc.setDriverName("com.mysql.jdbc.Driver"); //mysql5.6以下的驅動    dsc.setUsername("root");    dsc.setPassword("root");    dsc.setDbType(DbType.MYSQL);    mpg.setDataSource(dsc);    //3、包的配置    PackageConfig pc = new PackageConfig();    pc.setParent("com.kwhua"); //包名    pc.setModuleName("model"); //模組名    pc.setEntity("entity");    pc.setMapper("mapper");    pc.setService("service");    pc.setController("controller");    mpg.setPackageInfo(pc);    //4、策略配置    StrategyConfig strategy = new StrategyConfig();    strategy.setInclude("user","course"); // 設定要對映的表名    strategy.setNaming(NamingStrategy.underline_to_camel);    strategy.setColumnNaming(NamingStrategy.underline_to_camel);    strategy.setEntityLombokModel(true); // 自動lombok;    strategy.setLogicDeleteFieldName("deleted");    // 自動填充配置    TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);    TableFill gmtModified = new TableFill("gmt_modified",FieldFill.INSERT_UPDATE);    ArrayList<TableFill> tableFills = new ArrayList<>();    tableFills.add(gmtCreate);    tableFills.add(gmtModified);    strategy.setTableFillList(tableFills);    // 樂觀鎖    strategy.setVersionFieldName("version");    //根據你的表名來建對應的類名,如果你的表名沒有下劃線,比如test,那麼你就可以取消這一步    strategy.setTablePrefix("t_");    strategy.setRestControllerStyle(true); //rest請求    //自動轉下劃線,比如localhost:8080/hello_id_2    strategy.setControllerMappingHyphenStyle(true);     mpg.setStrategy(strategy);    mpg.execute(); //執行 }}

執行主方法即可生成對應程式碼

11
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 阿里雲簡訊服務的使用-----獲取簡訊驗證碼