diff --git a/README.md b/README.md
index 05e5cc88..93bb7a24 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,7 @@
# 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
+##Using H2 and Oracle for a Spring Boot Web Application
+
+How to use H2 and Oracle with a Spring Boot Web Application using Spring Framework profiles.
+
+You can see the full blog post about using Spring Boot with H2 and Oracle at [Spring Framework Guru](https://springframework.guru/using-h2-and-oracle-with-spring-boot/)
+
diff --git a/pom.xml b/pom.xml
index 575dff6a..afb019a0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,12 +40,29 @@
org.springframework.bootspring-boot-starter-web
-
+
+
+
+ org.webjars
+ bootstrap
+ 3.3.4
+
+
+ org.webjars
+ jquery
+ 2.1.4
+
+
com.h2databaseh2
- runtime
+
+
+ com.oracle
+ ojdbc6
+ 11.2.0.3.0
+ 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..3246fead
--- /dev/null
+++ b/src/main/java/guru/springframework/bootstrap/ProductLoader.java
@@ -0,0 +1,53 @@
+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) {
+
+ long productCount = productRepository.count();
+
+ log.info("Product Count is:" + productCount);
+
+ if(productCount == 0){
+ 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/OracleConfiguration.java b/src/main/java/guru/springframework/configuration/OracleConfiguration.java
new file mode 100644
index 00000000..f49b1221
--- /dev/null
+++ b/src/main/java/guru/springframework/configuration/OracleConfiguration.java
@@ -0,0 +1,48 @@
+package guru.springframework.configuration;
+
+import oracle.jdbc.pool.OracleDataSource;
+import org.springframework.context.annotation.Bean;
+
+import javax.sql.DataSource;
+import javax.validation.constraints.NotNull;
+import java.sql.SQLException;
+
+/**
+ * Un-comment the annoations to use the Oracle Java config
+ */
+//@Configuration
+//@ConfigurationProperties("oracle")
+public class OracleConfiguration {
+ @NotNull
+ private String username;
+
+ @NotNull
+ private String password;
+
+ @NotNull
+ private String url;
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ @Bean
+ DataSource dataSource() throws SQLException {
+
+ OracleDataSource dataSource = new OracleDataSource();
+ dataSource.setUser(username);
+ dataSource.setPassword(password);
+ dataSource.setURL(url);
+ dataSource.setImplicitCachingEnabled(true);
+ dataSource.setFastConnectionFailoverEnabled(true);
+ return dataSource;
+ }
+}
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..3e8f09b9
--- /dev/null
+++ b/src/main/java/guru/springframework/controllers/ProductController.java
@@ -0,0 +1,58 @@
+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());
+ 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();
+ }
+
+ @RequestMapping("product/delete/{id}")
+ public String delete(@PathVariable Integer id){
+ productService.deleteProduct(id);
+ return "redirect:/products";
+ }
+
+}
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..07a57c5e
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/Product.java
@@ -0,0 +1,68 @@
+package guru.springframework.domain;
+
+import javax.persistence.*;
+import java.math.BigDecimal;
+
+@Entity
+public class Product {
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "prooduct_id_seq")
+ @SequenceGenerator(name="prooduct_id_seq", sequenceName = "PRODUCT_ID_SEQ", allocationSize = 100)
+ 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..9c68033a
--- /dev/null
+++ b/src/main/java/guru/springframework/services/ProductService.java
@@ -0,0 +1,14 @@
+package guru.springframework.services;
+
+
+import guru.springframework.domain.Product;
+
+public interface ProductService {
+ Iterable listAllProducts();
+
+ Product getProductById(Integer id);
+
+ Product saveProduct(Product product);
+
+ void deleteProduct(Integer id);
+}
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..6fa75430
--- /dev/null
+++ b/src/main/java/guru/springframework/services/ProductServiceImpl.java
@@ -0,0 +1,36 @@
+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);
+ }
+
+ @Override
+ public void deleteProduct(Integer id) {
+ productRepository.delete(id);
+ }
+}
diff --git a/src/main/resources/application-h2.properties b/src/main/resources/application-h2.properties
new file mode 100644
index 00000000..74765ccf
--- /dev/null
+++ b/src/main/resources/application-h2.properties
@@ -0,0 +1,4 @@
+spring.datasource.url=jdbc:h2:mem:testdb;Mode=Oracle
+spring.datasource.platform=h2
+spring.jpa.hibernate.ddl-auto=none
+spring.datasource.continue-on-error=true
\ No newline at end of file
diff --git a/src/main/resources/application-oracle.properties b/src/main/resources/application-oracle.properties
new file mode 100644
index 00000000..cef95dbc
--- /dev/null
+++ b/src/main/resources/application-oracle.properties
@@ -0,0 +1,8 @@
+spring.jpa.hibernate.ddl-auto=validate
+
+#Basic Spring Boot Config for Oracle
+spring.datasource.url=jdbc:oracle:thin:@//springframework.guru.csi0i9rgj9ws.us-east-1.rds.amazonaws.com:1521/ORCL
+spring.datasource.username=scott
+spring.datasource.password=tiger
+spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
+
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index e69de29b..69014abb 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -0,0 +1,3 @@
+spring.profiles.active=oracle
+
+spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
\ No newline at end of file
diff --git a/src/main/resources/schema-h2.sql b/src/main/resources/schema-h2.sql
new file mode 100644
index 00000000..18d91d6a
--- /dev/null
+++ b/src/main/resources/schema-h2.sql
@@ -0,0 +1,19 @@
+DROP TABLE PRODUCT;
+
+CREATE TABLE PRODUCT (
+ID NUMBER(10,0) NOT NULL AUTO_INCREMENT,
+DESCRIPTION VARCHAR2(255) DEFAULT NULL,
+IMAGE_URL VARCHAR2(255) DEFAULT NULL,
+PRICE NUMBER(19,2) DEFAULT NULL,
+PRODUCT_ID VARCHAR2(255) DEFAULT NULL,
+VERSION NUMBER(10, 0) DEFAULT NULL,
+PRIMARY KEY (ID));
+
+DROP SEQUENCE PRODUCT_ID_SEQ;
+
+CREATE SEQUENCE PRODUCT_ID_SEQ
+ MINVALUE 1
+ MAXVALUE 9999999999999999
+ START WITH 1
+ INCREMENT BY 100
+ CACHE 100;
\ 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..61de20b0
--- /dev/null
+++ b/src/main/resources/templates/fragments/header.html
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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..cea3803b
--- /dev/null
+++ b/src/main/resources/templates/productform.html
@@ -0,0 +1,44 @@
+
+
+
+
+ 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..4e6124d2
--- /dev/null
+++ b/src/main/resources/templates/products.html
@@ -0,0 +1,39 @@
+
+
+
+
+ Spring Framework Guru
+
+
+
+
+