Overview
The Blackjack API uses MySQL with R2DBC (Reactive Relational Database Connectivity) to store player data reactively. MySQL provides reliable persistent storage for player profiles, including names, wins, and losses.Dependencies
The project uses Spring Data R2DBC with MySQL driver, configured inpom.xml:
Connection Configuration
Local Development
For local development, configure R2DBC connection inapplication-local.yml:
Docker Environment
For Docker deployments, use service names inapplication-docker.yml:
Production Environment
For production, use environment variables inapplication-prod.yml:
Configuration Properties
| Property | Description | Example |
|---|---|---|
spring.r2dbc.url | R2DBC connection URL | r2dbc:mysql://localhost:3307/blackjack |
spring.r2dbc.username | Database username | blackjack |
spring.r2dbc.password | Database password | blackjack |
R2DBC URL Format
useSSL=false- Disable SSL for local developmentserverTimezone=UTC- Set server timezone
Database Schema
Theplayers table stores player information:
Table Structure
- id: Auto-incrementing internal ID (primary key)
- external_id: UUID for external references (unique)
- name: Player name, 1-30 characters (unique)
- wins: Total number of wins
- losses: Total number of losses
Entity Model
Players are mapped to R2DBC entities using Spring Data:Reactive R2DBC Repository
The application uses Spring Data’sReactiveCrudRepository for reactive database operations:
Custom Queries
The ranking query uses custom SQL to order players by:- Win/loss differential (descending)
- Total wins (descending)
- Total losses (ascending)
- Player name (ascending)
Repository Adapter
The adapter pattern connects the R2DBC repository to the domain layer:Reactive Operations
All R2DBC operations return reactive types:Mono<Player>- Single player or emptyFlux<Player>- Stream of multiple players- Reactive operations are non-blocking and composable
Example Operations
Save a player:MySQL Setup
Local Development with Docker
Verify Connection
Connect using MySQL client:R2DBC vs JDBC
Why R2DBC?
| Feature | JDBC | R2DBC |
|---|---|---|
| Blocking | Yes | No |
| Reactive | No | Yes |
| Thread Model | One per connection | Event-loop based |
| Backpressure | No | Yes |
| Spring WebFlux | Not optimal | Fully compatible |
Best Practices
- Use Reactive Types: Always return
MonoorFluxfor non-blocking operations - Connection Pooling: Configure appropriate pool sizes for your workload
- Transactions: Use
@Transactionalwith reactive transaction manager when needed - Error Handling: Use reactive operators like
onErrorResumefor graceful error handling - Indexes: Create indexes on
external_idandnamecolumns for fast lookups - Mapping: Keep entity-to-domain mapping logic in repository adapters
Connection Pool Configuration
For production deployments, configure connection pooling:Troubleshooting
Connection Issues
If R2DBC connection fails:- Verify MySQL is running:
docker ps | grep mysql - Check R2DBC URL format (must start with
r2dbc:mysql://) - Ensure database exists and credentials are correct
- Review application logs for connection errors