Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
JPAの基礎と現場で役立つ開発Tips
SI-Toolkit for Application Development
• はじめに
• 環境構築
• JPA Programming
• JPA Configuration
• まとめ
はじめに
SI-Toolkit : SIプロジェクトで必要な道具一式
• Application Development : Java EE & CI/CD
• Web Testing : Test Automation
Concept:もっとSmart...
株式会社モノクレア
• SIプロジェクトの技術コンサルティング
• アプリケーションアーキテクチャ
• 開発方法論
• テスト自動化
• CI/CD
環境構築
構築する環境
Eclipse Project
pom.xml
src
main
java
a.b.c.myproject.domain.user
UserRepository.java
resources
META-INF
persistenc...
プロジェクト作成 正式
• 手順詳細
• クイックスタート Eclipseで実行する場合
• 「ファイル」メニュー>新規>Mavenプロジェクト
• カタログ
• Remote http://repo.maven.apache.org/mave...
プロジェクト作成 当勉強会用
• project-generator.zipをダウンロード
• https://github.com/sitoolkit/sit-ad-archetype-javaee7-web/issues/17
• Ecli...
プロジェクト作成 当勉強会用
• 「Java EE」パースペクティブ「プロジェクト・エクスプローラー」ビューでproject-generatorプロ
ジェクトを右クリック>実行>Mavenビルド または Alt + Shift + X, M (...
derbyプロファイルをactivate
• myproject/pom.xmlを開く
• mysql以下のactivationをderby以下に移動
• derbyプロファイルのpropertiesにdb.catalogプロパティを空で設定
...
wildfly-testプロファイルをactivate
• プロジェクト右クリック>Maven>Mavenプロファイルの選択
• wildfly-testを選択
Derbyを起動
• プロジェクト右クリック>実行>Mavenビルド または Alt + Shift + X, M
• myproject_10_derby-runを選択>OK
• 「ウィンドウ」メニュー>パースペクティブ>パースペクティブを開く>その他
• DBViewerを選択>OK
• 「DBツリー・ビュー」で「データベース定義をインポート」をクリック
• myproject/target/test-classe...
データベースを参照
• インポートしたデータベース定義をダブルクリック
db-migrateを実行
• myprojectプロジェクト右クリック>実行>Mavenビルド または Alt + Shift + X, M
• myproject_01_db-migrateを選択>OK
db-migrate後のデータベース
• APPを右クリック>更新 または F5
• USER_ENTITYをダブルクリック
db-migrate後のJavaリソース
• myprojectプロジェクトを右クリック>リフレッシュ または F5
Before After
サンプルテストを開く
• 「ナビゲート」メニュー>リソースを開く または Ctrl + Shift + R
サンプルテストを実行
• UserRepositoryTest.javaを開いた状態で右クリック>実行>Junitテスト または Alt +
Shift + X, T
JPA Programming
INSERT
• UserRepositoryTest.javaにEntityManagerフィールドとtestInsertメソッドを実装して実
行
• 「コンソール」ビューにINSERT INTO user_entityのSQL文が出力される...
O/R Mapping
• Hibernate ToolsでリバースしたUserEntity.java
@Entity
@Table(name="USER_ENTITY")
@Access(AccessType.PROPERTY)
public...
JPA 要するに
• DBのテーブルやカラムをJavaのクラスやフィールドとして扱うフレームワーク。
• テーブル、カラムとクラス、フィールドの対応はアノテーションで定義する。(※1)
※1 xmlファイルでも定義できますが当資料では言及しませ...
SELECT
• UserRepositoryTest.javaにtestSelectメソッドを実装して実行
• 「コンソール」ビューにSELECT FROM user_entityのSQL文が出力されることを確認
@RunWith(CdiTe...
UPDATE
• UserRepositoryTest.javaにtestUpdateメソッドを実装して実行
• 「コンソール」ビューにUPDATE user_entityのSQL文が出力されることを確認
• JPAではトランザクション内でMa...
UPDATEしない
• @Transactinalをコメントアウト、またはEntityManager.detachでUserEntityをデタッチ
• 「コンソール」ビューにUPDATE user_entityのSQL文が出力されないことを確認...
DELETE
• UserRepositoryTest.javaにtestDeleteメソッドを実装して実行
@RunWith(CdiTestRunner.class)
public class UserRepositoryTest {
@Te...
Managed
• EntityManagerから取得したEntityインスタンスはManaged
• SQLの実行タイミングはJPAが管理する。
• トランザクション内でのEntityインスタンスのプロパティ更新は、DBも更新されることを
意...
CRUD
• 問題:次のtestCrudメソッドで実行されるSQLとその順番は?
@RunWith(CdiTestRunner.class)
public class UserRepositoryTest {
@Inject
EntityMan...
JPQL SELECT
• UserRepositoryTest.javaにtestJpqlSelectメソッドを実装して実行
import javax.persistence.Query;
@RunWith(CdiTestRunner.cla...
JPQL JOIN – NG example
• UserRepositoryTest.javaにtestJpqlSelectメソッドを実装して実行
• UserEntity.getGroupEntities()実行時にもSELECTされる!
...
FetchType
• LAZY:getしたときにSELECTする
• EAGER:初回のJPQL実行時点でJOINする
@Entity
@Table(name="USER_ENTITY")
@Access(AccessType.PROPERT...
JPQL JOIN – OK example
A) 関連プロパティ(groupEntities)が必要な場合
• JOINの後にFETCHをつける。FETCHの有り無しでSELECTするカラムが変わる。
B) 不要な場合
• デタッチする。
•...
JPQL UPDATE
• Entityを使わずにUPDATEする場合はJPQLでUPDATEする。
@Dependent
@RunWith(CdiTestRunner.class)
public class UserRepositoryTes...
JPQL 要するに
• DBのオブジェクト名をO/Rマッピング後の名前で指定するSQL
SQL JPQL
テーブル名 Entityクラス名
カラム名 Entityクラスのフィールド名
JOIN table ON JOIN entity
Native Query
• SQLを実行することも可能。
• SELECT結果をEntityとして抽出することも可能。
• 主な利用場面
• データモデルが汚すぎて職人でないとSQLが組めない。職人はJPQLを知らない。
@Dependent...
JPA Configuration
persistence.xml
• src/main/resources/META-INF/persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="h...
persistence.xml 続き
:
:
<persistence-unit name="javaee7-web-tips-pu-non-ee-container" transaction-
type="RESOURCE_LOCAL">
<...
テスト用のPUは何故必要?
• Entityクラスをスキャンする範囲
• META-INF/persistence.xmlがあるディレクトリ、jarまたはwar
• Mavenの作法に則ってテスト用persistence.xmlをsrc/tes...
まとめ
今回学んだこと
Category Item Point
Programming O/R Mapping DBレコードをJavaオブジェクトとして扱うための定義 DB
テーブル構造をJavaクラスにマッピング
JPQL 単純CRUD以外のDBのデ...
発展内容
• JPA
• O/R Mapping
• @AttributeOverride、@Inheritance、@Convert
• EntityListener
• EntityGraph
• Criteria API (APIがわかり...
SIT-ADの活用方法
• JPAの練習
• DDL作成
• db-migration
• JUnit
• Tipsの参照
• Flyway
• Hibernate Tools
• DeltaSpike
ご清聴ありがとうございました!
SmartなSIを!
Upcoming SlideShare
Loading in …5
×

JPAの基礎と現場で役立つ開発Tips

1,674 views

Published on

2017/2/19実施のSI-Toolkitユーザーグループの勉強会資料です。

Published in: Technology
  • Hi there! I just wanted to share a list of sites that helped me a lot during my studies: .................................................................................................................................... www.EssayWrite.best - Write an essay .................................................................................................................................... www.LitReview.xyz - Summary of books .................................................................................................................................... www.Coursework.best - Online coursework .................................................................................................................................... www.Dissertations.me - proquest dissertations .................................................................................................................................... www.ReMovie.club - Movies reviews .................................................................................................................................... www.WebSlides.vip - Best powerpoint presentations .................................................................................................................................... www.WritePaper.info - Write a research paper .................................................................................................................................... www.EddyHelp.com - Homework help online .................................................................................................................................... www.MyResumeHelp.net - Professional resume writing service .................................................................................................................................. www.HelpWriting.net - Help with writing any papers ......................................................................................................................................... Save so as not to lose
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

JPAの基礎と現場で役立つ開発Tips

  1. 1. JPAの基礎と現場で役立つ開発Tips SI-Toolkit for Application Development
  2. 2. • はじめに • 環境構築 • JPA Programming • JPA Configuration • まとめ
  3. 3. はじめに
  4. 4. SI-Toolkit : SIプロジェクトで必要な道具一式 • Application Development : Java EE & CI/CD • Web Testing : Test Automation Concept:もっとSmartなSIを!
  5. 5. 株式会社モノクレア • SIプロジェクトの技術コンサルティング • アプリケーションアーキテクチャ • 開発方法論 • テスト自動化 • CI/CD
  6. 6. 環境構築
  7. 7. 構築する環境 Eclipse Project pom.xml src main java a.b.c.myproject.domain.user UserRepository.java resources META-INF persistence.xml test java a.b.c.myproject.domain.user UserRepositoryTest.java target/generate-sources/hibernate-tools a.b.c.myproject.domain.user UserEntity.java tools derby migration V1__create_user_and_group.sql hibernate-tools DB (Derby) Hibernate Tools Flyway JPA, CDI1. create project from maven archetype 3. db migrate 4. reverse engineer 2. start db
  8. 8. プロジェクト作成 正式 • 手順詳細 • クイックスタート Eclipseで実行する場合 • 「ファイル」メニュー>新規>Mavenプロジェクト • カタログ • Remote http://repo.maven.apache.org/maven2/archetype-catalog.xml • アーキタイプ • グループId:org.sitoolkit.ad.archetype アーティファクトId:javaee7-web-tips バージョ ン:1.1.1
  9. 9. プロジェクト作成 当勉強会用 • project-generator.zipをダウンロード • https://github.com/sitoolkit/sit-ad-archetype-javaee7-web/issues/17 • Eclipseに既存プロジェクトとしてインポート • 「ファイル」メニュー>インポート>既存プロジェクトをワークスペースへ
  10. 10. プロジェクト作成 当勉強会用 • 「Java EE」パースペクティブ「プロジェクト・エクスプローラー」ビューでproject-generatorプロ ジェクトを右クリック>実行>Mavenビルド または Alt + Shift + X, M (alt + shift + X, M) • project-generatorプロジェクトを右クリック>リフレッシュ またはF5 • myprojectフォルダを右クリック>Import as Project • project-generatorプロジェクトを右クリック>閉じる
  11. 11. derbyプロファイルをactivate • myproject/pom.xmlを開く • mysql以下のactivationをderby以下に移動 • derbyプロファイルのpropertiesにdb.catalogプロパティを空で設定 l.95 <profile> <id>derby</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <db.catalog></db.catalog> <db.client.groupId>org.apache.derby</db.client.groupId> l.117 <profile> <id>mysql</id> <activation> <activeByDefault>true</activeByDefault> </activation>
  12. 12. wildfly-testプロファイルをactivate • プロジェクト右クリック>Maven>Mavenプロファイルの選択 • wildfly-testを選択
  13. 13. Derbyを起動 • プロジェクト右クリック>実行>Mavenビルド または Alt + Shift + X, M • myproject_10_derby-runを選択>OK
  14. 14. • 「ウィンドウ」メニュー>パースペクティブ>パースペクティブを開く>その他 • DBViewerを選択>OK • 「DBツリー・ビュー」で「データベース定義をインポート」をクリック • myproject/target/test-classes/dbviewer/derby.xmlを選択 データベース接続定義をインポート
  15. 15. データベースを参照 • インポートしたデータベース定義をダブルクリック
  16. 16. db-migrateを実行 • myprojectプロジェクト右クリック>実行>Mavenビルド または Alt + Shift + X, M • myproject_01_db-migrateを選択>OK
  17. 17. db-migrate後のデータベース • APPを右クリック>更新 または F5 • USER_ENTITYをダブルクリック
  18. 18. db-migrate後のJavaリソース • myprojectプロジェクトを右クリック>リフレッシュ または F5 Before After
  19. 19. サンプルテストを開く • 「ナビゲート」メニュー>リソースを開く または Ctrl + Shift + R
  20. 20. サンプルテストを実行 • UserRepositoryTest.javaを開いた状態で右クリック>実行>Junitテスト または Alt + Shift + X, T
  21. 21. JPA Programming
  22. 22. INSERT • UserRepositoryTest.javaにEntityManagerフィールドとtestInsertメソッドを実装して実 行 • 「コンソール」ビューにINSERT INTO user_entityのSQL文が出力されることを確認 • USER_ENTITYテーブルにレコードが1件INSERTされていることを確認 @RunWith(CdiTestRunner.class) public class UserRepositoryTest { @Inject EntityManager em; @Test @Transactional public void testInsert() { UserEntity user = UserFactory.create(); em.persist(user); } }
  23. 23. O/R Mapping • Hibernate ToolsでリバースしたUserEntity.java @Entity @Table(name="USER_ENTITY") @Access(AccessType.PROPERTY) public class UserEntity extends BaseEntity implements java.io.Serializable { private String userId; private Set<GroupEntity> groupEntities = new HashSet<GroupEntity>(0); @Id @Column(name="USER_ID", unique=true, nullable=false, length=10) public String getUserId() { return this.userId; } @ManyToMany(fetch=FetchType.LAZY) @JoinTable(name="USER_GROUP_RELATION", schema="APP", joinColumns = { @JoinColumn(name="USER_ID", nullable=false, updatable=false) }, inverseJoinColumns = { @JoinColumn(name="GROUP_CODE", nullable=false, updatable=false) }) public Set<GroupEntity> getGroupEntities() { return this.groupEntities; }
  24. 24. JPA 要するに • DBのテーブルやカラムをJavaのクラスやフィールドとして扱うフレームワーク。 • テーブル、カラムとクラス、フィールドの対応はアノテーションで定義する。(※1) ※1 xmlファイルでも定義できますが当資料では言及しません。 DB Java テーブル @Entityのついたクラス カラム @Entityのついたクラスのフィールド レコード @Entityのついたクラスのインスタンス
  25. 25. SELECT • UserRepositoryTest.javaにtestSelectメソッドを実装して実行 • 「コンソール」ビューにSELECT FROM user_entityのSQL文が出力されることを確認 @RunWith(CdiTestRunner.class) public class UserRepositoryTest { @Test public void testSelect() { UserEntity user = em.find(UserEntity.class, "user0001"); System.out.println(user.getUserId()); } }
  26. 26. UPDATE • UserRepositoryTest.javaにtestUpdateメソッドを実装して実行 • 「コンソール」ビューにUPDATE user_entityのSQL文が出力されることを確認 • JPAではトランザクション内でManagedな状態のエンティティのプロパティを変更すると自動で UPDATE! @RunWith(CdiTestRunner.class) public class UserRepositoryTest { @Test @Transactional public void testUpdate() { UserEntity user = em.find(UserEntity.class, "user0001"); user.setFirstName("name"); } }
  27. 27. UPDATEしない • @Transactinalをコメントアウト、またはEntityManager.detachでUserEntityをデタッチ • 「コンソール」ビューにUPDATE user_entityのSQL文が出力されないことを確認 @RunWith(CdiTestRunner.class) public class UserRepositoryTest { @Test // @Transactional public void testUpdate() { UserEntity user = em.find(UserEntity.class, "user0001"); em.detach(user); user.setFirstName("name"); } }
  28. 28. DELETE • UserRepositoryTest.javaにtestDeleteメソッドを実装して実行 @RunWith(CdiTestRunner.class) public class UserRepositoryTest { @Test @Transactional public void testDelete() { UserEntity user = em.find(UserEntity.class, "user0001"); em.remove(user); } }
  29. 29. Managed • EntityManagerから取得したEntityインスタンスはManaged • SQLの実行タイミングはJPAが管理する。 • トランザクション内でのEntityインスタンスのプロパティ更新は、DBも更新されることを 意識しましょう! EntityManagerのメソッド 作用 persist(Object entity) INSERTしてentityをManagedにする。 find(Class entityClass, Object primaryKey) entityClassのインスタンスを取得する。 SELECTが実行される可能性がある。 merge(Object entity) entityをManagedにする。UPDATE、または INSERTが実行される可能性がある。 remove(Object entity) DELETEが実行される可能性がある。
  30. 30. CRUD • 問題:次のtestCrudメソッドで実行されるSQLとその順番は? @RunWith(CdiTestRunner.class) public class UserRepositoryTest { @Inject EntityManager em; @Test @Transactional public void testCrud() { UserEntity user = UserFactory.create(); em.persist(user); UserEntity userInDb = em.find(UserEntity.class, user.getUserId()); userInDb.setFirstName("user"); em.merge(userInDb); em.remove(userInDb); } }
  31. 31. JPQL SELECT • UserRepositoryTest.javaにtestJpqlSelectメソッドを実装して実行 import javax.persistence.Query; @RunWith(CdiTestRunner.class) public class UserRepositoryTest { @Test public void testJpqlSelect() { Query query = em.createQuery( "SELECT u FROM UserEntity u WHERE u.userId LIKE :userId"); query.setParameter("userId", "user%"); List<UserEntity> users = query.getResultList(); System.out.println(users.size()); } }
  32. 32. JPQL JOIN – NG example • UserRepositoryTest.javaにtestJpqlSelectメソッドを実装して実行 • UserEntity.getGroupEntities()実行時にもSELECTされる! @Dependent @RunWith(CdiTestRunner.class) public class UserRepositoryTest { @Test public void testJpqlJoin() { Query query = em.createQuery( "SELECT u FROM UserEntity u JOIN u.groupEntities g"); List<UserEntity> users = query.getResultList(); System.out.println(users.get(0).getGroupEntities()); } }
  33. 33. FetchType • LAZY:getしたときにSELECTする • EAGER:初回のJPQL実行時点でJOINする @Entity @Table(name="USER_ENTITY") @Access(AccessType.PROPERTY) public class UserEntity extends BaseEntity implements java.io.Serializable { @ManyToMany(fetch=FetchType.LAZY) @JoinTable(name="USER_GROUP_RELATION", schema="APP", joinColumns = { @JoinColumn(name="USER_ID", nullable=false, updatable=false) }, inverseJoinColumns = { @JoinColumn(name="GROUP_CODE", nullable=false, updatable=false) }) public Set<GroupEntity> getGroupEntities() { return this.groupEntities; }
  34. 34. JPQL JOIN – OK example A) 関連プロパティ(groupEntities)が必要な場合 • JOINの後にFETCHをつける。FETCHの有り無しでSELECTするカラムが変わる。 B) 不要な場合 • デタッチする。 • 注意:デタッチした後に関連プロパティにアクセスすると例外が発生する。 @Dependent @RunWith(CdiTestRunner.class) public class UserRepositoryTest { @Test public void testJpqlJoin() { Query query = em.createQuery( "SELECT u FROM UserEntity u JOIN FETCH u.groupEntities g"); List<UserEntity> users = query.getResultList(); users.stream().forEach(u -> em.detach(u)); System.out.println(users.get(0).getGroupEntities()); } } A) B)
  35. 35. JPQL UPDATE • Entityを使わずにUPDATEする場合はJPQLでUPDATEする。 @Dependent @RunWith(CdiTestRunner.class) public class UserRepositoryTest { @Test @Transactional public void testJpqlUpdate() { Query query = em.createQuery( "UPDATE UserEntity u SET u.lastName = :lastName " + "WHERE u.userId = :userId"); query.setParameter("lastName", "name"); query.setParameter("userId", "user0002"); System.out.println(query.executeUpdate()); } }
  36. 36. JPQL 要するに • DBのオブジェクト名をO/Rマッピング後の名前で指定するSQL SQL JPQL テーブル名 Entityクラス名 カラム名 Entityクラスのフィールド名 JOIN table ON JOIN entity
  37. 37. Native Query • SQLを実行することも可能。 • SELECT結果をEntityとして抽出することも可能。 • 主な利用場面 • データモデルが汚すぎて職人でないとSQLが組めない。職人はJPQLを知らない。 @Dependent @RunWith(CdiTestRunner.class) public class UserRepositoryTest { @Test public void testNativeQuery() { Query query = em.createNativeQuery( "SELECT * FROM user_entity", UserEntity.class); List<UserEntity> result = query.getResultList(); System.out.println(result.get(0)); } }
  38. 38. JPA Configuration
  39. 39. persistence.xml • src/main/resources/META-INF/persistence.xml <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd" version="2.1"> <persistence-unit name="javaee7-web-tips-pu" transaction-type="JTA"> <jta-data-source>jdbc/javaee7-web-tips-ds</jta-data-source> <properties> <property name="eclipselink.logging.logger" value="JavaLogger" /> <property name="eclipselink.logging.level" value="FINE" /> <property name="eclipselink.logging.parameters" value="true" /> <property name="hibernate.dialect" value="${hibernate.dialect}"/> <property name="hibernate.format_sql" value="true"/> <property name="wildfly.jpa.default-unit" value="true"/> </properties> </persistence-unit> : : Tips:実行SQLをロ グ出力するように設定
  40. 40. persistence.xml 続き : : <persistence-unit name="javaee7-web-tips-pu-non-ee-container" transaction- type="RESOURCE_LOCAL"> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="javax.persistence.jdbc.driver" value="${db.jdbc.driver}" /> <property name="javax.persistence.jdbc.url" value="${db.jdbc.url}" /> <property name="javax.persistence.jdbc.user" value="${db.username}" /> <property name="javax.persistence.jdbc.password" value="${db.password}" /> <property name="eclipselink.logging.logger" value="JavaLogger" /> <property name="eclipselink.logging.level" value="FINE" /> <property name="eclipselink.logging.parameters" value="true" /> <property name="hibernate.dialect" value="${hibernate.dialect}"/> <property name="hibernate.format_sql" value="true"/> </properties> </persistence-unit> </persistence> Tips:EEコンテナー外での 設定をテスト用として同一ファ イル内に定義(次頁) Tips:接続情報を開発 者ごとに切り替えられるよ うに設定
  41. 41. テスト用のPUは何故必要? • Entityクラスをスキャンする範囲 • META-INF/persistence.xmlがあるディレクトリ、jarまたはwar • Mavenの作法に則ってテスト用persistence.xmlをsrc/test/resourcesに配置すると、 Entityクラスがスキャンされない! src main java my/package/structure MyEntity.java resources META-INF persistence.xml test resources META-INF persistence.xml target classes my/package/structure MyEntity.class META-INF persistence.xml test-classes META-INF persistence.xml build スキャン対象 スキャン対象外
  42. 42. まとめ
  43. 43. 今回学んだこと Category Item Point Programming O/R Mapping DBレコードをJavaオブジェクトとして扱うための定義 DB テーブル構造をJavaクラスにマッピング JPQL 単純CRUD以外のDBのデータ操作はJPQLで行う Configuration persistence.xml DB接続情報やトランザクション管理方法などJPAの設 定はpersistence.xmlで定義する Tips DB Migration Tool DDL、DMLをチームで共有し&個々人が実行できる環 境を作る -> Flyway Reverse Engineering Tool EntityクラスをDBスキーマからリバースエンジニアリングで きる環境を作る -> Hibernate Tools SQL Log 実行SQLをログに出力するようにJPAプロバイダーを設定 する Unit Test with CDI CDI、特に宣言的トランザクションが使える単体テスト環 境を作る -> DeltaSpike
  44. 44. 発展内容 • JPA • O/R Mapping • @AttributeOverride、@Inheritance、@Convert • EntityListener • EntityGraph • Criteria API (APIがわかりにくいのでSIT-ADに入れるかは要検討。。) • Shared Cache Mode • DeltaSpike • Data Module • https://deltaspike.apache.org/documentation/data.html
  45. 45. SIT-ADの活用方法 • JPAの練習 • DDL作成 • db-migration • JUnit • Tipsの参照 • Flyway • Hibernate Tools • DeltaSpike
  46. 46. ご清聴ありがとうございました! SmartなSIを!

×