[Spring]DBアクセス技術-2


🌕 JPA


JPAは既存の重複コードだけでなく、基本的なSQLもJPA自身が作成して実行します.
JPAを使用すると、SQLおよびデータ集約設計からオブジェクト中心の設計にモードを変換できます.
JPAを使うことで開発生産性を大幅に向上させることができます.

🌒 build.JPA、h 2データベース関連ライブラリをgradleに追加

spring-boot-starter-data-jpaには内部のjdbc関連ライブラリが含まれており、jdbcを削除できます.build.gradle
dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	//implementation 'org.springframework.boot:spring-boot-starter-jdbc'
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	runtimeOnly 'com.h2database:h2'
	testImplementation('org.springframework.boot:spring-boot-starter-test') {
	exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}

🌒 JPA設定をスプリングガイドに追加

show-sql:JPA生成SQL出力.ddl-auto:JPAはテーブルを自動的に生成する機能を提供し、noneを使用する場合はこの機能をオフにします.(createを使用すると、エンティティ情報に基づいてテーブルを直接作成できます.)resources/application.properties
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none

🌒 JPAエンティティのマッピング


@Entityアニメーションを使用して、オブジェクト(メンバー)をDBに関連付けます.
@IDコメントを使用してpkを設定し、@GeneratedValueを使用してid値を自動的に生成し、pk値として指定します.
コメント処理の@Columnプレゼンテーションでは、名前メンバー変数をDBの「username」にマッピングできます.
package hello.hellospring.domain;

import javax.persistence.*;

@Entity
public class Member {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    //@Column(name="username")
    private String name;

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

🌒 JPA会員庫

src\main\java\hello\hellospring\repository\JpaMemberRepository.java
package hello.hellospring.repository;

import hello.hellospring.domain.Member;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.List;
import java.util.Optional;

public class JpaMemberRepository implements MemberRepository{

   private final EntityManager em;

    public JpaMemberRepository(EntityManager em) {
        this.em = em;
    }

    @Override
    public Member save(Member member) {
        em.persist(member);
        return member;
    }

    @Override
    public Optional<Member> findById(Long id) {
        Member member = em.find(Member.class, id);
        return Optional.ofNullable(member);
    }

    @Override
    public Optional<Member> findByName(String name) {
        List<Member> result = em.createQuery("select m from Member m where m.name = :name", Member.class)
                .setParameter("name", name)
                .getResultList();

        return result.stream().findAny();
    }

    @Override
    public List<Member> findAll() {
        return em.createQuery("select m from Member m", Member.class)
                .getResultList();
    }
}
src\main\java\hello\hellospring\service\MemberService.javaへのトランザクションの追加
@Transactionalorg.springframework.transaction.annotation.Transactionalの使用
スプリングは、クラスのメソッドを実行するとトランザクションを開始し、メソッドが正常に終了するとトランザクションをコミットします.実行時に異常が発生した場合は、ロールバックします.
JPAによるすべてのデータ変更は、トランザクションで実行する必要があります.

🌒 スプリング設定を変更してJPAを使用

src\main\java\hello\hellospring\SpringConfig.java
@Bean
 public MemberRepository memberRepository() {
// return new MemoryMemberRepository();
// return new JdbcMemberRepository(dataSource);
// return new JdbcTemplateMemberRepository(dataSource);
 return new JpaMemberRepository(em);
 }

🌕 SpringデータJPA


Spring Data JPAを使用すると、リポジトリに実装クラスを設定することなく、インタフェースだけで開発が完了します.また、開発を重ねたCRUD機能もSpring Data JPAが提供している.

🌒Spring Data JPAメンバーライブラリ


SpringDataJpaMemberRepositoryインタフェースはSpring Data JPAからのJpaRepositoryを受信します.保存されたメンバークラスとpkのタイプLongを指定し、JpaRepositoryなどのメンバーRepositoryを受信します.src\main\java\hello\hellospring\repository\SpringDataJpaMemberRepository.javaをインタフェースとして作成
package hello.hellospring.repository;

import hello.hellospring.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long>, MemberRepository {

    @Override
    Optional<Member> findByName(String name);
}

🌒 スプリングデータJPAメンバーライブラリを使用するためのスプリング設定の変更


Springdata JPAは、SpringDataJpaMemberRepositoryを自動的にspringbinとして登録します.src\main\java\hello\hellospring\SpringConfig.java
package hello.hellospring;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.*;
import hello.hellospring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//import javax.persistence.EntityManager;
//import javax.sql.DataSource;

@Configuration
public class SpringConfig {
    
    //private final DataSource dataSource;
    //private final EntityManager em;
    
    private final MemberRepository memberRepository;

    public SpringConfig(MemberRepository memberRepository){
        this.memberRepository = memberRepository;
    }

    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository);
    }

//    @Bean
//    public MemberRepository memberRepository(){
//        //return new MemoryMemberRepository();
//        //return new JdbcMemberRepository(dataSource);
//        //return new JdbcTemplateMemberRepository(dataSource);
//        return new JpaMemberRepository(em);
//    }
}

🌒 Spring Data JPA提供クラス



インタフェースを作成すると、Jpa RepositoryはPaging And Sorting Repositoryインタフェースを継承し、CrudRepositoryとRepositoryを継承します.これらのインタフェースには、save()、findOne()、findAll()、findById()など、以前に直接実装された機能と、count()やdelete()などの基本的なCRUDまたは簡単なクエリーを実行する機能が含まれています.
また、findByName()やfindByEmail()のような共通に抽出できない方法については、上記の「Optional findByName(String name)」をインタフェースで使用することができる.に示すようにSpring Data JPAは自動的に「select m from Memberm wherem.name=?」たとえば、JPQLクエリーを作成できます.
(例えば、findByEmail()「Optional findByEmail(String email)」;コードを追加するだけです(など)
SpringデータJPAの提供
インタフェースによる基本CRUDの作成findByName()findByEmail()のように、メソッド名のみを使用してクエリーを提供します.
自動ページング機能
スススススススススススススス|ス\1247Querydslを使用するとjavaコードを安全に使用してクエリーを記述したり、動的クエリーを容易に記述したりすることができます.JPAが提供するネイティブクエリーまたは以前に学習したSpring JdbcTemplateを使用すると、この組み合わせでは解決しにくいクエリーを解決できます.