Skip to content

Commit a320330

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 9dd2bff + 8b3fe2c commit a320330

File tree

187 files changed

+5481
-1555
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

187 files changed

+5481
-1555
lines changed

docs/sources/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ User Documentation
5252
transaction
5353
annotation-processing
5454
build
55+
lombok-support
5556
kotlin-support
5657

5758
Developer Documentation

docs/sources/lombok-support.rst

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
==================
2+
Lombok サポート
3+
==================
4+
5+
.. contents:: 目次
6+
:depth: 3
7+
8+
Doma は `Lombok <https://projectlombok.org/>`_ のバージョン 1.16.12 以上をサポートしています。
9+
10+
.. note::
11+
12+
IDE として Eclipse を利用する場合はバージョン 4.5 以上を使ってください。
13+
4.5 未満ではアノテーションプロッサで取得されるクラスに定義されたフィールドなどの並びがソースコードに記載されている順序と異なり、
14+
正しく動作しないためです。
15+
16+
Lombok サポートの概要
17+
================================
18+
19+
Lombok と Doma は共に JSR 269 で規定されたアノテーションプロセッサを提供していますが、
20+
Lombok と Doma を同時に利用する場合はアノテーションプロセッサの処理順序が問題になることがあります。
21+
例えば、 Lombok のアノテーションプロセッサがコンストラクタを生成し、
22+
Doma のアノテーションプロセッサがそのコンストラクタを読み取る場合などです。
23+
仮に、Doma のアノテーションプロセッサが先に実行されると単にコンストラクタが定義されていないものとして動作し、
24+
コンパイルに失敗します。
25+
26+
アノテーションプロセッサの処理順序を指定できればこの問題は解決するのですが、
27+
残念ながら処理順序が保証されないことが仕様に記載されており、実際に問題解決の仕組みは提供されていません。
28+
29+
Doma では、この問題に対応するために、Lombok のアノテーションの有無を認識して処理順序に依存にしない振る舞いをするようにしています。
30+
先ほどの例で言えば、 ``@lombok.Value`` などコンストラクタを生成するLombokのアノテーションが存在する場合は
31+
実際にはコンストラクタを読み取らなくてもコンストラクタが存在するものとして動作するということです。
32+
33+
Lombok 利用のベストプラクティス
34+
================================
35+
36+
Lombok のアノテーションを用いたクラスの定義について推奨する方法を記載します。
37+
38+
エンティティクラス
39+
-------------------
40+
41+
immutable(イミュータブル)
42+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
43+
44+
イミュータブルなエンティティクラスを定義する場合は下記の点に注意します。
45+
46+
* ``@Entity`` の ``immutable`` 要素に ``true`` を設定する
47+
* ``@lombok.Value`` もしくは ``@lombok.AllArgsConstructor`` を注釈する
48+
* ``@lombok.AllArgsConstructor`` を選んだ場合、getterを生成するためには ``@lombok.Getter`` を注釈する
49+
50+
.. code-block:: java
51+
52+
@Entity(immutable = true)
53+
@Value
54+
public class Employee {
55+
@Id
56+
Integer id;
57+
String name;
58+
Age age;
59+
}
60+
61+
.. code-block:: java
62+
63+
@Entity(immutable = true)
64+
@AllArgsConstructor
65+
@Getter
66+
public class Worker {
67+
@Id
68+
private final Integer id;
69+
private final String name;
70+
private final Age age;
71+
}
72+
73+
mutable(ミュータブル)
74+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
75+
76+
ミュータブルなエンティティクラスを定義する場合は下記の点に注意します。
77+
78+
* デフォルトコンストラクタを定義する(デフォルトコンストラクタの生成を抑制しない)
79+
* getter/setterを生成する場合は ``@lombok.Data`` もしくは ``@lombok.Getter`` / ``@lombok.Setter`` を注釈する
80+
81+
.. code-block:: java
82+
83+
@Entity
84+
@Data
85+
public class Person {
86+
@Id
87+
private Integer id;
88+
private String name;
89+
private Age age;
90+
}
91+
92+
.. code-block:: java
93+
94+
@Entity
95+
@Getter
96+
@Setter
97+
public class Businessman {
98+
@Id
99+
private Integer id;
100+
private String name;
101+
private Age age;
102+
}
103+
104+
ドメインクラス
105+
-------------------
106+
107+
ドメインクラスを定義する場合は下記の点に注意します。
108+
109+
* ``@lombok.Value`` を注釈する
110+
* インスタンスフィールドは1つだけ定義し名前は ``value`` にする
111+
112+
.. code-block:: java
113+
114+
@Domain(valueType = Integer.class)
115+
@Value
116+
public class Age {
117+
Integer value;
118+
}
119+
120+
エンベッダブルクラス
121+
----------------------
122+
123+
エンベッダブルクラスを定義する場合は下記の点に注意します。
124+
125+
* ``@lombok.Value`` もしくは ``@lombok.AllArgsConstructor`` を注釈する
126+
* ``@lombok.AllArgsConstructor`` を選んだ場合、getterを生成するためには ``@lombok.Getter`` を注釈する
127+
128+
.. code-block:: java
129+
130+
@Embeddable
131+
@Value
132+
public class Address {
133+
String street;
134+
String city;
135+
}
136+
137+
.. code-block:: java
138+
139+
@Embeddable
140+
@AllArgsConstructor
141+
@Getter
142+
public class Location {
143+
private final String street;
144+
private final String city;
145+
}

docs/sources/query/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@
1616
procedure
1717
factory
1818
script
19+
sql-processor
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
==================
2+
SQLプロセッサ
3+
==================
4+
5+
.. contents:: 目次
6+
:depth: 3
7+
8+
SQLテンプレートで組み立てられたSQLをアプリケーションで扱うには、 ``@SqlProcessor`` をDaoのメソッドに注釈します。
9+
10+
.. code-block:: java
11+
12+
@Config(config = AppConfig.class)
13+
public interface EmployeeDao {
14+
@SqlProcessor
15+
<R> R process(Integer id, BiFunction<Config, PreparedSql, R> handler);
16+
...
17+
}
18+
19+
メソッドに対応する :doc:`../sql` が必須です。
20+
21+
.. warning::
22+
23+
SQLプロセッサを使ってSQLを組み立て実行する場合、潜在的には常にSQLインジェクションのリスクがあります。
24+
まずは、他のクエリもしくはクエリビルダを使う方法を検討してください。
25+
また、SQLプロセッサでは信頼できない値をSQLの組み立てに使わないように注意してください。
26+
27+
戻り値
28+
==================
29+
30+
メソッドの戻り値は任意の型にできます。
31+
ただし、 ``BiFunction`` 型のパラメータの3番目の型パラメータと合わせる必要があります。
32+
33+
なお、戻り値の型を ``void`` にする場合、 ``BiFunction`` 型のパラメータの3番目の型パラメータには ``Void`` を指定します。
34+
35+
.. code-block:: java
36+
37+
@SqlProcessor
38+
void process(Integer id, BiFunction<Config, PreparedSql, Void> handler);
39+
40+
パラメータ
41+
==================
42+
43+
``BiFunction`` 型のパラメータを1つのみ含める必要があります。
44+
``BiFunction`` 型のパラメータはSQLテンプレート処理後のSQLを処理するために使われます。
45+
46+
その他のパラメータはSQLテンプレートで参照できます。
47+
基本的には、 :doc:`select` の問い合わせ条件に指定できるのと同じ型を使用できます。
48+
49+
利用例
50+
==================
51+
52+
例えば、SQLテンプレートで処理したSQLをさらに変形し直接実行することができます。(この例では例外処理を省略しています。)
53+
54+
.. code-block:: java
55+
56+
EmployeeDao dao = ...
57+
dao.process(1, (config, preparedSql) -> {
58+
String sql = preparedSql.getRawSql();
59+
String anotherSql = createAnotherSql(sql);
60+
DataSource dataSource = config.getDataSource()
61+
Connection connection = dataSource.getConnection();
62+
PreparedStatement statement = connection.prepareStatement(anotherSql);
63+
return statement.execute();
64+
});
65+
66+
.. code-block:: sql
67+
68+
select * from employee where id = /*^ id */0
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2004-2010 the Seasar Foundation and the Others.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13+
* either express or implied. See the License for the specific language
14+
* governing permissions and limitations under the License.
15+
*/
16+
package org.seasar.doma;
17+
18+
import java.lang.annotation.ElementType;
19+
import java.lang.annotation.Retention;
20+
import java.lang.annotation.RetentionPolicy;
21+
import java.lang.annotation.Target;
22+
23+
/**
24+
* SQLテンプレートで組み立てられたSQLを扱うことを示します。
25+
* <p>
26+
* このアノテーションが注釈されるメソッドは、Daoインタフェースのメンバでなければいけません。
27+
*
28+
* <h3>例:</h3>
29+
*
30+
* <pre>
31+
* &#064;Dao(config = AppConfig.class)
32+
* public interface EmployeeDao {
33+
* &#64;SqlProcessor
34+
* &lt;R&gt; R process(Integer id, BiFunction&lt;Config, PreparedSql, R&gt; handler);
35+
* }
36+
* </pre>
37+
*
38+
* @author nakamura
39+
* @since 2.14.0
40+
*/
41+
@Target(ElementType.METHOD)
42+
@Retention(RetentionPolicy.RUNTIME)
43+
@DaoMethod
44+
public @interface SqlProcessor {
45+
46+
}

0 commit comments

Comments
 (0)