システムアーキテクチャの概要
本記事では、シェアサイクルの運営支援と利用データの分析を目的としたWebアプリケーションのアーキテクチャと実装について解説します。バックエンドにはSpring Boot、フロントエンドにはVue.jsを採用し、データ永続化にはMySQLを使用しています。この構成により、大量の骑行(利用)データの処理と、直感的な管理画面の提供を両立しています。
バックエンドフレームワーク:Spring Boot
Spring Bootは、スタンドアロンで本番環境対応のSpringアプリケーションを迅速に構築するためのフレームワークです。「設定より規約(Convention over Configuration)」の原則に基づき、デフォルト設定を提供することで開発環境の複雑さを大幅に軽減します。
主な特徴として、TomcatやJettyなどのServletコンテナを内包しているため、WARファイルのデプロイなしでアプリケーションを単独で実行可能です。また、自動設定機能により、煩雑なXML設定を排除し、最小限のコードでアプリケーションを起動できます。これにより、開発者はビジネスロジックの実装に集中することができます。
フロントエンドフレームワーク:Vue.js
Vue.jsは、ユーザーインターフェース構築のためのプログレッシブなJavaScriptフレームワークです。コンポーネント指向の設計により、複雑なシングルページアプリケーション(SPA)を容易に構築できます。
Vue.jsの核心はリアクティブなデータバインディングと仮想DOM(Virtual DOM)です。データの変更が自動的にUIに反映されるため、状態管理が簡素化され、DOM操作の最適化により高いレンダリングパフォーマンスを実現します。さらに、Vue Routerによるルーティング管理や、Vuex(またはPinia)による状態管理、単一ファイルコンポーネント(SFC)によるHTML/CSS/JSの統合など、モダンなフロントエンド開発に必要なエコシステムが充実しています。
データベース:MySQL
MySQLは、オープンソースの関係データベース管理システム(RDBMS)であり、その高いパフォーマンス、信頼性、柔軟性から広く採用されています。標準SQLに準拠しており、データの操作や検索を効率的に行えます。
InnoDBやMyISAMなど複数のストレージエンジンをサポートしており、トランザクション処理やロック機構を必要とするシェアサイクルのリアルタイムなステータス管理には、InnoDBエンジンが最適です。また、クロスプラットフォーム対応により、LinuxやWindowsなど様々なOS環境で安定して動作します。
コア設定とデータアクセス層の実装
以下は、システムのデータベース接続およびORMフレームワーク(MyBatis-Plus)の設定ファイルと、シェアサイクルの車両管理を行うデータアクセス層の実装例です。
アプリケーション設定 (application.yml)
server:
port: 8090
tomcat:
uri-encoding: UTF-8
servlet:
context-path: /api/bike-share
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/bike_share_analytics?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Tokyo
username: admin_user
password: secure_password_123
servlet:
multipart:
max-file-size: 500MB
max-request-size: 500MB
mybatis-plus:
mapper-locations: classpath*:/mappers/**/*.xml
type-aliases-package: com.bikeshare.entity
global-config:
db-config:
id-type: ASSIGN_ID
logic-delete-field: isDeleted
logic-delete-value: 1
logic-not-delete-value: 0
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
call-setters-on-nulls: true
車両データマッパー (BicycleMapper.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.bikeshare.mapper.BicycleMapper">
<resultMap type="com.bikeshare.entity.Bicycle" id="bicycleResultMap">
<id property="bikeId" column="bike_id"/>
<result property="qrCode" column="qr_code"/>
<result property="modelType" column="model_type"/>
<result property="operationalStatus" column="operational_status"/>
<result property="lastMaintenanceDate" column="last_maintenance_date"/>
<result property="currentLocation" column="current_location"/>
</resultMap>
<select id="fetchAvailableBicycles" resultMap="bicycleResultMap">
SELECT * FROM bicycles
<where>
operational_status = 'ACTIVE'
<if test="ew.customSqlSegment != null and ew.customSqlSegment != ''">
AND ${ew.customSqlSegment}
</if>
</where>
</select>
<select id="getBicycleDetailsById" resultType="com.bikeshare.dto.BicycleDetailDTO">
SELECT b.*, m.maintenance_notes
FROM bicycles b
LEFT JOIN maintenance_logs m ON b.bike_id = m.bike_id
WHERE b.bike_id = #{bikeId}
</select>
</mapper>