codestory

Die Anleitung zu Spring Boot und Spring Data JPA

View more Tutorials:

Kostenlose Website zum Sprachenlernen:
Folge uns auf unserer fanpage, um jedes Mal benachrichtigt zu werden, wenn es neue Artikel gibt. Facebook

1- Das Projekt Spring Boot erstellen

Auf Eclipse erstellen Sie ein Projekt Spring Boot.
Wählen Sie die im Projekt verwendeten Technologies, einschließend JPA und eine Databank, an die Sie sich gewöhnen.
Fügen Sie das folgende Konfigurationsstück in die File pom.xml ein wenn Sie mit der Datenbank Oracle arbeiten möchten:
** Oracle **

<dependencies>
   <dependency>
      <groupId>com.oracle</groupId>
      <artifactId>ojdbc7</artifactId>
      <version>12.1.0.2</version>
   </dependency>
</dependencies>

<repositories>
   <!-- Repository for ORACLE ojdbc6. -->
   <repository>
      <id>codelds</id>
      <url>https://code.lds.org/nexus/content/groups/main-repo</url>
   </repository>
</repositories>
Die volle Inhalt der File pom.xml:
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
     http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>SpringBootDataJPA</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>SpringBootDataJPA</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc7</artifactId>
            <version>12.1.0.2</version>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <repositories>
        <!-- Repository for ORACLE ojdbc6. -->
        <repository>
            <id>codelds</id>
            <url>https://code.lds.org/nexus/content/groups/main-repo</url>
        </repository>
    </repositories>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
SpringBootDataJpaApplication.java

package org.o7planning.sbdatajpa;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootDataJpaApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootDataJpaApplication.class, args);
    }
    
}

2- Spring Boot & JPA konfigurieren

Damit Spring Boot in die Datenbank verbinden kann, sollen Sie in die File applications.properties konfigurieren. Sie können irgendeine Datenbank, an die Sie sich gewöhnnen. Unter sind die 4 Konfiguration, die 4 üblichen Datenbanken entsprechen (MySQL, Oracle, SQL Server, PostGres).
Im Praxis erstellen Sie eine leere Datenbank (leeres Schema) mit dem Name von "mydatabase". JPA erstellt die in der Applikation Entity entsprechenden Tabelle.
application.properties (MySQL)

# ===============================
# DATABASE
# ===============================

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase
spring.datasource.username=root
spring.datasource.password=12345

# ===============================
# JPA / HIBERNATE
# ===============================

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
application.properties (Oracle)

# ===============================
# DATABASE
# ===============================

spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver

spring.datasource.url=jdbc:oracle:thin:@localhost:1521:db12c
spring.datasource.username=mydatabase
spring.datasource.password=12345


# ===============================
# JPA / HIBERNATE
# ===============================

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
application.properties (SQL Server)

# ===============================
# DATABASE
# ===============================

spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.url=jdbc:sqlserver://localhost\\SQLEXPRESS:1433;databaseName=mydatabase
spring.datasource.username=sa
spring.datasource.password=12345


# ===============================
# JPA / HIBERNATE
# ===============================

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
application.properties (PostGres)

# ===============================
# DATABASE CONNECTION
# ===============================

spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/mydatabase
spring.datasource.username=postgres
spring.datasource.password=12345

# ===============================
# JPA / HIBERNATE
# ===============================

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect


# Fix Postgres JPA Error:
# Method org.postgresql.jdbc.PgConnection.createClob() is not yet implemented.
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false

3- Spring Data JPA (Quick Start)

In JPA entspricht jede Klasse Entity einer Tabelle in der Datenbank. Es gibt viele Tabelle in der Datenbank deshalb gibt es viele Klasse Entity. Sie arbeiten oft mit Entity, und müssen die Klasse DAO (Data Access Object) schreiben um durch Entity die Daten zu manipulieren. Das ist wirklich eine langweilige Arbeit
OK, Ich werde Sie sagen warum es langweilig ist. Stellen Sie sich vor, Sie haben in der Datenbank 2 Tabelle EMPLOYEE & DEPARTMENT, und Sie haben 2 entsprechenden Klasse Entity  Employee & Department.
Um mit Employee zu manipulieren, schreiben Sie eine Klasse DAO , die die ähnlichen Methode wie folgend umfasst:
  • Employee findById(Long id)
  • List<Employee> findAll()
  • List<Employee> findByName(String likeName)
  • .....
     
Natürlich zur Manipulierung mit Department machen Sie auch das ähnliche Ding. Und wenn die Anzahl von Entity zu viel ist, kostet es Ihre Zeit mehr
Spring Data JPA ist eine Bibliothek vom Spring. Nach dem Grundsatz vom Spring Data JPA brauchen Sie eine ausgeweiterte Interface - die Interface Repository<T,ID> definieren und deklarieren den Name der Methode mit Daten von diesem Entity. Spring Data JPA erstellt selbst eine Klasse, die diese Interface für Sie implementiert
Employee.java

package org.o7planning.sbdatajpa.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

    @Id
    private Long id;

    @Column(name = "Emp_No", length = 30, nullable = false)
    private String empNo;

    @Column(name = "Full_Name", length = 128, nullable = false)
    private String fullName;

    @Temporal(TemporalType.DATE)
    @Column(name = "Hire_Date", nullable = false)
    private Date hireDate;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getEmpNo() {
        return empNo;
    }

    public void setEmpNo(String empNo) {
        this.empNo = empNo;
    }

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }

    public Date getHireDate() {
        return hireDate;
    }

    public void setHireDate(Date hireDate) {
        this.hireDate = hireDate;
    }

    @Override
    public String toString() {
        return this.getEmpNo() + ", " + this.getFullName();
    }

}
Die Interface EmployeeRepository verlängert die Interface CrudRepository<Employee, Long>,. Sie hat die Methode um mit der entity Employee zu manipulieren. Spring Data JPA wird automatisch eine Klasse erstellen, die bei dem Runtime von Applikation diese Interface implementiert
EmployeeRepository.java

package org.o7planning.sbdatajpa.repository;

import java.util.Date;
import java.util.List;

import org.o7planning.sbdatajpa.entity.Employee;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;

// This is an Interface.
// No need Annotation here.
public interface EmployeeRepository extends CrudRepository<Employee, Long> { // Long: Type of Employee ID.

    Employee findByEmpNo(String empNo);

    List<Employee> findByFullNameLike(String fullName);

    List<Employee> findByHireDateGreaterThan(Date hireDate);

    @Query("SELECT coalesce(max(e.id), 0) FROM Employee e")
    Long getMaxId();

}
Spring Data JPA wird die Kode für Ihre abstrakte Methode schreiben. So sollen Sie Spring Data JPA sagen, was Sie durch den Name der Methode möchten.
Keyword Sample Equivalent to
GreaterThan findByAgeGreaterThan(int age) Select e from Person e where e.age > :age
LessThan findByAgeLessThan(int age) Select e from Person e where e.age < :age
Between findByAgeBetween(int from, int to) Select e from Person e where e.age between :from and :to
IsNotNull, NotNull findByFirstnameNotNull() Select e from Person e where e.firstname is not null
IsNull, Null findByFirstnameNull() Select e from Person e where e.firstname is null
Like findByFirstnameLike(String name) Select e from Person e where e.firstname like :name
(No keyword) findByFirstname(String name) Select e from Person e where e.firstname = :name
Not findByFirstnameNot(String name) Select e from Person e where e.firstname <> :name
 .....    
Außerdem können Sie die Interface mit der anpassenden Methode erstellen. In dieser Situation müssen Sie die Klasse schreiben um die solche Interface zu implementieren
EmployeeRepositoryCustom.java

package org.o7planning.sbdatajpa.repository;

import java.util.Date;

public interface EmployeeRepositoryCustom {
    
    public Long getMaxEmpId();

    public long updateEmployee(Long empId, String fullName, Date hireDate);

}
EmployeeRepositoryCustomImpl.java

package org.o7planning.sbdatajpa.repository;

import java.util.Date;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;

import org.o7planning.sbdatajpa.entity.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class EmployeeRepositoryCustomImpl implements EmployeeRepositoryCustom {

    @Autowired
    EntityManager entityManager;

    @Override
    public Long getMaxEmpId() {
        try {
            String sql = "SELECT coalesce(max(e.id), 0) FROM Employee e";
            Query query = entityManager.createQuery(sql);
            return (Long) query.getSingleResult();
        } catch (NoResultException e) {
            return 0L;
        }
    }

    @Override
    public long updateEmployee(Long empId, String fullName, Date hireDate) {
        Employee e = entityManager.find(Employee.class, empId);
        if (e == null) {
            return 0;
        }
        e.setFullName(fullName);
        e.setHireDate(hireDate);
        entityManager.flush();
        return 1;
    }

}

4- Controller

MainController.java

package org.o7planning.sbdatajpa.controller;

import java.util.Date;
import java.util.List;
import java.util.Random;

import org.o7planning.sbdatajpa.entity.Employee;
import org.o7planning.sbdatajpa.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MainController {

    @Autowired
    private EmployeeRepository employeeRepository;

    private static final String[] NAMES = new String[] { "Tom", "Jerry", "Donald" };

    @ResponseBody
    @RequestMapping("/")
    public String home() {
        String html = "";
        html += "<ul>";
        html += " <li><a href='/testInsert'>Test Insert</a></li>";
        html += " <li><a href='/showAllEmployee'>Show All Employee</a></li>";
        html += " <li><a href='/showFullNameLikeTom'>Show All 'Tom'</a></li>";
        html += " <li><a href='/deleteAllEmployee'>Delete All Employee</a></li>";
        html += "</ul>";
        return html;
    }

    @ResponseBody
    @RequestMapping("/testInsert")
    public String testInsert() {

        Long empIdMax = this.employeeRepository.getMaxId();

        Employee employee = new Employee();

        int random = new Random().nextInt(3);

        long id = empIdMax + 1;
        String fullName = NAMES[random] + " " + id;

        employee.setId(id);
        employee.setEmpNo("E" + id);
        employee.setFullName(fullName);
        employee.setHireDate(new Date());
        this.employeeRepository.save(employee);

        return "Inserted: " + employee;
    }

    @ResponseBody
    @RequestMapping("/showAllEmployee")
    public String showAllEmployee() {

        Iterable<Employee> employees = this.employeeRepository.findAll();

        String html = "";
        for (Employee emp : employees) {
            html += emp + "<br>";
        }

        return html;
    }

    @ResponseBody
    @RequestMapping("/showFullNameLikeTom")
    public String showFullNameLikeTom() {

        List<Employee> employees = this.employeeRepository.findByFullNameLike("Tom");

        String html = "";
        for (Employee emp : employees) {
            html += emp + "<br>";
        }

        return html;
    }

    @ResponseBody
    @RequestMapping("/deleteAllEmployee")
    public String deleteAllEmployee() {

        this.employeeRepository.deleteAll();
        return "Deleted!";
    }

}
 

5- Die Applikation laufen

View more Tutorials: