Spring boot + Gradle + Thymeleaf + Jpa + Mysql Uygulaması

Posted by dogukanhan on June 02, 2018 · 5 mins read

1. Özet

Bu yazı boyunca bir spring boot uygulamasını Thymeleaf ve Jpa kullanarak gerçekleştireceğiz. Projemizi oluşturmak için Gradle kullanıcağız.

2. Uygulama Dosyaları

build.gradle

buildscript {
    ext {
        springBootVersion = '2.0.2.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.dogukanhan'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
    mavenCentral()
}
dependencies {
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-security')
    compile('org.springframework.boot:spring-boot-starter-thymeleaf')
    compile('org.springframework.boot:spring-boot-starter-web')
    runtime('org.springframework.boot:spring-boot-devtools')
    runtime('mysql:mysql-connector-java')
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.springframework.security:spring-security-test')
}

settings.gradle

rootProject.name = 'spring101'

Dosyaları oluşturduktan sonra “gradle build” komutunu girelim

Proje yapısı ve src klasörünün içeriği şekildeki gibi olucaktır. Oluşturulmayan klasörleri ve dosyaları kendimiz oluşturalım veya yazının sonunda yer alan linkten indirebilirsiniz.

WebApp.java

package com.dogukanhan.spring101;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan("com.dogukanhan.spring101*")
public class WebApp {
    public static void main(String[] args) {
        SpringApplication.run(WebApp.class, args);
    }
}

WebMvcConfig.java

package com.dogukanhan.spring101.configuration;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    private ApplicationContext applicationContext;


    @Bean
    public SpringResourceTemplateResolver templateResolver() {
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setApplicationContext(applicationContext);
        templateResolver.setPrefix("/WEB-INF/views/");
        templateResolver.setSuffix(".html");
        templateResolver.setCacheable(false);
        return templateResolver;
    }

    /*
     * STEP 2 - Create SpringTemplateEngine
     * */
    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver());
        templateEngine.setEnableSpringELCompiler(true);
        return templateEngine;
    }


    /*
     * STEP 3 - Register ThymeleafViewResolver
     * */
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateEngine(templateEngine());
        registry.viewResolver(resolver);
    }


}

PersistenceJPAConfig.java

package com.dogukanhan.spring101.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@EnableTransactionManagement

public class PersistenceJPAConfig {
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em
                = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan(new String[]{"com.dogukanhan.spring101.entity"});

        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());

        return em;
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://172.17.0.1:3306/spring101");
        ds.setUsername("root");
        ds.setPassword("my-secret-pw");
        return ds;
    }

    @Bean
    public PlatformTransactionManager transactionManager(
            EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);

        return transactionManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
        properties.setProperty(
                "hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");

        return properties;
    }
}

HomeController.java

package com.dogukanhan.spring101.controller;

import com.dogukanhan.spring101.FormCommand;
import com.dogukanhan.spring101.entity.Post;
import com.dogukanhan.spring101.repository.PostRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.List;

@Controller
public class HomeController {

@Autowired
private PostRepository postRepository;

@ModelAttribute("formCommand")
public FormCommand formCommand() {
return new FormCommand();
}

@GetMapping("/")
public String index(Model model) {
List<Post> posts = postRepository.findAll();
model.addAttribute("posts", posts);
return "index";
}

@GetMapping("/new")
public String newpost(Model model) {
List<Post> posts = postRepository.findAll();
model.addAttribute("posts", posts);
return "new";
}

@PostMapping("/new")
public String processSubmit(Model model,@ModelAttribute FormCommand formCommand) {
Post post = new Post();
post.setContent(formCommand.getContent());
post.setTitle(formCommand.getTitle());
post.setSender(formCommand.getSender());
postRepository.save(post);
model.addAttribute("post",post);
return "new";
}

@GetMapping("/delete/{id}")
public String newpost(Model model, @PathVariable long id) {
postRepository.deleteById(id);
return "delete";
}
}

FormCommand.java

package com.dogukanhan.spring101;

public class FormCommand {
    private String sender, title, content;

    public String getSender() {
        return sender;
    }

    public void setSender(String sender) {
        this.sender = sender;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Spring Example</title>
</head>
<body>
<a th:href="@{/new}"> Create New Post </a>
<h2>Posts</h2>
<ul>
    <li th:each="post: ${posts}">
        <div th:text="${post.title} +' | ' + ${post.sender} "> Post List</div>
        <a th:href="@{/delete/}+${post.ID}"> Del </a>
    </li>
</ul>
</body>
</html>

new.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Spring Example</title>
</head>
<body>
    <div th:if="${post}">
        <div th:text="'Post is created id = ' +  ${post.ID}"> Post is created </div>
    </div>
    <div th:unless="${post}">
    <form action="#" th:action="@{/new}" th:object="${formCommand}" method="post">
        <p>Sender: <input type="text" th:field="*{sender}" /></p>
        <p>Title: <input type="text" th:field="*{title}" /></p>
        <p>Content: <textarea th:field="*{content}" ></textarea></p>
        <input type="submit"/>
    </form>
    </div>
</body>
</html>

##