> 當然可使用代碼生成器極速生成如下代碼,以下為具體講解各步驟注意事項
## 編寫`entity`
* 每一個`entity`類即為一個實體類,對應數據庫中的一個具體表。
* 名稱=`表具體名稱`,表名中`_`替換為駝峰命名法,首字母大寫。如:`Student`對應表為`t_student`。
* 創建在 項目模塊 的`xxx.entity.[模塊名稱]`包下。如:`xxx.entity.Student`
### 屬性規范
* 所有屬性均為`private`屬性。
* 每一個屬性需要生成對應的`getter`和`setter`方法。
* 字段名稱應根據駝峰命名規則從數據庫列名轉換過來。例如:數據庫列名為`USER_NAME`,則字段名為`UserName`,特殊字段名稱,可以在字段在添加`@Column(name = "xxx")`注解,指定數據庫列名。
* 每個屬性需加上Swagger注解,相當于注釋,且前端代碼生成器會用到該注釋。
* 建議可添加`Long`類型屬性`objectVersionNumber`,用以更新數據時的版本控制。
### 屬性的的類型與字段的`type`對應
* 不使用基本類型,全部使用基本類型的包裝類,如`Long`對應數據庫中的`INTEGER`,而不是使用`long`。
* 數字類型主鍵統一采用`Long`。
* 金額、數量 等精度嚴格浮點類型采用`BigDecimal`
> 注意:BigDecimal 在計算、比較方面的特殊性
### 所有的主鍵字段都需要用`@Id`標注
\* 對于自增張、序列(SEQUENCE)類型的主鍵,需要添加注解`@GeneratedValue`。
\* 序列命名規范:`表名_S`。例如:表`SYS_USER`對應的序列為`SYS_USER_S`。
### 非數據庫字段
* 需要用`@Transient`標注`javax.persistence.Transient`
### `entity`類相關注解
* `@Data`,Lombok自動生成get和set方法
* `@Entity`,JPA聲明實體類,并且使用默認的ORM規則,即類名即數據庫表中表名
* `@Table`,JPA改變類名與數據庫中表名的默認ORM映射規則
* `@TableName`,Mybatis-Plus注解
* `@ApiModel`,Swagger實體類注解
* `@ApiModelProperty`,Swagger實體類字段注解
### `Student.java`代碼
~~~
// 省略 import
/**
* @author Exrick
*/
@Data
@Entity
@Table(name = "t_student")
@TableName("t_student")
@ApiModel(value = "測試")
public class Student extends XbootBaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用戶名")
private String username;
@ApiModelProperty(value = "密碼")
private String password;
@ApiModelProperty(value = "版本")
private Long objectVersionNumber;
}
~~~
## 編寫Dao
### `Dao`接口類
* `Dao`接口類定義了數據操作的一系列接口,并不提供實現,具體實現需要通過`Dao`實現層提供。創建在項目模塊的`xxx.dao`包下。
* 每一個`Dao`對應一個`entity`,所以命名為`entity`類名尾綴替換為`Dao`。如:`StudentDao`對應`Student`。
### `StudentDao.java`代碼
~~~
// 省略 import
/**
* 測試數據處理層
* @author Exrick
*/
public interface StudentDao extends XbootBaseDao<Student,String> {
}
~~~
## 編寫應用層`Service`
`service`調用領域對象或服務來解決問題,應用層Service主要有以下特性:
1. 負責事務處理,所以事務的注解可以在這一層的`service`中使用。
2. 只處理非業務邏輯,重點是調度業務處理流程。業務邏輯處理一定要放在領域層處理。
3. 不做單元測試,只做驗收測試。
4. 可能會有比較多的依賴組件(領域實體數據層)。
## `Service`接口類
* `Service`接口類定義了業務操作的一系列接口,并不提供實現,具體實現需要通過服務實現層提供,所以屬于供應方的服務接口層。創建在項目模塊的`xxx.service`包下。
### `StudentService.java`代碼
~~~
// 省略 import
/**
* 測試接口
* @author Exrick
*/
public interface StudentService extends XbootBaseService<Student,String> {
/**
* 多條件分頁獲取
* @param student
* @param searchVo
* @param pageable
* @return
*/
Page<Student> findByCondition(Student student, SearchVo searchVo, Pageable pageable);
}
~~~
## `Service`實現類
* `Service`接口的具體實現通過服務實現層提供,所以屬于供應方的服務實現層。創建在項目模塊的`xxx.serviceimpl`包下。
* 實現類,需要用`@Service`標注
### `StudentServiceImpl.java`代碼
~~~
// 省略 import
@Slf4j
@Service
@Transactional
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentDao studentDao;
@Override
public StudentDao getRepository() {
return studentDao;
}
}
~~~
## 編寫`Controller`
* `Controller`負責對`Model`和`View`的處理,創建在項目模塊的`xxx.api.controller.v1`包下。如`xxx.api.controller.v1`。
* 每一個`Controller`是對一個具體的`DTO`或`VO`資源進行處理的,所以命名為`dto`或`vo`類名尾綴替換為`Controler`。如:`StudentController`對應`StudentDTO`或`StudentVO`類。
* 需要通過`@Controller`指定該類為一個`Controller`類。
### `Controller`類相關注解
* `@PreAuthorize`,設置API訪問權限,Spring Security官方推薦該權限管理,當然你可以在XBoot權限菜單中動態配置,更佳靈活
* @PreAuthorize("authenticated")
* @PreAuthorize("hasAuthority('SCOPE\_add')")
* @PreAuthorize("hasRole('ADMIN')")
* @PreAuthorize("hasRole('ADMIN') AND hasRole('USER')")
* @PreAuthorize("hasRole('ADMIN') OR hasRole('USER')")
~~~
@PreAuthorize("authentication.name == #username")
public User find(String username) {
return null;
}
~~~
* 更多詳見[官方文檔](https://docs.spring.io/spring-security/site/docs/5.1.5.RELEASE/reference/htmlsingle/#method-security-expressions)
* `@ApiOperation`,顯示在Swagger上的接口注釋
* `@GetMapping`,是一個組合注解,是`@RequestMapping(mathod = RequestMethod.GET)`的縮寫,`@PostMapping`等同理。建議使用**組合注解**。
### `StudentController.java`代碼
~~~
// 省略 import
/**
* @author Exrick
*/
@Slf4j
@RestController
@Api(description = "測試管理接口")
@RequestMapping("/xboot/student")
@Transactional
public class StudentController extends XbootBaseController<Student, String> {
@Autowired
private StudentService studentService;
@Override
public StudentService getService() {
return studentService;
}
}
~~~