Upload
naoya-kojima
View
301
Download
11
Embed Size (px)
Citation preview
JPAを初めた時のちょっとした話
Naoya KOJIMA @jugemix
学習前のJPAに対するイメージ
• SQLを書かなくても永続化層を実装できるらしい
• Spring JPAを使うとInterfaceを実装するだけでいいらしい
•どう結合するんだろ?
• DBMS毎にシーケンスの実装方法、様々だけどどうするの?
•なんだか楽できそう
学習前のJPAに対するイメージ
• SQLを書かなくても永続化層を実装できるらしい
• Spring JPAを使うとInterfaceを実装するだけでいいらしい
•どう結合するんだろ?
• DBMS毎にシーケンスの実装方法、様々だけどどうするの?
•なんだか楽できそう
結合してみた
例)運用するWebサイトを管理するアプリケーション
customer_sitecustomer operation_date
1 N 1 1
結合してみた
例)運用するWebサイトを管理するアプリケーション
customer_sitecustomer operation_date
1 N 1 1
結合してみた
--H2DB版
CREATE TABLE customer_site (
customer_site_code INT PRIMARY KEY AUTO_INCREMENT, --顧客サイトコード
url VARCHAR(1024) NOT NULL, --URL
operation_start_time TIMESTAMP NOT NULL, --運用開始時刻
operation_end_time TIMESTAMP NOT NULL, --運用終了時刻
operation_start_date TIMESTAMP NOT NULL, --運用開始日
operation_date_code INT REFERENCES operation_date(operation_date_code), --運用日コード
create_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
update_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
結合してみた
--H2DB版
CREATE TABLE operation_date (
operation_date_code INT PRIMARY KEY AUTO_INCREMENT, --運用日コード
operation_date_mon VARCHAR(12), --運用日
operation_date_tue VARCHAR(12), --運用日
operation_date_wed VARCHAR(12), --運用日
operation_date_thu VARCHAR(12), --運用日
operation_date_fri VARCHAR(12), --運用日
operation_date_sta VARCHAR(12), --運用日
operation_date_sun VARCHAR(12), --運用日
create_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
update_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
結合してみた
@Entity
@Table(name = "customer_site")
public class CustomerSite {
@SequenceGenerator(name = "customer_site_customer_site_code_seq",
sequenceName = "customer_site_customer_site_code_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer customerSiteCode; // 顧客サイトコード
/* 中略 */
@OneToOne(cascade=CascadeType.PERSIST)
@JoinColumn(name="operation_date_code")
private OperationDate operationDate; // 運用日エンティティ
}
結合してみた
@Entity
@Table(name = "operation_date")
public class OperationDate {
@SequenceGenerator(name = "operation_date_operation_date_code_seq",
sequenceName = "operation_date_operation_date_code_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer operationDateCode; // 運用日コード
private String operationDateSun; // 日曜日
/* 中略 */
private String operationDateSta; // 土曜日
}
学習前のJPAに対するイメージ
• SQLを書かなくても永続化層を実装できるらしい
• Spring JPAを使うとInterfaceを実装するだけでいいらしい
•どう結合するんだろ?
• DBMS毎にシーケンスの実装方法様々だけど、どうするの?
•なんだか楽できそう
H2DBのシーケンスを使ってみた
@Entity
@Table(name = "customer_site")
public class CustomerSite {
@SequenceGenerator(name = "customer_site_customer_site_code_seq",
sequenceName = "customer_site_customer_site_code_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer customerSiteCode; // 顧客サイトコード
/* 以下略 */
}
H2DBのシーケンスを使ってみたPostgreSQL Mode@Entity
@Table(name = "customer_site")
public class CustomerSite {
@SequenceGenerator(name = "customer_site_customer_site_code_seq",
sequenceName = "customer_site_customer_site_code_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "customer_site_customer_site_code_seq")
private Integer customerSiteCode; // 顧客サイトコード
/* 以下略 */
}このモードは @cero_tさんが教えてくれました!ありがとうございました!
PostgreSQLのシーケンスを使ってみた
@Entity
@Table(name = "customer_site")
public class CustomerSite {
@SequenceGenerator(name = "customer_site_customer_site_code_seq",
sequenceName = "customer_site_customer_site_code_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "customer_site_customer_site_code_seq")
private Integer customerSiteCode; // 顧客サイトコード
/* 以下略 */
}H2DBからPostgresへは移行しやすい~(^^)v
SQLServer2012 のシーケンスを使ってみた
@Entity
@Table(name = "customer_site")
public class CustomerSite {
@SequenceGenerator(name = "customer_site_customer_site_code_seq",
sequenceName = "customer_site_customer_site_code_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.AUTO,
generator = "customer_site_customer_site_code_seq")
private Integer customerSiteCode; // 顧客サイトコード
/* 以下略 */
}SQLServerのシーケンス実装は,2012Diarectかららしいので注意
Azure SQLServer をSpring Bootから使うときのappllicaiton.ymlspring:
profiles: development-sqlserver
datasource:
driver-class-name : com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://hogehoge.database.windows.net:1433;
/* 中略 */
username: hogehoge
password: fugafuga
jpa:
hibernate:
ddl-auto: none
dialect: org.hibernate.dialect.SQLServer2012Dialect
Azure SQLServer をSpring Bootから使うときのappllicaiton.ymlspring:
profiles: development-sqlserver
datasource:
driver-class-name : com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://hogehoge.database.windows.net:1433;
/* 中略 */
username: hogehoge
password: fugafuga
jpa:
hibernate:
ddl-auto: none
dialect: org.hibernate.dialect.SQLServer2012Dialect
余談ですが、Azure WebApps (PaaS)を使うと、簡単にWeb Applicationをデプロイできるので嬉しいです
学習後のJPAに対するイメージ
• UNIONしたくてJDBCでSQLを書くことはあった
• 永続化のタイミングを制御出来ず、DBExceptionに気づけないことがあった• saveAndFlush()で制御出来るし、一意制約違反みたいなDBException自体、起こらないように設計すべきという意見も貰えた
• オブジェクトとしてEntityを扱うので、結合の考え方が包含になってて新鮮
• DBMSを変えるときには少しコードを直した• DBMS変えるなんてそうそう無いからいいかな…
• 多少は楽できたかも
もっと知りたい
•発行されるSQLの最適化はどうやるの?
•バリバリJPQL書いているコードを見てみたい!
ありがとうございました
•僕こんな風にやってるよーなんて方いたら、この後飲みながら一緒に話しましょう