diff --git a/.run/petclinic.run.xml b/.run/petclinic.run.xml
deleted file mode 100644
index 1af228ba3..000000000
--- a/.run/petclinic.run.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/AfflictingQuery.png b/AfflictingQuery.png
deleted file mode 100644
index 3537a8687..000000000
Binary files a/AfflictingQuery.png and /dev/null differ
diff --git a/AfterOverview.png b/AfterOverview.png
deleted file mode 100644
index d47c270cd..000000000
Binary files a/AfterOverview.png and /dev/null differ
diff --git a/AfterTrace.png b/AfterTrace.png
deleted file mode 100644
index 2e278a56c..000000000
Binary files a/AfterTrace.png and /dev/null differ
diff --git a/BeforeTrace.png b/BeforeTrace.png
deleted file mode 100644
index 7777cf6e1..000000000
Binary files a/BeforeTrace.png and /dev/null differ
diff --git a/LocatedCode.png b/LocatedCode.png
deleted file mode 100644
index dd67ce15a..000000000
Binary files a/LocatedCode.png and /dev/null differ
diff --git a/SidePaneView.png b/SidePaneView.png
deleted file mode 100644
index 8738afe5d..000000000
Binary files a/SidePaneView.png and /dev/null differ
diff --git a/build.gradle b/build.gradle
index 1a53c506e..7839ea7f9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,8 +1,8 @@
plugins {
- id 'java'
- id 'org.springframework.boot' version '3.1.1'
- id 'io.spring.dependency-management' version '1.1.0'
- id 'org.graalvm.buildtools.native' version '0.9.23'
+ id 'java'
+ id 'org.springframework.boot' version '3.1.1'
+ id 'io.spring.dependency-management' version '1.1.0'
+ id 'org.graalvm.buildtools.native' version '0.9.23'
}
apply plugin: 'java'
@@ -11,42 +11,36 @@ group = 'org.springframework.samples'
version = '3.1.0'
sourceCompatibility = '17'
-def OPENTELEMETRY_VERSION = '1.22.1'
-
repositories {
- mavenCentral()
+ mavenCentral()
}
ext.webjarsFontawesomeVersion = "4.7.0"
ext.webjarsBootstrapVersion = "5.2.3"
dependencies {
- implementation 'org.hibernate:hibernate-core:6.2.1.Final'
- implementation 'org.springframework.boot:spring-boot-starter-cache'
- implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
- implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
- implementation 'org.springframework.boot:spring-boot-starter-web'
- implementation 'org.springframework.boot:spring-boot-starter-validation'
- implementation 'javax.cache:cache-api'
- implementation 'jakarta.xml.bind:jakarta.xml.bind-api'
- runtimeOnly 'org.springframework.boot:spring-boot-starter-actuator'
- runtimeOnly "org.webjars.npm:bootstrap:${webjarsBootstrapVersion}"
- runtimeOnly "org.webjars.npm:font-awesome:${webjarsFontawesomeVersion}"
- runtimeOnly 'com.github.ben-manes.caffeine:caffeine'
- runtimeOnly 'org.postgresql:postgresql'
- developmentOnly 'org.springframework.boot:spring-boot-devtools'
- testImplementation 'org.springframework.boot:spring-boot-starter-test'
- testImplementation 'org.springframework.boot:spring-boot-testcontainers'
- testImplementation 'org.springframework.boot:spring-boot-docker-compose'
- testImplementation 'org.testcontainers:junit-jupiter'
-
- implementation("io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations:${OPENTELEMETRY_VERSION}")
- implementation("io.opentelemetry.instrumentation:opentelemetry-instrumentation-api:${OPENTELEMETRY_VERSION}")
-
+ implementation 'org.springframework.boot:spring-boot-starter-cache'
+ implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
+ implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
+ implementation 'org.springframework.boot:spring-boot-starter-web'
+ implementation 'org.springframework.boot:spring-boot-starter-validation'
+ implementation 'javax.cache:cache-api'
+ implementation 'jakarta.xml.bind:jakarta.xml.bind-api'
+ runtimeOnly 'org.springframework.boot:spring-boot-starter-actuator'
+ runtimeOnly "org.webjars.npm:bootstrap:${webjarsBootstrapVersion}"
+ runtimeOnly "org.webjars.npm:font-awesome:${webjarsFontawesomeVersion}"
+ runtimeOnly 'com.github.ben-manes.caffeine:caffeine'
+ runtimeOnly 'com.h2database:h2'
+ runtimeOnly 'com.mysql:mysql-connector-j'
+ runtimeOnly 'org.postgresql:postgresql'
+ developmentOnly 'org.springframework.boot:spring-boot-devtools'
+ testImplementation 'org.springframework.boot:spring-boot-starter-test'
+ testImplementation 'org.springframework.boot:spring-boot-testcontainers'
+ testImplementation 'org.springframework.boot:spring-boot-docker-compose'
+ testImplementation 'org.testcontainers:junit-jupiter'
+ testImplementation 'org.testcontainers:mysql'
}
-
-
tasks.named('test') {
- useJUnitPlatform()
+ useJUnitPlatform()
}
diff --git a/createDB.py b/createDB.py
deleted file mode 100644
index b163d0bd9..000000000
--- a/createDB.py
+++ /dev/null
@@ -1,27 +0,0 @@
-import os as installer
-try:
- import psycopg2
-
-except ImportError:
- installer.system("pip install psycopg2 --user")
- print("All packages successfully installed")
-
- import psycopg2
-
-
-conn = psycopg2.connect(
- database="postgres", user="postgres", password="admin", host="127.0.0.1", port="5432"
-)
-
-conn.autocommit = True
-
-cursor = conn.cursor()
-
-sql = '''CREATE database petclinic'''
-
-cursor.execute(sql)
-
-print("Database created successfully")
-
-conn.close()
-
\ No newline at end of file
diff --git a/loadScript.sh b/loadScript.sh
deleted file mode 100644
index 20dd5bffe..000000000
--- a/loadScript.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-shell_files=("hibernateLoad.sh" "sqlLoad.sh" "dbcpLoad.sh" "jdbcLoad.sh")
-
-for file in "${shell_files[@]}"; do
- echo "Running $file"
- bash "$file" &
-
- # Store the process ID of the background job
- pid=$!
-
- # Wait for the process to finish
- wait "$pid"
-
- echo "$file completed"
-done
-
-echo "All shell files completed"
diff --git a/ownerLoad.sh b/ownerLoad.sh
deleted file mode 100644
index 222717b3c..000000000
--- a/ownerLoad.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-THREAD_COUNT=100
-
-callOwners() {
- responseOwners=$(curl "http://localhost:9753/owners")
-}
-
-for ((i=0; i<$THREAD_COUNT; i++)); do
- callOwners &
-done
-
-wait
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java
index 2b639c429..d87b7806e 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java
@@ -18,7 +18,6 @@ package org.springframework.samples.petclinic.owner;
import java.util.List;
import java.util.Map;
-import io.opentelemetry.instrumentation.annotations.WithSpan;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
@@ -65,7 +64,6 @@ class OwnerController {
return ownerId == null ? new Owner() : this.owners.findById(ownerId);
}
- @WithSpan
@GetMapping("/owners/new")
public String initCreationForm(Map model) {
Owner owner = new Owner();
@@ -83,14 +81,12 @@ class OwnerController {
return "redirect:/owners/" + owner.getId();
}
- @WithSpan
@GetMapping("/owners/find")
public String initFindForm() {
return "owners/findOwners";
}
- @WithSpan
@GetMapping("/owners")
public String processFindForm(@RequestParam(defaultValue = "1") int page, Owner owner, BindingResult result,
Model model) {
@@ -129,11 +125,9 @@ class OwnerController {
private String addPaginationModel(int page, Model model, Page paginated) {
model.addAttribute("listOwners", paginated);
- //List listOwners = paginated.getContent();
model.addAttribute("currentPage", page);
model.addAttribute("totalPages", paginated.getTotalPages());
model.addAttribute("totalItems", paginated.getTotalElements());
- //model.addAttribute("listOwners", listOwners);
model.addAttribute("listOwners",paginated);
return "owners/ownersList";
}
diff --git a/src/main/resources/application-mysql.properties b/src/main/resources/application-mysql.properties
new file mode 100644
index 000000000..e23dfa605
--- /dev/null
+++ b/src/main/resources/application-mysql.properties
@@ -0,0 +1,7 @@
+# database init, supports mysql too
+database=mysql
+spring.datasource.url=${MYSQL_URL:jdbc:mysql://localhost/petclinic}
+spring.datasource.username=${MYSQL_USER:petclinic}
+spring.datasource.password=${MYSQL_PASS:petclinic}
+# SQL is written to be idempotent so this is safe
+spring.sql.init.mode=always
diff --git a/src/main/resources/application-postgres.properties b/src/main/resources/application-postgres.properties
new file mode 100644
index 000000000..60889b43c
--- /dev/null
+++ b/src/main/resources/application-postgres.properties
@@ -0,0 +1,6 @@
+database=postgres
+spring.datasource.url=${POSTGRES_URL:jdbc:postgresql://localhost/petclinic}
+spring.datasource.username=${POSTGRES_USER:petclinic}
+spring.datasource.password=${POSTGRES_PASS:petclinic}
+# SQL is written to be idempotent so this is safe
+spring.sql.init.mode=always
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index f7e7bc4a8..5d3eeed32 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,15 +1,7 @@
-#server
-server.port=9753
-
# database init, supports mysql too
-spring.datasource.driver-class-name=org.postgresql.Driver
-spring.sql.init.schema-locations=classpath*:db/postgres/schema.sql
-spring.sql.init.data-locations=classpath*:db/postgres/data.sql
-spring.datasource.url=jdbc:postgresql://localhost:5432/petclinic
-spring.datasource.username=postgres
-spring.datasource.password=admin
-# SQL is written to be idempotent so this is safe
-spring.sql.init.mode=always
+database=h2
+spring.sql.init.schema-locations=classpath*:db/${database}/schema.sql
+spring.sql.init.data-locations=classpath*:db/${database}/data.sql
# Web
spring.thymeleaf.mode=HTML
diff --git a/src/main/resources/db/h2/data.sql b/src/main/resources/db/h2/data.sql
new file mode 100644
index 000000000..f232b1361
--- /dev/null
+++ b/src/main/resources/db/h2/data.sql
@@ -0,0 +1,53 @@
+INSERT INTO vets VALUES (default, 'James', 'Carter');
+INSERT INTO vets VALUES (default, 'Helen', 'Leary');
+INSERT INTO vets VALUES (default, 'Linda', 'Douglas');
+INSERT INTO vets VALUES (default, 'Rafael', 'Ortega');
+INSERT INTO vets VALUES (default, 'Henry', 'Stevens');
+INSERT INTO vets VALUES (default, 'Sharon', 'Jenkins');
+
+INSERT INTO specialties VALUES (default, 'radiology');
+INSERT INTO specialties VALUES (default, 'surgery');
+INSERT INTO specialties VALUES (default, 'dentistry');
+
+INSERT INTO vet_specialties VALUES (2, 1);
+INSERT INTO vet_specialties VALUES (3, 2);
+INSERT INTO vet_specialties VALUES (3, 3);
+INSERT INTO vet_specialties VALUES (4, 2);
+INSERT INTO vet_specialties VALUES (5, 1);
+
+INSERT INTO types VALUES (default, 'cat');
+INSERT INTO types VALUES (default, 'dog');
+INSERT INTO types VALUES (default, 'lizard');
+INSERT INTO types VALUES (default, 'snake');
+INSERT INTO types VALUES (default, 'bird');
+INSERT INTO types VALUES (default, 'hamster');
+
+INSERT INTO owners VALUES (default, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023');
+INSERT INTO owners VALUES (default, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749');
+INSERT INTO owners VALUES (default, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763');
+INSERT INTO owners VALUES (default, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198');
+INSERT INTO owners VALUES (default, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765');
+INSERT INTO owners VALUES (default, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654');
+INSERT INTO owners VALUES (default, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387');
+INSERT INTO owners VALUES (default, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683');
+INSERT INTO owners VALUES (default, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435');
+INSERT INTO owners VALUES (default, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487');
+
+INSERT INTO pets VALUES (default, 'Leo', '2010-09-07', 1, 1);
+INSERT INTO pets VALUES (default, 'Basil', '2012-08-06', 6, 2);
+INSERT INTO pets VALUES (default, 'Rosy', '2011-04-17', 2, 3);
+INSERT INTO pets VALUES (default, 'Jewel', '2010-03-07', 2, 3);
+INSERT INTO pets VALUES (default, 'Iggy', '2010-11-30', 3, 4);
+INSERT INTO pets VALUES (default, 'George', '2010-01-20', 4, 5);
+INSERT INTO pets VALUES (default, 'Samantha', '2012-09-04', 1, 6);
+INSERT INTO pets VALUES (default, 'Max', '2012-09-04', 1, 6);
+INSERT INTO pets VALUES (default, 'Lucky', '2011-08-06', 5, 7);
+INSERT INTO pets VALUES (default, 'Mulligan', '2007-02-24', 2, 8);
+INSERT INTO pets VALUES (default, 'Freddy', '2010-03-09', 5, 9);
+INSERT INTO pets VALUES (default, 'Lucky', '2010-06-24', 2, 10);
+INSERT INTO pets VALUES (default, 'Sly', '2012-06-08', 1, 10);
+
+INSERT INTO visits VALUES (default, 7, '2013-01-01', 'rabies shot');
+INSERT INTO visits VALUES (default, 8, '2013-01-02', 'rabies shot');
+INSERT INTO visits VALUES (default, 8, '2013-01-03', 'neutered');
+INSERT INTO visits VALUES (default, 7, '2013-01-04', 'spayed');
diff --git a/src/main/resources/db/h2/schema.sql b/src/main/resources/db/h2/schema.sql
new file mode 100644
index 000000000..4a6c322cb
--- /dev/null
+++ b/src/main/resources/db/h2/schema.sql
@@ -0,0 +1,64 @@
+DROP TABLE vet_specialties IF EXISTS;
+DROP TABLE vets IF EXISTS;
+DROP TABLE specialties IF EXISTS;
+DROP TABLE visits IF EXISTS;
+DROP TABLE pets IF EXISTS;
+DROP TABLE types IF EXISTS;
+DROP TABLE owners IF EXISTS;
+
+
+CREATE TABLE vets (
+ id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
+ first_name VARCHAR(30),
+ last_name VARCHAR(30)
+);
+CREATE INDEX vets_last_name ON vets (last_name);
+
+CREATE TABLE specialties (
+ id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
+ name VARCHAR(80)
+);
+CREATE INDEX specialties_name ON specialties (name);
+
+CREATE TABLE vet_specialties (
+ vet_id INTEGER NOT NULL,
+ specialty_id INTEGER NOT NULL
+);
+ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets (id);
+ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties (id);
+
+CREATE TABLE types (
+ id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
+ name VARCHAR(80)
+);
+CREATE INDEX types_name ON types (name);
+
+CREATE TABLE owners (
+ id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
+ first_name VARCHAR(30),
+ last_name VARCHAR_IGNORECASE(30),
+ address VARCHAR(255),
+ city VARCHAR(80),
+ telephone VARCHAR(20)
+);
+CREATE INDEX owners_last_name ON owners (last_name);
+
+CREATE TABLE pets (
+ id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
+ name VARCHAR(30),
+ birth_date DATE,
+ type_id INTEGER NOT NULL,
+ owner_id INTEGER
+);
+ALTER TABLE pets ADD CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES owners (id);
+ALTER TABLE pets ADD CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types (id);
+CREATE INDEX pets_name ON pets (name);
+
+CREATE TABLE visits (
+ id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
+ pet_id INTEGER,
+ visit_date DATE,
+ description VARCHAR(255)
+);
+ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id);
+CREATE INDEX visits_pet_id ON visits (pet_id);
diff --git a/src/main/resources/db/hsqldb/data.sql b/src/main/resources/db/hsqldb/data.sql
new file mode 100644
index 000000000..16dda3e84
--- /dev/null
+++ b/src/main/resources/db/hsqldb/data.sql
@@ -0,0 +1,53 @@
+INSERT INTO vets VALUES (1, 'James', 'Carter');
+INSERT INTO vets VALUES (2, 'Helen', 'Leary');
+INSERT INTO vets VALUES (3, 'Linda', 'Douglas');
+INSERT INTO vets VALUES (4, 'Rafael', 'Ortega');
+INSERT INTO vets VALUES (5, 'Henry', 'Stevens');
+INSERT INTO vets VALUES (6, 'Sharon', 'Jenkins');
+
+INSERT INTO specialties VALUES (1, 'radiology');
+INSERT INTO specialties VALUES (2, 'surgery');
+INSERT INTO specialties VALUES (3, 'dentistry');
+
+INSERT INTO vet_specialties VALUES (2, 1);
+INSERT INTO vet_specialties VALUES (3, 2);
+INSERT INTO vet_specialties VALUES (3, 3);
+INSERT INTO vet_specialties VALUES (4, 2);
+INSERT INTO vet_specialties VALUES (5, 1);
+
+INSERT INTO types VALUES (1, 'cat');
+INSERT INTO types VALUES (2, 'dog');
+INSERT INTO types VALUES (3, 'lizard');
+INSERT INTO types VALUES (4, 'snake');
+INSERT INTO types VALUES (5, 'bird');
+INSERT INTO types VALUES (6, 'hamster');
+
+INSERT INTO owners VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023');
+INSERT INTO owners VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749');
+INSERT INTO owners VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763');
+INSERT INTO owners VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198');
+INSERT INTO owners VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765');
+INSERT INTO owners VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654');
+INSERT INTO owners VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387');
+INSERT INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683');
+INSERT INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435');
+INSERT INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487');
+
+INSERT INTO pets VALUES (1, 'Leo', '2010-09-07', 1, 1);
+INSERT INTO pets VALUES (2, 'Basil', '2012-08-06', 6, 2);
+INSERT INTO pets VALUES (3, 'Rosy', '2011-04-17', 2, 3);
+INSERT INTO pets VALUES (4, 'Jewel', '2010-03-07', 2, 3);
+INSERT INTO pets VALUES (5, 'Iggy', '2010-11-30', 3, 4);
+INSERT INTO pets VALUES (6, 'George', '2010-01-20', 4, 5);
+INSERT INTO pets VALUES (7, 'Samantha', '2012-09-04', 1, 6);
+INSERT INTO pets VALUES (8, 'Max', '2012-09-04', 1, 6);
+INSERT INTO pets VALUES (9, 'Lucky', '2011-08-06', 5, 7);
+INSERT INTO pets VALUES (10, 'Mulligan', '2007-02-24', 2, 8);
+INSERT INTO pets VALUES (11, 'Freddy', '2010-03-09', 5, 9);
+INSERT INTO pets VALUES (12, 'Lucky', '2010-06-24', 2, 10);
+INSERT INTO pets VALUES (13, 'Sly', '2012-06-08', 1, 10);
+
+INSERT INTO visits VALUES (1, 7, '2013-01-01', 'rabies shot');
+INSERT INTO visits VALUES (2, 8, '2013-01-02', 'rabies shot');
+INSERT INTO visits VALUES (3, 8, '2013-01-03', 'neutered');
+INSERT INTO visits VALUES (4, 7, '2013-01-04', 'spayed');
diff --git a/src/main/resources/db/hsqldb/schema.sql b/src/main/resources/db/hsqldb/schema.sql
new file mode 100644
index 000000000..5d6760a4b
--- /dev/null
+++ b/src/main/resources/db/hsqldb/schema.sql
@@ -0,0 +1,64 @@
+DROP TABLE vet_specialties IF EXISTS;
+DROP TABLE vets IF EXISTS;
+DROP TABLE specialties IF EXISTS;
+DROP TABLE visits IF EXISTS;
+DROP TABLE pets IF EXISTS;
+DROP TABLE types IF EXISTS;
+DROP TABLE owners IF EXISTS;
+
+
+CREATE TABLE vets (
+ id INTEGER IDENTITY PRIMARY KEY,
+ first_name VARCHAR(30),
+ last_name VARCHAR(30)
+);
+CREATE INDEX vets_last_name ON vets (last_name);
+
+CREATE TABLE specialties (
+ id INTEGER IDENTITY PRIMARY KEY,
+ name VARCHAR(80)
+);
+CREATE INDEX specialties_name ON specialties (name);
+
+CREATE TABLE vet_specialties (
+ vet_id INTEGER NOT NULL,
+ specialty_id INTEGER NOT NULL
+);
+ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets (id);
+ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties (id);
+
+CREATE TABLE types (
+ id INTEGER IDENTITY PRIMARY KEY,
+ name VARCHAR(80)
+);
+CREATE INDEX types_name ON types (name);
+
+CREATE TABLE owners (
+ id INTEGER IDENTITY PRIMARY KEY,
+ first_name VARCHAR(30),
+ last_name VARCHAR_IGNORECASE(30),
+ address VARCHAR(255),
+ city VARCHAR(80),
+ telephone VARCHAR(20)
+);
+CREATE INDEX owners_last_name ON owners (last_name);
+
+CREATE TABLE pets (
+ id INTEGER IDENTITY PRIMARY KEY,
+ name VARCHAR(30),
+ birth_date DATE,
+ type_id INTEGER NOT NULL,
+ owner_id INTEGER
+);
+ALTER TABLE pets ADD CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES owners (id);
+ALTER TABLE pets ADD CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types (id);
+CREATE INDEX pets_name ON pets (name);
+
+CREATE TABLE visits (
+ id INTEGER IDENTITY PRIMARY KEY,
+ pet_id INTEGER,
+ visit_date DATE,
+ description VARCHAR(255)
+);
+ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id);
+CREATE INDEX visits_pet_id ON visits (pet_id);
diff --git a/src/main/resources/db/mysql/data.sql b/src/main/resources/db/mysql/data.sql
new file mode 100644
index 000000000..3f1dcf8ea
--- /dev/null
+++ b/src/main/resources/db/mysql/data.sql
@@ -0,0 +1,53 @@
+INSERT IGNORE INTO vets VALUES (1, 'James', 'Carter');
+INSERT IGNORE INTO vets VALUES (2, 'Helen', 'Leary');
+INSERT IGNORE INTO vets VALUES (3, 'Linda', 'Douglas');
+INSERT IGNORE INTO vets VALUES (4, 'Rafael', 'Ortega');
+INSERT IGNORE INTO vets VALUES (5, 'Henry', 'Stevens');
+INSERT IGNORE INTO vets VALUES (6, 'Sharon', 'Jenkins');
+
+INSERT IGNORE INTO specialties VALUES (1, 'radiology');
+INSERT IGNORE INTO specialties VALUES (2, 'surgery');
+INSERT IGNORE INTO specialties VALUES (3, 'dentistry');
+
+INSERT IGNORE INTO vet_specialties VALUES (2, 1);
+INSERT IGNORE INTO vet_specialties VALUES (3, 2);
+INSERT IGNORE INTO vet_specialties VALUES (3, 3);
+INSERT IGNORE INTO vet_specialties VALUES (4, 2);
+INSERT IGNORE INTO vet_specialties VALUES (5, 1);
+
+INSERT IGNORE INTO types VALUES (1, 'cat');
+INSERT IGNORE INTO types VALUES (2, 'dog');
+INSERT IGNORE INTO types VALUES (3, 'lizard');
+INSERT IGNORE INTO types VALUES (4, 'snake');
+INSERT IGNORE INTO types VALUES (5, 'bird');
+INSERT IGNORE INTO types VALUES (6, 'hamster');
+
+INSERT IGNORE INTO owners VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023');
+INSERT IGNORE INTO owners VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749');
+INSERT IGNORE INTO owners VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763');
+INSERT IGNORE INTO owners VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198');
+INSERT IGNORE INTO owners VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765');
+INSERT IGNORE INTO owners VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654');
+INSERT IGNORE INTO owners VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387');
+INSERT IGNORE INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683');
+INSERT IGNORE INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435');
+INSERT IGNORE INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487');
+
+INSERT IGNORE INTO pets VALUES (1, 'Leo', '2000-09-07', 1, 1);
+INSERT IGNORE INTO pets VALUES (2, 'Basil', '2002-08-06', 6, 2);
+INSERT IGNORE INTO pets VALUES (3, 'Rosy', '2001-04-17', 2, 3);
+INSERT IGNORE INTO pets VALUES (4, 'Jewel', '2000-03-07', 2, 3);
+INSERT IGNORE INTO pets VALUES (5, 'Iggy', '2000-11-30', 3, 4);
+INSERT IGNORE INTO pets VALUES (6, 'George', '2000-01-20', 4, 5);
+INSERT IGNORE INTO pets VALUES (7, 'Samantha', '1995-09-04', 1, 6);
+INSERT IGNORE INTO pets VALUES (8, 'Max', '1995-09-04', 1, 6);
+INSERT IGNORE INTO pets VALUES (9, 'Lucky', '1999-08-06', 5, 7);
+INSERT IGNORE INTO pets VALUES (10, 'Mulligan', '1997-02-24', 2, 8);
+INSERT IGNORE INTO pets VALUES (11, 'Freddy', '2000-03-09', 5, 9);
+INSERT IGNORE INTO pets VALUES (12, 'Lucky', '2000-06-24', 2, 10);
+INSERT IGNORE INTO pets VALUES (13, 'Sly', '2002-06-08', 1, 10);
+
+INSERT IGNORE INTO visits VALUES (1, 7, '2010-03-04', 'rabies shot');
+INSERT IGNORE INTO visits VALUES (2, 8, '2011-03-04', 'rabies shot');
+INSERT IGNORE INTO visits VALUES (3, 8, '2009-06-04', 'neutered');
+INSERT IGNORE INTO visits VALUES (4, 7, '2008-09-04', 'spayed');
diff --git a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt
new file mode 100644
index 000000000..8b39c07a4
--- /dev/null
+++ b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt
@@ -0,0 +1,36 @@
+================================================================================
+=== Spring PetClinic sample application - MySQL Configuration ===
+================================================================================
+
+@author Sam Brannen
+@author Costin Leau
+@author Dave Syer
+
+--------------------------------------------------------------------------------
+
+1) Download and install the MySQL database (e.g., MySQL Community Server 5.1.x),
+ which can be found here: https://dev.mysql.com/downloads/. Or run the
+ "docker-compose.yml" from the root of the project (if you have docker installed
+ locally):
+
+ $ docker-compose up
+ ...
+ mysql_1_eedb4818d817 | MySQL init process done. Ready for start up.
+ ...
+
+2) (Once only) create the PetClinic database and user by executing the "db/mysql/user.sql"
+ scripts. You can connect to the database running in the docker container using
+ `mysql -u root -h localhost --protocol tcp`, but you don't need to run the script there
+ because the petclinic user is already set up if you use the provided `docker-compose.yml`.
+
+3) Run the app with `spring.profiles.active=mysql` (e.g. as a System property via the command
+ line, but any way that sets that property in a Spring Boot app should work). For example use
+
+ mvn spring-boot:run -Dspring-boot.run.profiles=mysql
+
+ To activate the profile on the command line.
+
+N.B. the "petclinic" database has to exist for the app to work with the JDBC URL value
+as it is configured by default. This condition is taken care of automatically by the
+docker-compose configuration provided, or by the `user.sql` script if you run that as
+root.
diff --git a/src/main/resources/db/mysql/schema.sql b/src/main/resources/db/mysql/schema.sql
new file mode 100644
index 000000000..2591a516d
--- /dev/null
+++ b/src/main/resources/db/mysql/schema.sql
@@ -0,0 +1,55 @@
+CREATE TABLE IF NOT EXISTS vets (
+ id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ first_name VARCHAR(30),
+ last_name VARCHAR(30),
+ INDEX(last_name)
+) engine=InnoDB;
+
+CREATE TABLE IF NOT EXISTS specialties (
+ id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(80),
+ INDEX(name)
+) engine=InnoDB;
+
+CREATE TABLE IF NOT EXISTS vet_specialties (
+ vet_id INT(4) UNSIGNED NOT NULL,
+ specialty_id INT(4) UNSIGNED NOT NULL,
+ FOREIGN KEY (vet_id) REFERENCES vets(id),
+ FOREIGN KEY (specialty_id) REFERENCES specialties(id),
+ UNIQUE (vet_id,specialty_id)
+) engine=InnoDB;
+
+CREATE TABLE IF NOT EXISTS types (
+ id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(80),
+ INDEX(name)
+) engine=InnoDB;
+
+CREATE TABLE IF NOT EXISTS owners (
+ id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ first_name VARCHAR(30),
+ last_name VARCHAR(30),
+ address VARCHAR(255),
+ city VARCHAR(80),
+ telephone VARCHAR(20),
+ INDEX(last_name)
+) engine=InnoDB;
+
+CREATE TABLE IF NOT EXISTS pets (
+ id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(30),
+ birth_date DATE,
+ type_id INT(4) UNSIGNED NOT NULL,
+ owner_id INT(4) UNSIGNED,
+ INDEX(name),
+ FOREIGN KEY (owner_id) REFERENCES owners(id),
+ FOREIGN KEY (type_id) REFERENCES types(id)
+) engine=InnoDB;
+
+CREATE TABLE IF NOT EXISTS visits (
+ id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ pet_id INT(4) UNSIGNED,
+ visit_date DATE,
+ description VARCHAR(255),
+ FOREIGN KEY (pet_id) REFERENCES pets(id)
+) engine=InnoDB;
diff --git a/src/main/resources/db/mysql/user.sql b/src/main/resources/db/mysql/user.sql
new file mode 100644
index 000000000..d2c7b88a0
--- /dev/null
+++ b/src/main/resources/db/mysql/user.sql
@@ -0,0 +1,7 @@
+CREATE DATABASE IF NOT EXISTS petclinic;
+
+ALTER DATABASE petclinic
+ DEFAULT CHARACTER SET utf8
+ DEFAULT COLLATE utf8_general_ci;
+
+GRANT ALL PRIVILEGES ON petclinic.* TO 'petclinic'@'%' IDENTIFIED BY 'petclinic';