主頁 > 後端開發 > MyBatis-Plus入門,看這一篇就足夠了

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

2020-10-03 10:12:17 後端開發

文章設計源代碼和筆記: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=https://www.cnblogs.com/MessiXiaoMo3334/p/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生成的時候會讓你選擇當前分組的模板

,

,

,

.

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/151063.html

標籤:Java

上一篇:SpringMVC+Spring+Hibernate個人家庭財務管理系統

下一篇:第七章第四題(分析成績)(Analyze scores) - 編程練習題答案

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more