0%

Java | 使用 IDEA 的文件模板功能简化 Spring Boot 的类创建

环境

  • IntelliJ IDEA Community 2020.3.3

介绍

在 Spring Boot 项目中,每当新增一个 entity/module 对象时,如UserPO.java,接下来通常还要创建对应的 repository、service、service implement、controller 等,并且这些文件初始的内容也都是相似的,一套模板类创建下来,真是又慢又重复的劳动。

于是,想着是否存在根据类模板“一键”创建多个类文件的功能,在Settings中一通翻找,在File and Code Templates中找到了解决办法。本文就是介绍通过文件模板批量创建类文件的步骤。

期望+最终效果演示

先演示一下最终实现的效果,也是最初的需求:

  1. 在包根目录下,右键——>New——>选择新设置的模板,
    Right click
  2. 输入 entity 名,如User,首字母大写
    Input entity
  3. 生成的如下文件:
    • entity/po : User.java
    • dao : UserRepository.java
    • service : UserService.java
    • service/impl : UserServiceImpl.java
    • controller : UserController.java

对应的项目结构如下,下文的配置也是以这个结构为前提的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
src/main/java
└── com.github.quanqinle
├── Application.java
├── entity
│ ├── po
│ │ └── User.java
│ └── vo
├── dao
│ └── UserRepository.java
├── service
│ ├── impl
│ │ └── UserServiceImpl.java
│ └── UserService.java
└── controller
└── UserController.java

设置

先放一张最终的配置,就像下图中的(1)所示:

Final settings

图1

配置 PO 模板

打开Settings窗口,找到Editor——>File and Code templates,在Files分类下,点击Create Template,即图 1 的按钮(2)

  • Name:右键创建时看到的名字,例Create whole classes in package root
  • Extension:默认的 java
  • File Name:文件路径和文件名(不用加.java 后缀),./entity/po/${Subject}
  • 输入模板内容,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#set($SubjectOfLowerFirst = ${Subject.substring(0,1).toLowerCase()} + $Subject.substring(1))
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.entity.po;#end

import lombok.Data;
import javax.persistence.*;
import java.time.LocalDateTime;

#parse("File Header.java")
@Data
@Entity
@Table(name = "${SubjectOfLowerFirst}")
public class ${Subject} {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

/**
* name
*/
private String name;

@Column(name = "create_time")
private LocalDateTime createTime;
@Column(name = "update_time")
private LocalDateTime updateTime;
}

配置 DAO 模板

选中第一步创建的Create Template前提下,点击Create Child Template File,即图 1 的按钮(3)

  • File Name:文件路径和文件名(不用加.java 后缀),./dao/${Subject}Repository
  • Extension:默认的 java
  • 输入模板内容,如下:
1
2
3
4
5
6
7
8
9
10
11
#set($SubjectOfLowerFirst = ${Subject.substring(0,1).toLowerCase()} + $Subject.substring(1))
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.dao;#end

import ${PACKAGE_NAME}.entity.po.${Subject};
import org.springframework.stereotype.Repository;
import org.springframework.data.jpa.repository.JpaRepository;

#parse("File Header.java")
@Repository
public interface ${Subject}Repository extends JpaRepository<${Subject}, Long> {
}

配置 Service 模板

选中第一步创建的Create Template前提下,点击Create Child Template File,即图 1 的按钮(3)

  • File Name:文件路径和文件名(不用加.java 后缀),./service/${Subject}Service
  • Extension:默认的 java
  • 输入模板内容,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#set($SubjectOfLowerFirst = ${Subject.substring(0,1).toLowerCase()} + $Subject.substring(1))
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.service;#end

import ${PACKAGE_NAME}.entity.po.${Subject};
import java.util.Optional;

#parse("File Header.java")
public interface ${Subject}Service {

/**
* insert
* @param ${SubjectOfLowerFirst} a ${Subject} object
* @return
*/
${Subject} insert(${Subject} ${SubjectOfLowerFirst});

/**
* update
* @param ${SubjectOfLowerFirst} a ${Subject} object
* @return
*/
${Subject} update(${Subject} ${SubjectOfLowerFirst});

/**
* query by id
* @param id ${Subject} id
* @return
*/
Optional<${Subject}> queryById(Long id);

/**
* delete by id
* @param id ${Subject} id
* @return
*/
boolean deleteById(Long id);

}

配置 Service Implement 模板

选中第一步创建的Create Template前提下,点击Create Child Template File,即图 1 的按钮(3)

  • File Name:文件路径和文件名(不用加.java 后缀),./service/impl/${Subject}ServiceImpl
  • Extension:默认的 java
  • 输入模板内容,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#set($SubjectOfLowerFirst = ${Subject.substring(0,1).toLowerCase()} + $Subject.substring(1))
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.service.impl;#end

import ${PACKAGE_NAME}.dao.${Subject}Repository;
import ${PACKAGE_NAME}.entity.po.${Subject};
import ${PACKAGE_NAME}.service.${Subject}Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;

#parse("File Header.java")
@Service
@Transactional(rollbackFor = Exception.class)
public class ${Subject}ServiceImpl implements ${Subject}Service {

private Logger log = LoggerFactory.getLogger(${Subject}Service.class);

@Autowired
private ${Subject}Repository repository;

public ${Subject}ServiceImpl() {
}

@Override
public ${Subject} insert(${Subject} ${SubjectOfLowerFirst}) {
return repository.save(${SubjectOfLowerFirst});
}

@Override
public ${Subject} update(${Subject} ${SubjectOfLowerFirst}) {
return repository.save(${SubjectOfLowerFirst});
}

@Override
public boolean deleteById(Long id) {
boolean result = true;
try {
repository.deleteById(id);
} catch (Exception e) {
result = false;
}
return result;
}

@Override
public Optional<${Subject}> queryById(Long id) {
return repository.findById(id);
}

}

配置 Controller 模板

选中第一步创建的Create Template前提下,点击Create Child Template File,即图 1 的按钮(3)

  • File Name:文件路径和文件名(不用加.java 后缀),./controller/${Subject}Controller
  • Extension:默认的 java
  • 输入模板内容,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#set($SubjectOfLowerFirst = ${Subject.substring(0,1).toLowerCase()} + $Subject.substring(1))
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.controller;#end

import ${PACKAGE_NAME}.entity.Result;
import ${PACKAGE_NAME}.entity.po.${Subject};
import ${PACKAGE_NAME}.service.${Subject}Service;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;

#parse("File Header.java")
// @Controller
@RestController
@RequestMapping("/api/${SubjectOfLowerFirst}")
public class ${Subject}Controller {

@Resource
private ${Subject}Service ${SubjectOfLowerFirst}Service;

@PostMapping
public Result<${Subject}> create(@RequestBody ${Subject} record) {
${Subject} ${SubjectOfLowerFirst} = ${SubjectOfLowerFirst}Service.insert(record);
return Result.success(${SubjectOfLowerFirst});
}

@PutMapping
public Result<${Subject}> update(@RequestBody ${Subject} record) {
${Subject} ${SubjectOfLowerFirst} = ${SubjectOfLowerFirst}Service.update(record);
return Result.success(${SubjectOfLowerFirst});
}

@DeleteMapping("/{id}")
public Result<Void> deleteById(@PathVariable Long id) {
boolean success = ${SubjectOfLowerFirst}Service.deleteById(id);
return success ? Result.success() : Result.fail();
}

@GetMapping("/{id}")
public Result<${Subject}> queryById(@PathVariable Long id) {
var optional = ${SubjectOfLowerFirst}Service.queryById(id);
if (optional.isPresent()) {
return Result.success(optional.get());
} else {
return Result.success();
}
}

}

保存配置。

欢迎关注我的其它发布渠道