Free tools Windows power users keep installed
One-click scans. No signup required.
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Spring Boot can connect to MySQL and manage tables, but it does not normally create the MySQL server or database for you. The reliable workflow is to start MySQL, create a database and dedicated user, configure Spring Boot’s JDBC connection, then create tables with a migration (recommended) or Hibernate (for a quick local experiment). This guide uses Java 17+, Spring Boot 4.1.0, and MySQL 8.4 as its baseline; use the compatible version offered by Spring Initializr if the available release has changed.
What you need
- Java 17 or later and a current Maven or Gradle installation. Check the Spring Boot system requirements for the release you select.
- A MySQL server, either installed locally, running in Docker, or provided by a database host. MySQL 8.4 is the baseline used in Spring’s MySQL guide.
- A project generated at Spring Initializr.
Choose Maven or Gradle, Java, Jar packaging, and Java 17 or later. Add Spring Data JPA and MySQL Driver. Add Spring Web if you want to test through HTTP, and Flyway Migration if you want versioned schema changes. Spring Boot manages compatible dependency versions, so avoid pinning a Connector/J version without a specific reason. The driver is published as com.mysql:mysql-connector-j; it provides JDBC communication with MySQL, as described in the Connector/J documentation.
A typical Maven project needs these dependencies (keep the Spring Boot parent or dependency management generated by Initializr):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
For Flyway, add org.flywaydb:flyway-core and org.flywaydb:flyway-mysql, with versions managed by Spring Boot where supported.
#1 Best Overall
Start MySQL and create the database
You can run MySQL outside the application and create the database manually, or use Compose for a repeatable local server. These are alternatives; both leave the same key distinction: the server and database must exist before Spring Boot can use them.
Option 1: Create it in an existing MySQL server
Connect with an administrative account:
mysql -u root -p
Then create a database and a separate application account:
CREATE DATABASE IF NOT EXISTS appdb
CHARACTER SET utf8mb4
COLLATE utf8mb4_0900_ai_ci;
CREATE USER IF NOT EXISTS 'appuser'@'localhost'
IDENTIFIED BY 'change-this-password';
GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'localhost';
SHOW DATABASES;
SELECT User, Host FROM mysql.user WHERE User = 'appuser';
CREATE DATABASE is the MySQL operation that creates the database; it is separate from creating tables. See MySQL’s database-creation reference and character-set guidance. The example collation is appropriate for MySQL 8.4; check compatibility before using it with older MySQL-compatible servers.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →The broad grant above keeps a local tutorial simple. For a deployed application, use a dedicated account with only the privileges it needs, and configure its permitted host deliberately. MySQL account identity includes both the username and host: 'appuser'@'localhost' is not automatically the same account as 'appuser'@'%'. Do not connect your application as root.
Rank #2
Option 2: Run MySQL with Docker Compose
Create compose.yml in the project directory:
services:
mysql:
image: mysql:8.4
environment:
MYSQL_DATABASE: appdb
MYSQL_USER: appuser
MYSQL_PASSWORD: change-this-password
MYSQL_ROOT_PASSWORD: change-this-root-password
ports:
- "127.0.0.1:3306:3306"
volumes:
- mysql-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 10
volumes:
mysql-data:
The loopback-only port binding makes this example accessible from the host machine without exposing MySQL on every network interface. Start the service and check its logs:
docker compose up -d
docker compose logs -f mysql
When the application runs on your computer, connect to localhost:3306. When the application itself runs as another Compose service, use mysql:3306 as the host: inside a container, localhost refers to that container, not its MySQL neighbor. A published port is not needed for service-to-service traffic on the Compose network.
A named volume preserves database files when the container is recreated. MySQL’s initialization variables, including the database, user, and passwords, are applied when the data directory is first initialized; changing them later does not rewrite credentials in an existing volume. To reset a disposable local database, you can run docker compose down -v and then docker compose up -d, but -v permanently deletes that volume’s data. A running container is also not proof that MySQL is ready to accept connections; inspect the logs or retry after startup.
Configure Spring Boot’s connection
For an application running on the host with the Compose example above, put this in src/main/resources/application.properties:
Rank #3
spring.datasource.url=jdbc:mysql://localhost:3306/appdb
spring.datasource.username=appuser
spring.datasource.password=${DB_PASSWORD:change-this-password}
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.open-in-view=false
Set the password through the environment in a real project rather than committing a real credential. The fallback shown is only a local tutorial convenience. For example, set DB_PASSWORD in your shell or run configuration. If the application is another Compose service, change the URL to:
spring.datasource.url=jdbc:mysql://mysql:3306/appdb
The URL follows the JDBC form jdbc:mysql://host:port/database. Spring Boot normally infers the MySQL driver from the URL and dependency, so you do not need to set spring.datasource.driver-class-name for this setup. Old tutorials may specify an obsolete driver coordinate or force a dialect property; do not add either without a specific compatibility need.
Create a table and persist a record
With JPA, map a Java class to a table and expose a repository. For example, create src/main/java/com/example/demo/user/User.java:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorspackage com.example.demo.user;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.Column;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
protected User() {
}
public User(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
}
Use jakarta.persistence imports for current Spring Boot generations; older material may show javax.persistence. @Entity maps the class to a relational entity, @Id marks its primary key, and GenerationType.IDENTITY uses MySQL’s auto-increment style identity. The explicit table name avoids depending on implicit naming conventions.
Rank #4
Then create UserRepository.java in the same package:
package com.example.demo.user;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
Choose how tables are created
Creating the database and creating its tables are different jobs. Hibernate can create tables from entities, while Flyway or Liquibase can apply explicit, versioned schema changes. Spring Boot also supports SQL initialization scripts, but combining several competing schema-management mechanisms makes startup behavior harder to reason about. Its database initialization guidance recommends using a migration tool on its own when one is present.
| Setting or tool | Use | Trade-off |
|---|---|---|
create |
Disposable demo or test schema | Recreates schema at startup and can destroy data. |
create-drop |
Short-lived tests | Creates at startup and drops at shutdown; do not use for data you need to keep. |
update |
Local experimentation | Convenient, but not a dependable versioned migration process or production change plan. |
validate |
Schema managed separately | Checks entity mappings against tables and fails on mismatch; it does not create a missing table. |
none |
Schema managed outside Hibernate | No Hibernate schema action; missing or incorrect schema may surface later. |
| Flyway or Liquibase | Team and production schema changes | Provides explicit, ordered changes; requires migration discipline. |
For a quick first run, you can temporarily set spring.jpa.hibernate.ddl-auto=update and let Hibernate create the table. Do not treat it as a production migration strategy. For a maintainable project, let Flyway own schema changes and keep Hibernate at validate.
Use Flyway for a versioned table
Create src/main/resources/db/migration/V1__create_users_table.sql:
CREATE TABLE users (
id BIGINT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);
Keep spring.jpa.hibernate.ddl-auto=validate. On startup, Flyway applies the migration to the configured database; Hibernate then checks that the entity mapping agrees with the resulting schema. Flyway’s MySQL reference documents its MySQL support.
Verify the connection and insert a row
For a minimal HTTP check, add a controller. This example accepts and returns an entity directly to keep the setup short; a real API should generally use request/response DTOs, validation, and explicit error handling.
package com.example.demo.user;
import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/users")
public class UserController {
private final UserRepository repository;
public UserController(UserRepository repository) {
this.repository = repository;
}
@PostMapping
public User create(@RequestBody User user) {
return repository.save(user);
}
@GetMapping
public List<User> findAll() {
return repository.findAll();
}
}
Start the application with the Maven wrapper (./mvnw spring-boot:run, or mvn spring-boot:run if you do not have the wrapper), then insert and read a record:
Recommended Free Tools
curl -X POST http://localhost:8080/users
-H "Content-Type: application/json"
-d '{"name":"Ada"}'
curl http://localhost:8080/users
The POST response should include an assigned ID, and the GET response should include the saved user. You can independently confirm the database state by connecting to MySQL and running:
USE appdb;
SHOW TABLES;
SELECT * FROM users;
If using a Compose-only MySQL service, one local way to connect from the host is docker compose exec mysql mysql -uappuser -p appdb; enter the password when prompted. Avoid placing real passwords in shell history.
Troubleshoot common failures
| Error or symptom | What to check |
|---|---|
Communications link failure or connection refused |
Confirm MySQL is running and ready, the port is correct, and the URL host matches where the application runs. Use localhost from the host and the Compose service name mysql from a sibling container. Confirm Docker publishes the port if connecting from the host. |
Unknown database 'appdb' |
The server responded, but that database does not exist on that server or the URL names another database. Run SHOW DATABASES; on the same server and create it or correct the URL. |
Access denied for user |
Check the credential and the MySQL account’s host component and grants. A connection through a different hostname or network path may match a different MySQL account. Inspect with SHOW GRANTS FOR 'appuser'@'localhost'; when that is the account in use. |
No suitable driver |
Ensure the MySQL Driver dependency is included, the artifact was rebuilt, and the runtime classpath contains Connector/J. Use the current com.mysql:mysql-connector-j coordinate rather than an old copied coordinate. |
Table doesn't exist |
Check whether schema creation is disabled or set to validate without a migration, whether the migration is under src/main/resources/db/migration, whether it failed in startup logs, and whether SQL and entity table names match. |
| Compose password changes have no effect | An existing named volume retains its initialized database state. Reset only if its contents can be discarded: docker compose down -v deletes the volume, after which Compose initializes a new database. |
If you see Public Key Retrieval is not allowed, do not blindly paste an old JDBC parameter as a fix. Check the MySQL authentication configuration, Connector/J version, and TLS requirements for your environment; secure authentication should be configured deliberately.
Before deploying
- Use a dedicated, least-privilege database account, not MySQL
root. - Keep secrets out of source control; use deployment environment variables or a secret manager.
- Use Flyway or Liquibase to version schema changes, and validate mappings rather than silently updating production schema.
- Use TLS and restrict network access according to the deployment environment.
- Plan backups, recovery, connection limits/pooling, and health checks; a container health check alone does not guarantee application retries.
- Keep development, test, staging, and production databases separate. For integration tests that need MySQL-specific behavior, consider Testcontainers rather than assuming an H2 test behaves identically.
Spring Data JPA is not required for every application. If you prefer explicit SQL and do not need ORM mapping, Spring JDBC is a simpler alternative; the Spring MySQL guide discusses both approaches. MySQL-compatible services such as MariaDB can differ in driver behavior, authentication, and SQL features, so verify compatibility rather than assuming they are interchangeable. A managed MySQL service can reduce database-operations work, but is optional; compare backups, availability, networking, operational burden, and workload-specific costs before choosing one.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchQuick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

