MyBatis-Plus入門,看這一篇就足夠了

来源:https://www.cnblogs.com/MessiXiaoMo3334/archive/2020/07/04/13237247.html
-Advertisement-
Play Games

文章設計源代碼和筆記:gitee 一、Mybatis-Plus 簡介 MyBatis-Plus(簡稱 MP)是一個 MyBatis 的增強工具,在 MyBatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生。 我們的願景是成為 MyBatis 最好的搭檔,就像 魂鬥羅 中的 1P、2P,基友 ...


文章設計源代碼和筆記:gitee

一、Mybatis-Plus

簡介

MyBatis-Plus(簡稱 MP)是一個 MyBatis 的增強工具,在 MyBatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生。

我們的願景是成為 MyBatis 最好的搭檔,就像 魂鬥羅 中的 1P、2P,基友搭配,效率翻倍。

特性

  • 無侵入:只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑
  • 損耗小:啟動即會自動註入基本 CURD,性能基本無損耗,直接面向對象操作
  • 強大的 CRUD 操作:內置通用 Mapper、通用 Service,僅僅通過少量配置即可實現單表大部分 CRUD 操作,更有強大的條件構造器,滿足各類使用需求
  • 支持 Lambda 形式調用:通過 Lambda 表達式,方便的編寫各類查詢條件,無需再擔心欄位寫錯
  • 支持主鍵自動生成:支持多達 4 種主鍵策略(內含分散式唯一 ID 生成器 - Sequence),可自由配置,完美解決主鍵問題
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式調用,實體類只需繼承 Model 類即可進行強大的 CRUD 操作
  • 支持自定義全局通用操作:支持全局通用方法註入( Write once, use anywhere )
  • 內置代碼生成器:採用代碼或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 層代碼,支持模板引擎,更有超多自定義配置等您來使用
  • 內置分頁插件:基於 MyBatis 物理分頁,開發者無需關心具體操作,配置好插件之後,寫分頁等同於普通 List 查詢
  • 分頁插件支持多種資料庫:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多種資料庫
  • 內置性能分析插件:可輸出 Sql 語句以及其執行時間,建議開發測試時啟用該功能,能快速揪出慢查詢
  • 內置全局攔截插件:提供全表 delete 、 update 操作智能分析阻斷,也可自定義攔截規則,預防誤操作

支持資料庫

  • mysql 、 mariadb 、 oracle 、 db2 、 h2 、 hsql 、 sqlite 、 postgresql 、 sqlserver 、 presto
  • 達夢資料庫 、 虛谷資料庫 、 人大金倉資料庫

框架結構

代碼托管

Gitee | Github

二、快速入門

地址:https://mp.baomidou.com/guide/quick-start.html#初始化工程

使用第三方組件

  1. 導入對應依賴
  2. 研究依賴配置
  3. 代碼如何編寫
  4. 提高擴展技術能力!

步驟

  1. 創建資料庫mybatis_plus
  2. 創建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)
);

DELETE FROM user;

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]');
  1. 編寫項目,初始化項目! 使用SpringBoot初始化!
  2. 導入依賴
<dependency>
    <groupId>org.springframework.boot</groupI
    <artifactId>spring-boot-starter-web</arti
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupI
    <artifactId>spring-boot-starter-test</art
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintage</group
            <artifactId>junit-vintage-engine<
        </exclusion>
    </exclusions>
</dependency>
<!--資料庫驅動-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifac
    <version>8.0.20</version>
</dependency>
<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
</dependency>
<!--mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</ar
    <version>3.3.1</version>
</dependency>

說明:我們使用mybatis-plus可以節省大量代碼,儘量不要同時導入mybatis和mybatis-plus!版本差異!

  1. 配置資料庫,和mybatis一樣
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?userSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.username=mybatis_plus
spring.datasource.password=mybatis_plus123
  1. 在 Spring Boot 啟動類中添加 @MapperScan 註解,掃描 Mapper 文件夾:
@MapperScan("com.godfrey.mapper")
@SpringBootApplication
public class MybatisPlusApplication {

    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusApplication.class, args);
    }

}
  1. 編碼

編寫實體類 User.java

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

編寫Mapper類 UserMapper.java

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

8.使用

添加測試類,進行功能測試:

@SpringBootTest
class MybatisPlusApplicationTests {

    @Resource
    private UserMapper userMapper;

    @Test
    void contextLoads() {
        //查詢全部用戶
        //參數是一個Wrapper,條件構造器
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }
}

控制台輸出:

User(id=1, name=Jone, age=18, [email protected])
User(id=2, name=Jack, age=20, [email protected])
User(id=3, name=Tom, age=28, [email protected])
User(id=4, name=Sandy, age=21, [email protected])
User(id=5, name=Billie, age=24, [email protected])

小結

通過以上幾個簡單的步驟,我們就實現了 User 表的 CRUD 功能,甚至連 XML 文件都不用編寫!

從以上步驟中,我們可以看到集成MyBatis-Plus非常的簡單,只需要引入 starter 工程,並配置 mapper 掃描路徑即可。

三、配置日誌

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

四、CRUD擴展

插入操作

//測試插入
@Test
public void testInsert(){
    User user = new User();
    user.setName("淮城一隻貓");
    user.setAge(5);
    user.setEmail("[email protected]");
    int result = userMapper.insert(user); //自動生成id
    System.out.println(result); //受影響的行數
    System.out.println(user); //發現id自動回填
}

資料庫插入的id預設是全局唯一id

主鍵生成策略

預設ID_WORKER,全局唯一id

分散式系統唯一id生成方案彙總

雪花演算法:

snowflake是Twitter開源的分散式ID生成演算法,結果是一個long型的ID。其核心思想是:使用41bit作為毫秒數,10bit作為機器的ID(5個bit是數據中心,5個bit的機器ID),12bit作為毫秒內的流水號(意味著每個節點在每毫秒可以產生 4096 個 ID),最後還有一個符號位,永遠是0。可以保證幾乎全球唯一!

主鍵自增

我們需要配置註解自增:

  1. 實體類欄位上:@TableId(type = IdType.AUTUO)
  2. 資料庫欄位一定要自增

3.再次測試插入即可!

其餘的策略解釋

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();
    user.setId(6L);
    user.setName("我的博客叫:淮城一隻貓");
    user.setAge(6);
    user.setEmail("[email protected]");
    //註意:updateById參數是一個對象
    int result = userMapper.updateById(user); //自動生成id
    System.out.println(result); //受影響的行數
}

自動填充

創建時間、修改時間!這些操作一般自動化完成的,我們不希望手動更新!

阿裡巴巴開發手冊:所有的資料庫表:gmt_create、gmt_modified幾乎所有表都要配置上!而且需要自動化!

方式一:資料庫級別(工作中不建議這麼做)

  1. 在表中新增欄位create_time、update_time

  1. 再次測試插入方法,需要先把實體類同步!
private Date creteTime;
private Date updateTime;

方式二:代碼級別

  1. 輸出資料庫中的預設值、更新操作

  1. 在實體類欄位屬性上需要註釋
//欄位添加填充內容
@TableField(fill = FieldFill.INSERT)
private Date creteTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
  1. 編寫處理器處理註解!
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler{
    //插入時填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }

    //更新時填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}
  1. 測試插入
  2. 測試更新、觀察時間即可!

樂觀鎖

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

悲觀鎖:顧名思義悲觀,它總是認為會出現問題,無論乾什麼都會加上鎖!再去操作

樂觀鎖實現方式:

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

測試MP樂觀鎖插件

  1. 資料庫中添加version欄位!

  1. 實體類添加對應欄位
@Version  //樂觀鎖註解
private Integer version;
  1. 註冊組件
@MapperScan("com.godfrey.mapper")
@EnableTransactionManagement  //自動管理事務(預設也是開啟的)
@Configuration  //配置類
public class MybaitsPlusConfig {

    //註冊樂觀鎖插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}
  1. 測試一下
//測試樂觀鎖成功!
@Test
public void testOptimisticLocker1() {
    //1.查詢用戶信息
    User user = userMapper.selectById(1L);
    //2.修改用戶信息
    user.setName("godfrey");
    user.setEmail("[email protected]");
    //3.執行更新操作
    userMapper.updateById(user);
}


//測試樂觀鎖失敗!多線程下
@Test
public void testOptimisticLocker2() {
    //線程1
    User user1 = userMapper.selectById(1L);
    user1.setName("godfrey111");
    user1.setEmail("[email protected]");

    //模擬另外一個線程執行插隊操作
    User user2 = userMapper.selectById(1L);
    user2.setName("godfrey222");
    user2.setEmail("[email protected]");
    userMapper.updateById(user2);

    //自旋鎖多次操作嘗試提交
    userMapper.updateById(user1);
}

查詢操作

//測試查詢
@Test
public void testSelectById() {
    User user = userMapper.selectById(1L);
    System.out.println(user);
}

//測試批量查詢
@Test
public void testSelectByBatchId() {
    List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L));
    users.forEach(System.out::println);
}

//條件查詢之一 使用map操作
@Test
public void testSelectBatchIds() {
    HashMap<String, Object> map = new HashMap<>();
    //自定義查詢
    map.put("name","Tom");
    map.put("age",28);

    List<User> users = userMapper.selectByMap(map);
    users.forEach(System.out::println);
}

分頁查詢

分頁在網站中使用非常多!

  1. 原始limit進行分頁
  2. pageHelper第三方插件
  3. MP其實也內置了分頁插件

如何使用?

  1. 配置分頁插件
//分頁插件
@Bean
public PaginationInterceptor paginationInterceptor() {
    return new PaginationInterceptor();
}
  1. 直接使用Page對象即可!
//測試分頁查詢
@Test
public void testPage() {
    //參數一:當前頁
    //參數二:頁面大小
    //使用了分頁插件之後,所有的分頁操作頁變得簡單了
    Page<User> page = new Page<>(1,5);
    userMapper.selectPage(page,null);

    page.getRecords().forEach(System.out::println);
    System.out.println(page.getTotal());
}

刪除操作

基本的刪除操作

//通過id刪除
@Test
public void testDeleteById() {
    userMapper.deleteById(8L);
}

//通過id批量刪除
@Test
public void testDeleteBatchId() {
    userMapper.deleteBatchIds(Arrays.asList(6L, 7L));
}

//通過map刪除
@Test
public void testDeleteMap() {
    HashMap<String, Object> map = new HashMap<>();
    map.put("name", "godfrey");
    userMapper.deleteByMap(map);
}

我們在工作中會遇到一些問題:邏輯刪除!

邏輯刪除

物理刪除:從資料庫中直接移除

邏輯刪除:在資料庫中沒有被移除,而是通過一個變數來讓他失效!delete=0 => delete=1

管理員可以查看被刪除的記錄!防止數據的丟失,類似於回收站!

測試一下:

  1. 在數據表中增加deleted欄位

  1. 實體類中同步屬性
//邏輯刪除欄位
private Integer deleted;
  1. 配置
# 配置邏輯刪除
mybatis-plus.global-config.db-config.logic-delete-field=deleted # 全局邏輯刪除的實體欄位名
mybatis-plus.global-config.db-config.logic-delete-value=1 # 邏輯已刪除值(預設為 1)
mybatis-plus.global-config.db-config.logic-not-delete-value=0 # 邏輯未刪除值(預設為 0)
  1. 測試一下刪除

以上的所有CRUD操作及其擴展操作,我們都必須精通掌握!會大大提高工作和寫項目效率

性能分析插件

我們在開發中,會遇到一些慢sql,我們有必要把它揪出來 。測試!druid...

MP也提供性能分析插件,如果超過這個時間就停止運行!官方3.1.0以上版本推薦使用p6spy!

  1. 導入依賴
<!--p6spy性能分析插件-->
<dependency>
    <groupId>p6spy</groupId>
    <artifactId>p6spy</artifactId>
    <version>3.9.0</version>
</dependency>
  1. 修改資料庫連接配置
# 資料庫連接配置
spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
spring.datasource.url=jdbc:p6spy:mysql://localhost:3306/mybatis_plus?userSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
  1. 新建spy.properties 並設置參數
#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定義日誌列印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日誌輸出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日誌系統記錄 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 設置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL首碼
useprefix=true
# 配置記錄 Log 例外,可去掉的結果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式gui
dateformat=yyyy-MM-dd HH:mm:ss
# 實際驅動可多個
#driverlist=org.h2.Driver
# 是否開啟慢SQL記錄
outagedetection=true
# 慢SQL記錄標準 2 秒
outagedetectioninterval=2
  1. 測試使用!(只要超過了規定時間就會拋出異常)

註意,插件會影響性能,建議開發和測試環境下使用

條件構造器

  1. 測試一
@Test
void test1() {
    //查詢name不為空的用戶,並且郵箱不為空的,年齡大於等於12
    QueryWrapper<User> wapper = new QueryWrapper<>();
    wapper.isNotNull("name")
            .isNotNull("email")
            .ge("age", 12);
    userMapper.selectList(wapper).forEach(System.out::println);
}
  1. 測試二
@Test
void test2() {
    //查詢名字為Tom
    QueryWrapper<User> wapper = new QueryWrapper<>();
    wapper.eq("name","Tom");
    User user = userMapper.selectOne(wapper);
    System.out.println(user);
}
  1. 測試三
//範圍查詢
@Test
void test3() {
    //查詢年齡在20~30歲之間的用戶
    QueryWrapper<User> wapper = new QueryWrapper<>();
    wapper.between("age", 20, 30);//區間
    System.out.println(userMapper.selectCount(wapper));//查詢結果數
}
  1. 測試四
//模糊查詢
@Test
void test4() {
    //查詢名字有
    QueryWrapper<User> wapper = new QueryWrapper<>();
    wapper.notLike("name","e")//%e%
            .likeRight("email","t");//t%
    List<Map<String, Object>> maps = userMapper.selectMaps(wapper);
    maps.forEach(System.out::println);
}
  1. 測試五
//子查詢
@Test
void test5() {
    QueryWrapper<User> wapper = new QueryWrapper<>();
    //id在子查詢中查出來
    wapper.inSql("id","select id from user where id<3");
    List<Object> objects = userMapper.selectObjs(wapper);
    objects.forEach(System.out::println);
}
  1. 測試六
//排序
@Test
void test6() {
    QueryWrapper<User> wapper = new QueryWrapper<>();
    //通過id進行排序
    wapper.orderByDesc("id");
    userMapper.selectList(wapper).forEach(System.out::println);
}

代碼生成器

mapper、pojo、service、controller都給我自己去編寫完成!

AutoGenerator 是 MyBatis-Plus 的代碼生成器,通過 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各個模塊的代碼,極大的提升了開發效率。

1.EasyCode介紹


1.1 EasyCode是一個什麼東西?


EasyCode是基於IntelliJ IDEA Ultimate版開發的一個代碼生成插件,主要通過自定義模板(基於velocity)來生成各種你想要的代碼。通常用於生成Entity、Dao、Service、Controller。如果你動手能力強還可以用於生成HTML、JS、PHP等代碼。理論上來說只要是與數據有關的代碼都是可以生成的。


1.2 原理

基於Mybatis底層強大的逆向工程能力和良好的項目架構


1.3 使用環境

IntelliJ IDEA Ultimate版


1.4 支持的資料庫類型

因為是基於Database Tool開發,所有Database Tool支持的資料庫都是支持的。

包括如下資料庫:

  1. MySQL
  2. SQL Server
  3. Oracle
  4. PostgreSQL
  5. Sqlite
  6. Sybase
  7. Derby
  8. DB2
  9. HSQLDB
  10. H2

當然支持的資料庫類型也會隨著Database Tool插件的更新同步更新。


1.5 功能說明:

  • 支持多表同時操作
  • 支持同時生成多個模板
  • 支持自定義模板
  • 支持自定義類型映射(支持正則)
  • 支持自定義附加列
  • 支持列附加屬性
  • 所有配置項目支持分組模式,在不同項目(或選擇不同資料庫時),只需要切換對應的分組,所有配置統一變化

1.6 功能對比:

功能 Easy Code 其他工具
自定義模板 支持 支持
多表生成 支持 支持
生成方式 無縫集成在項目中 部分工具需要複製粘貼
附加列 支持 不支持
附加列屬性 支持 不支持
動態調試模板 支持 不支持
圖形化界面 支持 部分支持
使用環境 僅限IDEA 支持各種形式
線上支持 後期擴展 不支持
自定義類型映射 支持 部分支持
全局變數 支持 不支持

2.EasyCode使用


2.1 下載Easy Code插件


2.2 創建一個SpringBoot項目

2.3 配置數據源

使用Easy Code一定要使用IDEA自帶的資料庫工具來配置數據源

.


打開側邊的Database,查看效果

,


提前準備的數據表

,


2.4 自定義生成模板


第一次安裝EasyCode的時候預設的模板(服務於MyBatis)可以生成下麵類型的代碼

  1. entity.java
  2. dao.java
  3. service.java
  4. serviceImpl.java
  5. controller.java
  6. mapper.xml
  7. debug.json

2.5 以user表為例,根據你定義的模板生成代碼,文章的最後貼出我使用的自定義的模板

,


選擇模板

,


點擊OK之後,就可以看到生成了這些代碼

,


2.6 代碼展示

實體類層:User.java
package com.godfrey.easycode.entity;

import java.io.Serializable;

/**
 * (User)實體類
 *
 * @author godfrey
 * @since 2020-04-20 19:21:17
 */
public class User implements Serializable {
    private static final long serialVersionUID = 502672392114472688L;
    /**
     * 主鍵ID
     */
    private Integer id;
    /**
     * 姓名
     */
    private String name;
    /**
     * 年齡
     */
    private Integer age;
    /**
     * 郵箱
     */
    private String email;

        
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
        
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
        
    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
        
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                "name=" + name +
                "age=" + age +
                "email=" + email +
                '}';
    }
}

Dao資料庫訪問層:UserDao.java
package com.godfrey.easycode.dao;

import com.godfrey.easycode.entity.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * description : (User)表資料庫訪問層
 *
 * @author godfrey
 * @since  2020-04-20 19:21:17
 */
@Mapper
public interface UserDao {

    /**
     * description : 添加User
     *
     * @param user 實例對象
     * @return 影響行數
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    int insert(User user);

    /**
     * description : 刪除User
     *
     * @param  id 主鍵
     * @return 影響行數
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    int deleteById(Integer id);

    /**
     * description : 通過ID查詢單條數據
     *
     * @param  id 主鍵
     * @return 實例對象
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    User queryById(Integer id);

    /**
     * description : 查詢全部數據(分頁使用MyBatis的插件實現)
     *
     * @return 對象列表
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    List<User> queryAll();

    /**
     * description : 實體作為篩選條件查詢數據
     *
     * @param  user 實例對象
     * @return 對象列表
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    List<User> queryAll(User user);

    /**
     * description : 修改User
     *
     * @param  user 根據user的主鍵修改數據
     * @return 影響行數
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    int update(User user);
}

Service服務介面層:UserService.java
package com.godfrey.easycode.service;

import com.godfrey.easycode.entity.User;
import java.util.List;

/**
 * description : (User)表服務介面
 *
 * @author godfrey
 * @since  2020-04-20 19:21:17
 */
public interface UserService {

    /**
     * description : 添加User
     *
     * @param  user 實例對象
     * @return 是否成功
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    boolean insert(User user);

    /**
     * description : 刪除User
     *
     * @param  id 主鍵
     * @return 是否成功
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    boolean deleteById(Integer id);

    /**
     * description : 查詢單條數據
     * @param  id 主鍵
     * @return 實例對象
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    User queryById(Integer id);

    /**
     * description : 查詢全部數據(分頁使用MyBatis的插件實現)
     *
     * @return 對象列表
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    List<User> queryAll();

    /**
     * description : 實體作為篩選條件查詢數據
     *
     * @param  user 實例對象
     * @return 對象列表
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    List<User> queryAll(User user);

    /**
     * description : 修改數據,哪個屬性不為空就修改哪個屬性
     *
     * @param  user 實例對象
     * @return 是否成功
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    boolean update(User user);
}

ServiceImpl服務介面實現層:UserServiceImpl.java
package com.godfrey.easycode.service.impl;

import com.godfrey.easycode.entity.User;
import com.godfrey.easycode.dao.UserDao;
import com.godfrey.easycode.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

 /**
  * description : (User)表服務實現類
  *
  * @author godfrey
  * @since  2020-04-20 19:21:17
  **/
@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    protected UserDao userDao;

    /**
     * description : 添加User
     *
     * @param  user 實例對象
     * @return 是否成功
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    @Override
    public boolean insert(User user) {
        return userDao.insert(user) == 1;
    }

    /**
     * description : 刪除User
     *
     * @param  id 主鍵
     * @return 是否成功
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    @Override
    public boolean deleteById(Integer id) {
        return userDao.deleteById(id) == 1;
    }

    /**
     * description : 查詢單條數據
     *
     * @param  id 主鍵
     * @return 實例對象
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    @Override
    public User queryById(Integer id) {
        return userDao.queryById(id);
    }

    /**
     * description : 查詢全部數據(分頁使用MyBatis的插件實現)
     *
     * @return 對象列表
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    @Override
    public List<User> queryAll() {
        return userDao.queryAll();
    }

    /**
     * description : 實體作為篩選條件查詢數據
     *
     * @param user 實例對象
     * @return 對象列表
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    @Override
    public List<User> queryAll(User user) {
        return userDao.queryAll(user);
    }

    /**
     * description : 修改數據,哪個屬性不為空就修改哪個屬性
     *
     * @param user 實例對象
     * @return 是否成功
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    @Override
    public boolean update(User user) {
        return userDao.update(user) == 1;
    }
}

前端控制器:UserController.java
package com.godfrey.easycode.controller;

import com.godfrey.easycode.entity.User;
import com.godfrey.easycode.service.UserService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * description : (User)表控制層
 *
 * @author godfrey
 * @since  2020-04-20 19:21:17
 */
@RestController
@RequestMapping("user")
public class UserController {
    /**
     * 服務對象
     */
    @Resource
    private UserService userService;

    /**
     * description : 通過主鍵查詢單條數據
     *
     * @param  id 主鍵
     * @return 單條數據
     * @author godfrey
     * @since  2020-04-20 19:21:17
     */
    @GetMapping("selectOne")
    public User selectOne(Integer id) {
        return this.userService.queryById(id);
    }
}

Mapper映射文件:UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.godfrey.easycode.dao.UserDao">

    <!--user的映射結果集-->
    <resultMap type="com.godfrey.easycode.entity.User" id="UserMap">
        <result property="id" column="id" jdbcType="INTEGER"/>
        <result property="name" column="name" jdbcType="VARCHAR"/>
        <result property="age" column="age" jdbcType="INTEGER"/>
        <result property="email" column="email" jdbcType="VARCHAR"/>
    </resultMap>

    <!--全部欄位-->
    <sql id="allColumn"> id, name, age, email </sql>

    <!--添加語句的欄位列表-->
    <sql id="insertColumn">
        <if test="name != null and name != ''">
            name,
        </if>
        <if test="age != null">
            age,
        </if>
        <if test="email != null and email != ''">
            email,
        </if>
    </sql>

    <!--添加語句的值列表-->
    <sql id="insertValue">
        <if test="name != null and name != ''">
            #{name},
        </if>
        <if test="age != null">
            #{age},
        </if>
        <if test="email != null and email != ''">
            #{email},
        </if>
    </sql>

    <!--通用對User各個屬性的值的非空判斷-->
    <sql id="commonsValue">
        <if test="name != null and name != ''">
            name = #{name},
        </if>
        <if test="age != null">
            age = #{age},
        </if>
        <if test="email != null and email != ''">
            email = #{email},
        </if>
    </sql>

    <!--新增user:哪個欄位不為空就添加哪列數據,返回自增主鍵-->
    <insert id="insert" keyProperty="id" useGeneratedKeys="true">
        insert into user
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <include refid="insertColumn"/>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <include refid="insertValue"/>
        </trim>
    </insert>

    <!--刪除user:通過主鍵-->
    <delete id="deleteById">
        delete from user
        <where>
            id = #{id}
        </where>
    </delete>

    <!--查詢單個user-->
    <select id="queryById" resultMap="UserMap">
        select
        <include refid="allColumn"></include>
        from user
        <where>
            id = #{id}
        </where>
    </select>

    <!--通過實體作為篩選條件查詢-->
    <select id="queryAll" resultMap="UserMap">
        select
        <include refid="allColumn"></include>
        from user
        <trim prefix="where" prefixOverrides="and" suffixOverrides=",">
            <include refid="commonsValue"></include>
        </trim>
    </select>

    <!--通過主鍵修改數據-->
    <update id="update">
        update user
        <set>
            <include refid="commonsValue"></include>
        </set>
        <where>
            id = #{id}
        </where>
    </update>
</mapper>

以上代碼完全是生成出來了,從頭到尾只需要點幾下滑鼠,是不是很神奇!


3.我的預設定製模板


entity.java

##引入巨集定義
$!define

##使用巨集定義設置回調(保存位置與文件尾碼)
#save("/entity", ".java")

##使用巨集定義設置包尾碼
#setPackageSuffix("entity")

##使用全局變數實現預設包導入
$!autoImport
import java.io.Serializable;

##使用巨集定義實現類註釋信息
#tableComment("實體類")
public class $!{tableInfo.name} implements Serializable {
    private static final long serialVersionUID = $!tool.serial();
#foreach($column in $tableInfo.fullColumn)
    #if(${column.comment})/**
     * ${column.comment}
     */#end

    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end

#foreach($column in $tableInfo.fullColumn)
    ##使用巨集定義實現get,set方法
    #getSetMethod($column)
#end

    @Override
    public String toString() {
        return "$!{tableInfo.name}{" +
    #foreach($column in $tableInfo.fullColumn)
            "$!{column.name}=" + $!{column.name} +
    #end
            '}';
    }
}

dao.java

##定義初始變數
#set($tableName = $tool.append($tableInfo.name, "Dao"))
##設置回調
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/dao"))

##拿到主鍵
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}dao;

import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * description : $!{tableInfo.comment}($!{tableInfo.name})表資料庫訪問層
 *
 * @author $!author
 * @since  $!time.currTime()
 */
@Mapper
public interface $!{tableName} {

    /**
     * description : 添加$!{tableInfo.name}
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 實例對象
     * @return 影響行數
     * @author $!author
     * @since  $!time.currTime()
     */
    int insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * description : 刪除$!{tableInfo.name}
     *
     * @param  $!pk.name 主鍵
     * @return 影響行數
     * @author $!author
     * @since  $!time.currTime()
     */
    int deleteById($!pk.shortType $!pk.name);

    /**
     * description : 通過ID查詢單條數據
     *
     * @param  $!pk.name 主鍵
     * @return 實例對象
     * @author $!author
     * @since  $!time.currTime()
     */
    $!{tableInfo.name} queryById($!pk.shortType $!pk.name);

    /**
     * description : 查詢全部數據(分頁使用MyBatis的插件實現)
     *
     * @return 對象列表
     * @author $!author
     * @since  $!time.currTime()
     */
    List<$!{tableInfo.name}> queryAll();

    /**
     * description : 實體作為篩選條件查詢數據
     *
     * @param  $!tool.firstLowerCase($!{tableInfo.name}) 實例對象
     * @return 對象列表
     * @author $!author
     * @since  $!time.currTime()
     */
    List<$!{tableInfo.name}> queryAll($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * description : 修改$!{tableInfo.name}
     *
     * @param  user 根據$!tool.firstLowerCase($!{tableInfo.name})的主鍵修改數據
     * @return 影響行數
     * @author $!author
     * @since  $!time.currTime()
     */
    int update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
}

service.java

##定義初始變數
#set($tableName = $tool.append($tableInfo.name, "Service"))
##設置回調
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service"))

##拿到主鍵
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service;

import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import java.util.List;

/**
 * description : $!{tableInfo.comment}($!{tableInfo.name})表服務介面
 *
 * @author $!author
 * @since  $!time.currTime()
 */
public interface $!{tableName} {

    /**
     * description : 添加$!{tableInfo.name}
     *
     * @param  $!tool.firstLowerCase($!{tableInfo.name}) 實例對象
     * @return 是否成功
     * @author $!author
     * @since  $!time.currTime()
     */
    boolean insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * description : 刪除$!{tableInfo.name}
     *
     * @param  $!pk.name 主鍵
     * @return 是否成功
     * @author $!author
     * @since  $!time.currTime()
     */
    boolean deleteById($!pk.shortType $!pk.name);

    /**
     * description : 查詢單條數據
     * @param  $!pk.name 主鍵
     * @return 實例對象
     * @author $!author
     * @since  $!time.currTime()
     */
    $!{tableInfo.name} queryById($!pk.shortType $!pk.name);

    /**
     * description : 查詢全部數據(分頁使用MyBatis的插件實現)
     *
     * @return 對象列表
     * @author $!author
     * @since  $!time.currTime()
     */
    List<$!{tableInfo.name}> queryAll();

    /**
     * description : 實體作為篩選條件查詢數據
     *
     * @param  $!tool.firstLowerCase($!{tableInfo.name}) 實例對象
     * @return 對象列表
     * @author $!author
     * @since  $!time.currTime()
     */
    List<$!{tableInfo.name}> queryAll($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * description : 修改數據,哪個屬性不為空就修改哪個屬性
     *
     * @param  $!tool.firstLowerCase($!{tableInfo.name}) 實例對象
     * @return 是否成功
     * @author $!author
     * @since  $!time.currTime()
     */
    boolean update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
}

serviceImpl.java

##定義初始變數
#set($tableName = $tool.append($tableInfo.name, "ServiceImpl"))
##設置回調
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service/impl"))

##拿到主鍵
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service.impl;

import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.dao.$!{tableInfo.name}Dao;
import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

 /**
  * description : $!{tableInfo.comment}($!{tableInfo.name})表服務實現類
  *
  * @author $!author
  * @since  $!time.currTime()
  **/
@Service("$!tool.firstLowerCase($!{tableInfo.name})Service")
public class $!{tableName} implements $!{tableInfo.name}Service {

    @Autowired
    protected $!{tableInfo.name}Dao $!tool.firstLowerCase($!{tableInfo.name})Dao;

    /**
     * description : 添加$!{tableInfo.name}
     *
     * @param  $!tool.firstLowerCase($!{tableInfo.name}) 實例對象
     * @return 是否成功
     * @author $!author
     * @since  $!time.currTime()
     */
    @Override
    public boolean insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
        return $!{tool.firstLowerCase($!{tableInfo.name})}Dao.insert($!tool.firstLowerCase($!{tableInfo.name})) == 1;
    }

    /**
     * description : 刪除$!{tableInfo.name}
     *
     * @param  $!pk.name 主鍵
     * @return 是否成功
     * @author $!author
     * @since  $!time.currTime()
     */
    @Override
    public boolean deleteById($!pk.shortType $!pk.name) {
        return $!{tool.firstLowerCase($!{tableInfo.name})}Dao.deleteById($!pk.name) == 1;
    }

    /**
     * description : 查詢單條數據
     *
     * @param  $!pk.name 主鍵
     * @return 實例對象
     * @author $!author
     * @since  $!time.currTime()
     */
    @Override
    public $!{tableInfo.name} queryById($!pk.shortType $!pk.name) {
        return $!{tool.firstLowerCase($!{tableInfo.name})}Dao.queryById($!pk.name);
    }

    /**
     * description : 查詢全部數據(分頁使用MyBatis的插件實現)
     *
     * @return 對象列表
     * @author $!author
     * @since  $!time.currTime()
     */
    @Override
    public List<$!{tableInfo.name}> queryAll() {
        return $!{tool.firstLowerCase($!{tableInfo.name})}Dao.queryAll();
    }

    /**
     * description : 實體作為篩選條件查詢數據
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 實例對象
     * @return 對象列表
     * @author $!author
     * @since  $!time.currTime()
     */
    @Override
    public List<$!{tableInfo.name}> queryAll($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
        return $!{tool.firstLowerCase($!{tableInfo.name})}Dao.queryAll($!tool.firstLowerCase($!{tableInfo.name}));
    }

    /**
     * description : 修改數據,哪個屬性不為空就修改哪個屬性
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 實例對象
     * @return 是否成功
     * @author $!author
     * @since  $!time.currTime()
     */
    @Override
    public boolean update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
        return $!{tool.firstLowerCase($!{tableInfo.name})}Dao.update($!tool.firstLowerCase($!{tableInfo.name})) == 1;
    }
}

controller.java

##定義初始變數
#set($tableName = $tool.append($tableInfo.name, "Controller"))
##設置回調
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/controller"))
##拿到主鍵
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}controller;

import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * description : $!{tableInfo.comment}($!{tableInfo.name})表控制層
 *
 * @author $!author
 * @since  $!time.currTime()
 */
@RestController
@RequestMapping("$!tool.firstLowerCase($tableInfo.name)")
public class $!{tableName} {
    /**
     * 服務對象
     */
    @Resource
    private $!{tableInfo.name}Service $!tool.firstLowerCase($tableInfo.name)Service;

    /**
     * description : 通過主鍵查詢單條數據
     *
     * @param  id 主鍵
     * @return 單條數據
     * @author $!author
     * @since  $!time.currTime()
     */
    @GetMapping("selectOne")
    public $!{tableInfo.name} selectOne($!pk.shortType id) {
        return this.$!{tool.firstLowerCase($tableInfo.name)}Service.queryById(id);
    }
}

mapper.xml

##引入mybatis支持
$!mybatisSupport

##設置保存名稱與保存位置
$!callback.setFileName($tool.append($!{tableInfo.name}, "Dao.xml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources/mybatis/mapper"))

##拿到主鍵
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="$!{tableInfo.savePackageName}.dao.$!{tableInfo.name}Dao">

    <!--$!{tableInfo.obj.name}的映射結果集-->
    <resultMap type="$!{tableInfo.savePackageName}.entity.$!{tableInfo.name}" id="$!{tableInfo.name}Map">
#foreach($column in $tableInfo.fullColumn)
        <result property="$!column.name" column="$!column.obj.name" jdbcType="$!column.ext.jdbcType"/>
#end
    </resultMap>

    <!--全部欄位-->
    <sql id="allColumn"> #allSqlColumn() </sql>

    <!--添加語句的欄位列表-->
    <sql id="insertColumn">
#foreach($column in $tableInfo.otherColumn)
        <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
            $!column.obj.name,
        </if>
#end
    </sql>

    <!--添加語句的值列表-->
    <sql id="insertValue">
#foreach($column in $tableInfo.otherColumn)
        <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
            #{$!column.name},
        </if>
#end
    </sql>

    <!--通用對$!{tableInfo.name}各個屬性的值的非空判斷-->
    <sql id="commonsValue">
#foreach($column in $tableInfo.otherColumn)
        <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
            $!column.obj.name = #{$!column.name},
        </if>
#end
    </sql>

    <!--新增$!{tableInfo.obj.name}:哪個欄位不為空就添加哪列數據,返回自增主鍵-->
    <insert id="insert" keyProperty="$!pk.name" useGeneratedKeys="true">
        insert into $!{tableInfo.obj.name}
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <include refid="insertColumn"/>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <include refid="insertValue"/>
        </trim>
    </insert>

    <!--刪除$!{tableInfo.obj.name}:通過主鍵-->
    <delete id="deleteById">
        delete from $!{tableInfo.obj.name}
        <where>
            $!pk.obj.name = #{$!pk.name}
        </where>
    </delete>

    <!--查詢單個$!{tableInfo.obj.name}-->
    <select id="queryById" resultMap="$!{tableInfo.name}Map">
        select
        <include refid="allColumn"></include>
        from $!tableInfo.obj.name
        <where>
            $!pk.obj.name = #{$!pk.name}
        </where>
    </select>

    <!--通過實體作為篩選條件查詢-->
    <select id="queryAll" resultMap="$!{tableInfo.name}Map">
        select
        <include refid="allColumn"></include>
        from $!tableInfo.obj.name
        <trim prefix="where" prefixOverrides="and" suffixOverrides=",">
            <include refid="commonsValue"></include>
        </trim>
    </select>

    <!--通過主鍵修改數據-->
    <update id="update">
        update $!{tableInfo.obj.name}
        <set>
            <include refid="commonsValue"></include>
        </set>
        <where>
            $!pk.obj.name = #{$!pk.name}
        </where>
    </update>
</mapper>

新創建一個分組Lombok,可以在生成實體類的時候使用Lombok註解

,

實體類層:entity.java

##引入巨集定義
$!define

##使用巨集定義設置回調(保存位置與文件尾碼)
#save("/entity", ".java")

##使用巨集定義設置包尾碼
#setPackageSuffix("entity")

##使用全局變數實現預設包導入
$!autoImport
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

##使用巨集定義實現類註釋信息
#tableComment("實體類")
@AllArgsConstructor
@Data
@Builder
public class $!{tableInfo.name} implements Serializable {
    private static final long serialVersionUID = $!tool.serial();
#foreach($column in $tableInfo.fullColumn)
    #if(${column.comment})/**
    * ${column.comment}
    */#end

    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end
}

多個分組的切換

選擇好分組後,點擊OK,之後在Datebase視圖的數據表右鍵選擇EasyCode生成的時候會讓你選擇當前分組的模板

,

,

,

.


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文章通過簡單的css和html的操作,來實現Tom貓小游戲的功能,通過簡單的js代碼,讓圖片不斷切換來實現動畫效果。 Tom貓小游戲的HTML部分: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name= ...
  • 前置 本篇隨筆包含 _.compact 和 _.concat 及其依賴的工具函數。 你可能需要一些 JavaScript 基礎知識才能看懂一些沒有註釋的細節。 compact _.compact(array) 創建一個新數組,包含原數組中所有的非假值元素。例如 false, null, 0, "", ...
  • 如果你是想要學習web前端的新人,那麼恭喜你,看完這篇文章,儘早的選擇好努力的方向和規劃好自己的學習路線,比別人多一點付出並且持之以恆,你就已經贏在了起跑線上。 因為工作原因,經常關註有關互聯網行業的最新動態。這不,剛送走了高考,又迎來了每年的畢業季,看到好多人都說今年的前端工作不好找,很多童鞋簡歷 ...
  • 一、postcss-loader有什麼用? PostCSS 本身是一個功能比較單一的工具。它提供了一種方式用 JavaScript 代碼來處理 CSS。它負責把 CSS 代碼解析成抽象語法樹結構(Abstract Syntax Tree,AST),再交由插件來進行處理。插件基於 CSS 代碼的 AS ...
  • 1、精靈圖 (1)為什麼需要精靈圖 一個網頁中往往會應用到很多小的背景圖片,當網頁中的圖像過多時,伺服器就會頻繁地接收和發送請求圖片,造成伺服器的壓力過大,這將大大降低頁面的載入速度,精靈圖是將圖片放到一張裡面,這樣的話只要請求一次就可以了 精靈圖的出現降低了伺服器的壓力,提高了圖片的載入速度 (2 ...
  • 1.SierPinski三角形 Sierpinski三角形是一種分形,由波蘭數學家謝爾賓斯基在1915年提出,它是一種典型的自相似集。其生成過程為: (1)取一個三角形(多數使用等邊三角形); (2)沿三邊中點連線,將它分成四個小三角形; (3)對上、左、右這三個小三角形重覆這一過程。 SierPi ...
  • 1 前言 從沒想到Docker也有可視化的工具,因為它的命令還是非常清晰簡單的。無聊搜了一下,原來已經有很多Docker可視化工具了。如DockerUI、Shipyard、Rancher、Portainer等。查看對比了一番,最後覺得Portainer還不錯,功能齊全、界面簡潔好看,就裝來玩玩。 2 ...
  • 編寫一個程式,讀人個數不確定的考試分數,並且判斷有多少個分數是大於或等於平均分,多少個分數是低於平均分的。輸人一個負數表示輸入的結束。假設最高分為100。 Write a program that reads an unspecified number of scores and determine ...
一周排行
    -Advertisement-
    Play Games
  • C#TMS系統代碼-基礎頁面BaseCity學習 本人純新手,剛進公司跟領導報道,我說我是java全棧,他問我會不會C#,我說大學學過,他說這個TMS系統就給你來管了。外包已經把代碼給我了,這幾天先把增刪改查的代碼背一下,說不定後面就要趕鴨子上架了 Service頁面 //using => impo ...
  • 委托與事件 委托 委托的定義 委托是C#中的一種類型,用於存儲對方法的引用。它允許將方法作為參數傳遞給其他方法,實現回調、事件處理和動態調用等功能。通俗來講,就是委托包含方法的記憶體地址,方法匹配與委托相同的簽名,因此通過使用正確的參數類型來調用方法。 委托的特性 引用方法:委托允許存儲對方法的引用, ...
  • 前言 這幾天閑來沒事看看ABP vNext的文檔和源碼,關於關於依賴註入(屬性註入)這塊兒產生了興趣。 我們都知道。Volo.ABP 依賴註入容器使用了第三方組件Autofac實現的。有三種註入方式,構造函數註入和方法註入和屬性註入。 ABP的屬性註入原則參考如下: 這時候我就開始疑惑了,因為我知道 ...
  • C#TMS系統代碼-業務頁面ShippingNotice學習 學一個業務頁面,ok,領導開完會就被裁掉了,很突然啊,他收拾東西的時候我還以為他要旅游提前請假了,還在尋思為什麼回家連自己買的幾箱飲料都要叫跑腿帶走,怕被偷嗎?還好我在他開會之前拿了兩瓶芬達 感覺感覺前面的BaseCity差不太多,這邊的 ...
  • 概述:在C#中,通過`Expression`類、`AndAlso`和`OrElse`方法可組合兩個`Expression<Func<T, bool>>`,實現多條件動態查詢。通過創建表達式樹,可輕鬆構建複雜的查詢條件。 在C#中,可以使用AndAlso和OrElse方法組合兩個Expression< ...
  • 閑來無聊在我的Biwen.QuickApi中實現一下極簡的事件匯流排,其實代碼還是蠻簡單的,對於初學者可能有些幫助 就貼出來,有什麼不足的地方也歡迎板磚交流~ 首先定義一個事件約定的空介面 public interface IEvent{} 然後定義事件訂閱者介面 public interface I ...
  • 1. 案例 成某三甲醫預約系統, 該項目在2024年初進行上線測試,在正常運行了兩天後,業務系統報錯:The connection pool has been exhausted, either raise MaxPoolSize (currently 800) or Timeout (curren ...
  • 背景 我們有些工具在 Web 版中已經有了很好的實踐,而在 WPF 中重新開發也是一種費時費力的操作,那麼直接集成則是最省事省力的方法了。 思路解釋 為什麼要使用 WPF?莫問為什麼,老 C# 開發的堅持,另外因為 Windows 上已經裝了 Webview2/edge 整體打包比 electron ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...