diff --git a/README.md b/README.md
index 05e5cc88..76ac4a7b 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,3 @@
# Spring Boot Web Application
-This repository has the project files for a tutorial series on Spring Boot available from by website at [Spring Framework Guru](https://springframework.guru)
\ No newline at end of file
+## Configuring Spring Boot for MySQL
+This repository has the project files for a blog post about configuring Spring Boot to work with MySQL. You can find the full post on my website [Spring Framework Guru](https://springframework.guru/configuring-spring-boot-for-mysql/)
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 575dff6a..4fbf4107 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,12 +40,27 @@
org.springframework.bootspring-boot-starter-web
-
+
+
+
+ org.webjars
+ bootstrap
+ 3.3.4
+
+
+ org.webjars
+ jquery
+ 2.1.4
+
+
com.h2databaseh2
- runtime
+
+ mysql
+ mysql-connector-java
+ org.springframework.bootspring-boot-starter-test
diff --git a/src/main/java/guru/springframework/bootstrap/ProductLoader.java b/src/main/java/guru/springframework/bootstrap/ProductLoader.java
new file mode 100644
index 00000000..0120eba2
--- /dev/null
+++ b/src/main/java/guru/springframework/bootstrap/ProductLoader.java
@@ -0,0 +1,46 @@
+package guru.springframework.bootstrap;
+
+import guru.springframework.domain.Product;
+import guru.springframework.repositories.ProductRepository;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+
+@Component
+public class ProductLoader implements ApplicationListener {
+
+ private ProductRepository productRepository;
+
+ private Logger log = Logger.getLogger(ProductLoader.class);
+
+ @Autowired
+ public void setProductRepository(ProductRepository productRepository) {
+ this.productRepository = productRepository;
+ }
+
+ @Override
+ public void onApplicationEvent(ContextRefreshedEvent event) {
+
+ Product shirt = new Product();
+ shirt.setDescription("Spring Framework Guru Shirt");
+ shirt.setPrice(new BigDecimal("18.95"));
+ shirt.setImageUrl("https://springframework.guru/wp-content/uploads/2015/04/spring_framework_guru_shirt-rf412049699c14ba5b68bb1c09182bfa2_8nax2_512.jpg");
+ shirt.setProductId("235268845711068308");
+ productRepository.save(shirt);
+
+ log.info("Saved Shirt - id: " + shirt.getId());
+
+ Product mug = new Product();
+ mug.setDescription("Spring Framework Guru Mug");
+ mug.setImageUrl("https://springframework.guru/wp-content/uploads/2015/04/spring_framework_guru_coffee_mug-r11e7694903c348e1a667dfd2f1474d95_x7j54_8byvr_512.jpg");
+ mug.setProductId("168639393495335947");
+ mug.setPrice(new BigDecimal("11.95"));
+ productRepository.save(mug);
+
+ log.info("Saved Mug - id:" + mug.getId());
+ }
+}
diff --git a/src/main/java/guru/springframework/configuration/SecurityConfiguration.java b/src/main/java/guru/springframework/configuration/SecurityConfiguration.java
new file mode 100644
index 00000000..87c00b72
--- /dev/null
+++ b/src/main/java/guru/springframework/configuration/SecurityConfiguration.java
@@ -0,0 +1,19 @@
+package guru.springframework.configuration;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@Configuration
+public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(HttpSecurity httpSecurity) throws Exception {
+ httpSecurity.authorizeRequests().antMatchers("/").permitAll().and()
+ .authorizeRequests().antMatchers("/console/**").permitAll();
+
+ httpSecurity.csrf().disable();
+ httpSecurity.headers().frameOptions().disable();
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/guru/springframework/configuration/WebConfiguration.java b/src/main/java/guru/springframework/configuration/WebConfiguration.java
new file mode 100644
index 00000000..6d4567c0
--- /dev/null
+++ b/src/main/java/guru/springframework/configuration/WebConfiguration.java
@@ -0,0 +1,16 @@
+package guru.springframework.configuration;
+
+import org.h2.server.web.WebServlet;
+import org.springframework.boot.context.embedded.ServletRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class WebConfiguration {
+ @Bean
+ ServletRegistrationBean h2servletRegistration(){
+ ServletRegistrationBean registrationBean = new ServletRegistrationBean( new WebServlet());
+ registrationBean.addUrlMappings("/console/*");
+ return registrationBean;
+ }
+}
diff --git a/src/main/java/guru/springframework/controllers/IndexController.java b/src/main/java/guru/springframework/controllers/IndexController.java
new file mode 100644
index 00000000..95280b66
--- /dev/null
+++ b/src/main/java/guru/springframework/controllers/IndexController.java
@@ -0,0 +1,12 @@
+package guru.springframework.controllers;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+public class IndexController {
+ @RequestMapping("/")
+ String index(){
+ return "index";
+ }
+}
diff --git a/src/main/java/guru/springframework/controllers/ProductController.java b/src/main/java/guru/springframework/controllers/ProductController.java
new file mode 100644
index 00000000..57a89f76
--- /dev/null
+++ b/src/main/java/guru/springframework/controllers/ProductController.java
@@ -0,0 +1,55 @@
+package guru.springframework.controllers;
+
+import guru.springframework.domain.Product;
+import guru.springframework.services.ProductService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+@Controller
+public class ProductController {
+
+ private ProductService productService;
+
+ @Autowired
+ public void setProductService(ProductService productService) {
+ this.productService = productService;
+ }
+
+ @RequestMapping(value = "/products", method = RequestMethod.GET)
+ public String list(Model model){
+ model.addAttribute("products", productService.listAllProducts());
+ System.out.println("Returning products:");
+ return "products";
+ }
+
+ @RequestMapping("product/{id}")
+ public String showProduct(@PathVariable Integer id, Model model){
+ model.addAttribute("product", productService.getProductById(id));
+ return "productshow";
+ }
+
+ @RequestMapping("product/edit/{id}")
+ public String edit(@PathVariable Integer id, Model model){
+ model.addAttribute("product", productService.getProductById(id));
+ return "productform";
+ }
+
+ @RequestMapping("product/new")
+ public String newProduct(Model model){
+ model.addAttribute("product", new Product());
+ return "productform";
+ }
+
+ @RequestMapping(value = "product", method = RequestMethod.POST)
+ public String saveProduct(Product product){
+
+ productService.saveProduct(product);
+
+ return "redirect:/product/" + product.getId();
+ }
+
+}
diff --git a/src/main/java/guru/springframework/domain/Product.java b/src/main/java/guru/springframework/domain/Product.java
new file mode 100644
index 00000000..a40c7045
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/Product.java
@@ -0,0 +1,67 @@
+package guru.springframework.domain;
+
+import javax.persistence.*;
+import java.math.BigDecimal;
+
+@Entity
+public class Product {
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Integer id;
+
+ @Version
+ private Integer version;
+
+ private String productId;
+ private String description;
+ private String imageUrl;
+ private BigDecimal price;
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Integer getVersion() {
+ return version;
+ }
+
+ public void setVersion(Integer version) {
+ this.version = version;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getProductId() {
+ return productId;
+ }
+
+ public void setProductId(String productId) {
+ this.productId = productId;
+ }
+
+ public String getImageUrl() {
+ return imageUrl;
+ }
+
+ public void setImageUrl(String imageUrl) {
+ this.imageUrl = imageUrl;
+ }
+
+ public BigDecimal getPrice() {
+ return price;
+ }
+
+ public void setPrice(BigDecimal price) {
+ this.price = price;
+ }
+}
diff --git a/src/main/java/guru/springframework/repositories/ProductRepository.java b/src/main/java/guru/springframework/repositories/ProductRepository.java
new file mode 100644
index 00000000..820f086a
--- /dev/null
+++ b/src/main/java/guru/springframework/repositories/ProductRepository.java
@@ -0,0 +1,7 @@
+package guru.springframework.repositories;
+
+import guru.springframework.domain.Product;
+import org.springframework.data.repository.CrudRepository;
+
+public interface ProductRepository extends CrudRepository{
+}
diff --git a/src/main/java/guru/springframework/services/ProductService.java b/src/main/java/guru/springframework/services/ProductService.java
new file mode 100644
index 00000000..f144809b
--- /dev/null
+++ b/src/main/java/guru/springframework/services/ProductService.java
@@ -0,0 +1,12 @@
+package guru.springframework.services;
+
+
+import guru.springframework.domain.Product;
+
+public interface ProductService {
+ Iterable listAllProducts();
+
+ Product getProductById(Integer id);
+
+ Product saveProduct(Product product);
+}
diff --git a/src/main/java/guru/springframework/services/ProductServiceImpl.java b/src/main/java/guru/springframework/services/ProductServiceImpl.java
new file mode 100644
index 00000000..5fd4e7fd
--- /dev/null
+++ b/src/main/java/guru/springframework/services/ProductServiceImpl.java
@@ -0,0 +1,31 @@
+package guru.springframework.services;
+
+import guru.springframework.domain.Product;
+import guru.springframework.repositories.ProductRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ProductServiceImpl implements ProductService {
+ private ProductRepository productRepository;
+
+ @Autowired
+ public void setProductRepository(ProductRepository productRepository) {
+ this.productRepository = productRepository;
+ }
+
+ @Override
+ public Iterable listAllProducts() {
+ return productRepository.findAll();
+ }
+
+ @Override
+ public Product getProductById(Integer id) {
+ return productRepository.findOne(id);
+ }
+
+ @Override
+ public Product saveProduct(Product product) {
+ return productRepository.save(product);
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index e69de29b..31aa559c 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -0,0 +1,7 @@
+#logging.level.org.h2.server: DEBUG
+# Database
+spring.datasource.url= jdbc:mysql://localhost:3306/springbootdb
+spring.datasource.username=root
+spring.datasource.password=
+
+spring.jpa.hibernate.ddl-auto=create-drop
\ No newline at end of file
diff --git a/src/main/resources/static/css/guru.css b/src/main/resources/static/css/guru.css
new file mode 100644
index 00000000..e69de29b
diff --git a/src/main/resources/static/images/FBcover1200x628.png b/src/main/resources/static/images/FBcover1200x628.png
new file mode 100644
index 00000000..d28620ad
Binary files /dev/null and b/src/main/resources/static/images/FBcover1200x628.png differ
diff --git a/src/main/resources/static/images/NewBannerBOOTS_2.png b/src/main/resources/static/images/NewBannerBOOTS_2.png
new file mode 100644
index 00000000..e6b7ea3d
Binary files /dev/null and b/src/main/resources/static/images/NewBannerBOOTS_2.png differ
diff --git a/src/main/resources/templates/fragments/header.html b/src/main/resources/templates/fragments/header.html
new file mode 100644
index 00000000..3c6e4616
--- /dev/null
+++ b/src/main/resources/templates/fragments/header.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Spring Framework Guru
+
+
Spring Boot Web App
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/fragments/headerinc.html b/src/main/resources/templates/fragments/headerinc.html
new file mode 100644
index 00000000..57b18037
--- /dev/null
+++ b/src/main/resources/templates/fragments/headerinc.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html
new file mode 100644
index 00000000..99830d5e
--- /dev/null
+++ b/src/main/resources/templates/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+ Spring Framework Guru
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/productform.html b/src/main/resources/templates/productform.html
new file mode 100644
index 00000000..1fd5d598
--- /dev/null
+++ b/src/main/resources/templates/productform.html
@@ -0,0 +1,50 @@
+
+
+
+
+ Spring Framework Guru
+
+
+
+
+
+
+
+
Product Details
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/products.html b/src/main/resources/templates/products.html
new file mode 100644
index 00000000..13688b43
--- /dev/null
+++ b/src/main/resources/templates/products.html
@@ -0,0 +1,37 @@
+
+
+
+
+ Spring Framework Guru
+
+
+
+
+