一、ロール管理APIの実装
1. 使用技術スタック
| フレームワーク:SpringBoot |
|---|
| キャッシュ:Redis |
| データベース:MySQL |
| 認証:SpringSecurity |
| ワークフロー:Activiti |
| フロントエンド:vue-admin-template + Node.js + Npm + Vue + ElementUI + Axios |
| 微信統合:メニューAPI + OAuth認証 + メッセージ配信 |
2. モジュール構成
- YunshangOffice:ルートモジュール
- common:共通クラスモジュール
- util:ユーティリティクラス
- service:サービス層共通処理
- security:認証関連モジュール
- model:エンティティ定義モジュール
- service-oa:システムサービスモジュール
3. 環境構築手順
3.1 プロジェクト構造作成
3.2 デpendency設定
3.2.1 ルートモジュールの依存関係
<!--SpringBootプロジェクト必須の親依存-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.10</version>
</parent>
<properties>
<java.version>1.8</java.version>
<mybatis.version>3.4.1</mybatis.version>
<mysql.version>8.0.30</mysql.version>
<swagger.version>3.0.3</swagger.version>
<jwt.version>0.9.1</jwt.version>
<json.version>2.0.21</json.version>
</properties>
<!--依存関係バージョン管理-->
<dependencyManagement>
<dependencies>
<!--MyBatis Plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!--MySQL-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--Swagger UI-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>${swagger.version}</version>
</dependency>
<!--JWTライブラリ-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<!--JSONライブラリ-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${json.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
3.2.2 utilモジュールの依存関係
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
3.2.3 serviceモジュールの依存関係
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>util</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--MySQL-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
3.2.4 modelモジュールの依存関係
<dependencies>
<!--Lombokによるエンティティ簡略化-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
3.2.5 service-oaモジュールの依存関係
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>model</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3.3 MyBatis-Plusテストケース
3.3.1 データベース作成とロールテーブル
-- データベース作成
CREATE DATABASE `YunshangOffice`;
use `YunshangOffice`;
-- ロールテーブル作成
CREATE TABLE `sys_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ロールID',
`role_name` varchar(20) NOT NULL DEFAULT '' COMMENT 'ロール名',
`role_code` varchar(20) DEFAULT NULL COMMENT 'ロールコード',
`description` varchar(255) DEFAULT NULL COMMENT '説明',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '作成日時',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新日時',
`is_deleted` tinyint(3) NOT NULL DEFAULT '0' COMMENT '削除フラグ(0:無効 1:有効)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COMMENT='ロール';
3.3.2 設定ファイル
SpringBootアプリケーションでは通常1つの設定ファイル(application.yml)を使用しますが、spring.profiles属性で特定環境の設定ファイルを指定可能です。
# application.yml
spring:
application:
name: service-oa
profiles:
active: dev
# application-dev.yml
server:
port: 8800
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # ロギング設定
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/データベース名?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8
username: ユーザー名
password: パスワード
3.3.3 エンティティクラス
//BaseEntity
package pers.beiluo.yunshangoffice.model.base;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Data
public class BaseEntity implements Serializable {
//自動増分ID設定
@TableId(type = IdType.AUTO)
private Long id;
/**
* テーブルフィールドとエンティティフィールドのマッピング
*/
@TableField("create_time")
private Date createTime;
@TableField("update_time")
private Date updateTime;
/**
* 論理削除設定
*/
@TableLogic
@TableField("is_deleted")
private Integer isDeleted;
/**
* マップ型パラメータ保持
*/
@TableField(exist = false)
private Map<String,Object> param = new HashMap<>();
}
//SysRole
package pers.beiluo.yunshangoffice.model.system;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import pers.beiluo.yunshangoffice.model.base.BaseEntity;
/**
* 継承時の注釈使用注意点
*/
@Data
@TableName("sys_role")
public class SysRole extends BaseEntity {
private static final long serialVersionUID = 1L;
@TableField("role_name")
private String roleTitle;
@TableField("role_code")
private String roleIdentifier;
@TableField("description")
private String description;
}
3.3.4 Mapperインターフェース
package pers.beiluo.yunshangoffice.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import pers.beiluo.yunshangoffice.model.system.SysRole;
/**
* マッパーインターフェース
*/
@Mapper
public interface RoleRepository extends BaseMapper<SysRole> {
}
3.3.5 アプリケーション起動クラス
package pers.beiluo.yunshangoffice;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* マッパー検索範囲指定
*/
@SpringBootApplication(scanBasePackages = "pers.beiluo.yunshangoffice")
@MapperScan("pers.beiluo.yunshangoffice.mapper")
public class AuthServiceApplication {
public static void main(String[] args) {
SpringApplication.run(AuthServiceApplication.class,args);
}
}
3.3.6 テストケース
//テストクラス
package pers.beiluo.yunshangoffice;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import pers.beiluo.yunshangoffice.mapper.RoleRepository;
import pers.beiluo.yunshangoffice.model.system.SysRole;
import javax.annotation.Resource;
import java.util.List;
@SpringBootTest
public class RoleRepositoryTest {
@Autowired
private RoleRepository repository;
}
3.3.6.1 全件取得テスト
//全ロール取得テスト
@Test
public void fetchAllRoles(){
List<SysRole> roles = repository.selectList(null);
roles.forEach(System.out::println);
}
3.3.6.2 新規登録テスト
//新規登録テスト
@Test
public void createRoleTest(){
SysRole role = new SysRole();
role.setRoleTitle("管理者");
role.setRoleIdentifier("admin");
role.setDescription("システム管理者");
int result = repository.insert(role);
System.out.println(result);
System.out.println(role);
}
3.3.6.3 更新テスト
//更新テスト
@Test
public void updateRoleTest(){
SysRole role = new SysRole();
role.setId(1L);
role.setRoleTitle("スーパーマネージャー");
int result = repository.updateById(role);
System.out.println(result);
}
3.3.6.4 削除テスト
//単体削除テスト
@Test
public void deleteRoleTest(){
int result = repository.deleteById(9);
System.out.println(result);
}
//複数削除テスト
@Test
public void batchDeleteTest(){
int result = repository.deleteBatchIds(Arrays.asList(1,2));
System.out.println(result);
}
3.3.6.5 条件検索テスト
//条件検索テスト
@Test
public void searchRolesTest(){
LambdaQueryWrapper<SysRole> query = new LambdaQueryWrapper<>();
query.eq(SysRole::getRoleIdentifier, "admin");
List<SysRole> roles = repository.selectList(query);
roles.forEach(System.out::println);
}