権限管理システムの実装ガイド

一、ロール管理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);
    }

タグ: SpringBoot MyBatis-Plus redis MySQL SpringSecurity

6月3日 18:46 投稿