Skip to content

Commit 11a32f8

Browse files
committed
Add tutorial
1 parent e808954 commit 11a32f8

File tree

1 file changed

+241
-0
lines changed

1 file changed

+241
-0
lines changed

README.md

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,247 @@ Add the following repository to use snapshots.
4545
</repository>
4646
```
4747

48+
## Tutorial
49+
50+
### Create a project
51+
52+
Create a blank project from [SPRING INITIALIZR](https://start.spring.io).
53+
Enter and select "Web", "JDBC" and "H2" in「Search for dependencies」.
54+
55+
<img width="80%" src="https://qiita-image-store.s3.amazonaws.com/0/1852/87eb3d20-dda4-a52d-e1e7-9adb264aef44.png">
56+
57+
Then click 「Generate Project」 and `demo.zip` will be downloaded. Extract the zip and import the Maven project into IDE.
58+
In this tutorial we will use IntelliJ IDEA. In case of IDEA, only you have to do is just open `pom.xml`.
59+
60+
Add the following dependency to `pom.xml` so that we can use Doma with Spring Boot.
61+
62+
``` xml
63+
<dependency>
64+
<groupId>org.seasar.doma.boot</groupId>
65+
<artifactId>doma-spring-boot-starter</artifactId>
66+
<version>1.0.0.RC2</version>
67+
</dependency>
68+
```
69+
70+
### Create an entity
71+
72+
Next, create the following entity
73+
74+
``` java
75+
package com.example;
76+
77+
import org.seasar.doma.Entity;
78+
import org.seasar.doma.GeneratedValue;
79+
import org.seasar.doma.GenerationType;
80+
import org.seasar.doma.Id;
81+
82+
@Entity
83+
public class Reservation {
84+
@Id
85+
@GeneratedValue(strategy = GenerationType.IDENTITY)
86+
public Integer id;
87+
public String name;
88+
}
89+
```
90+
91+
### Create a DAO interface
92+
93+
Then, create the following DAO interface. We will add search and insert method.
94+
95+
``` java
96+
package com.example;
97+
98+
import org.seasar.doma.Dao;
99+
import org.seasar.doma.Insert;
100+
import org.seasar.doma.Select;
101+
import org.seasar.doma.boot.ConfigAutowireable;
102+
import org.springframework.transaction.annotation.Transactional;
103+
104+
import java.util.List;
105+
106+
@ConfigAutowireable
107+
@Dao
108+
public interface ReservationDao {
109+
@Select
110+
List<Reservation> selectAll();
111+
112+
@Insert
113+
@Transactional
114+
int insert(Reservation reservation);
115+
}
116+
```
117+
`@ConfigAutowireable` is the annotation to annotate `@Repository` and `@Autowired` on generated DAO implematations using [@AnnotateWith](http://doma.readthedocs.org/ja/stable/config/#id22).
118+
119+
### Generate the DAO imlementation class
120+
121+
After create a DAO interface, build by IDE or Maven, then the implementation class will be generated. However, update methods need the corresponding SQL files **at the compile time**. Unless SQL files exist, compilation will fail.
122+
Usually, SQL corresponding to the method will be written in `src/main/resources/META-INF/(FQCN)/(class name)/(method name).sql`. In this case, it's `src/main/resources/META-INF/com/example/ReservationDao/selectAll.sql`.
123+
124+
<img width="80%" src="https://qiita-image-store.s3.amazonaws.com/0/1852/bc75a9c8-fdb4-aafc-e5a5-0921575b556d.png" />
125+
126+
**Tip**: On the image above, `selectAll` is highlighted by red because the required SQL file does not exist. This feature is enabled by [Doma Support Plugin](https://github.com/siosio/DomaSupport). This is not compulsory but really useful.
127+
128+
<img width="60%" src="https://qiita-image-store.s3.amazonaws.com/0/1852/1aa25b5d-50e2-f19d-f539-92f6d6adc25b.png">
129+
130+
With this plugin, SQL file can be created easily. `Option + Enter` on the method, and select 「SQLファイルを作る。」 on the menu.
131+
132+
<img width="80%" src="https://qiita-image-store.s3.amazonaws.com/0/1852/d008815c-f5b8-a4cf-4b85-2e7503bac42b.png" />
133+
134+
Then select `.../src/main/resouces` and SQL file will be generated.
135+
136+
<img width="40%" src="https://qiita-image-store.s3.amazonaws.com/0/1852/f1486c0f-ba90-2f3a-d70a-dc962d1e0a76.png">
137+
138+
139+
After that, write your query in this SQL file.
140+
141+
``` sql
142+
SELECT
143+
id,
144+
name
145+
FROM reservation
146+
ORDER BY name ASC
147+
```
148+
149+
<img width="80%" src="https://qiita-image-store.s3.amazonaws.com/0/1852/dd62c85b-5ccb-13ef-6927-8e17f12903db.png" />
150+
151+
Build again, then compilation will succeed and you can see `ReservationDaoImpl` is generated under `target` and compiled.
152+
153+
<img src="https://qiita-image-store.s3.amazonaws.com/0/1852/2a23f92d-348a-d7ff-957a-027a80473983.png" />
154+
155+
### Create an application
156+
157+
Let's make a small application using `ReservationDao` in `DemoApplication`.
158+
159+
``` java
160+
package com.example;
161+
162+
import org.springframework.beans.factory.annotation.Autowired;
163+
import org.springframework.boot.CommandLineRunner;
164+
import org.springframework.boot.SpringApplication;
165+
import org.springframework.boot.autoconfigure.SpringBootApplication;
166+
import org.springframework.context.annotation.Bean;
167+
import org.springframework.web.bind.annotation.RequestMapping;
168+
import org.springframework.web.bind.annotation.RestController;
169+
170+
import java.util.Arrays;
171+
import java.util.List;
172+
173+
@SpringBootApplication
174+
@RestController
175+
public class DemoApplication {
176+
177+
public static void main(String[] args) {
178+
SpringApplication.run(DemoApplication.class, args);
179+
}
180+
181+
@Autowired
182+
ReservationDao reservationDao;
183+
184+
// Insert data at initailizing phase using ReservationDao#insert
185+
@Bean
186+
CommandLineRunner runner() {
187+
return args -> Arrays.asList("spring", "spring boot", "spring cloud", "doma").forEach(s -> {
188+
Reservation r = new Reservation();
189+
r.name = s;
190+
reservationDao.insert(r);
191+
});
192+
}
193+
194+
@RequestMapping(path = "/")
195+
List<Reservation> all() {
196+
return reservationDao.selectAll();
197+
}
198+
}
199+
```
200+
201+
Next configure the SQL dialect for Doma. In this case, we use H2 database, so set
202+
203+
``` properties
204+
doma.dialect=h2
205+
```
206+
207+
in `application.properties`.
208+
209+
Property values can be suggested by `Ctrl + Space`.
210+
211+
<img width="60%" src="https://qiita-image-store.s3.amazonaws.com/0/1852/b6416edb-748c-54e4-a473-0fcce5870963.png" />
212+
213+
214+
<img width="60%" src="https://qiita-image-store.s3.amazonaws.com/0/1852/92179170-839a-d3be-d05b-18f8e4fa0f3c.png" />
215+
216+
Doma does not generate schema, so DDL script is needed. Create `src/main/resources/schema.sql` as follows:
217+
218+
``` sql
219+
CREATE TABLE reservation (
220+
id IDENTITY,
221+
NAME VARCHAR(50)
222+
);
223+
```
224+
225+
**Tip**:
226+
Executing `schema.sql` can be skipped by setting `spring.datasource.initialize=false`. This will be helpful in deploying.
227+
228+
Finally, run `main` method on `DemoApplication`, then the application will launch.
229+
230+
Access [http://localhost:8080](http://localhost:8080), the result of `selectAll.sql` will show.
231+
232+
<img width="80%" src="https://qiita-image-store.s3.amazonaws.com/0/1852/c962a9a6-8eae-fc2f-167f-86af07988e8a.png" />
233+
234+
235+
### Add a method
236+
237+
Add `selectByName` to try Doma's 2 way SQL.
238+
239+
``` java
240+
@ConfigAutowireable
241+
@Dao
242+
public interface ReservationDao {
243+
@Select
244+
List<Reservation> selectAll();
245+
246+
@Select
247+
List<Reservation> selectByName(String name);
248+
249+
@Insert
250+
@Transactional
251+
int insert(Reservation reservation);
252+
}
253+
```
254+
255+
Write the correspoinding SQL in `src/main/resources/META-INF/com/example/ReservationDao/selectByName.sql`.
256+
257+
``` sql
258+
SELECT
259+
id,
260+
name
261+
FROM reservation
262+
WHERE name LIKE /* @prefix(name) */'spring%' ESCAPE '$'
263+
```
264+
265+
Check the [doc](http://doma.readthedocs.org/ja/stable/expression/#id11) for the special expression in SQL comment.
266+
267+
This SQL can be executed as it is!
268+
269+
<img width="80%" src="https://qiita-image-store.s3.amazonaws.com/0/1852/2ec92660-9370-572e-8b54-eb169cf705f3.png" />
270+
271+
<img width="80%" src="https://qiita-image-store.s3.amazonaws.com/0/1852/07c3a4ea-0786-95a7-b812-2630ccd4889b.png" />
272+
273+
Add the following method to Controller and call `ReservationDao#selectByName`.
274+
275+
``` java
276+
@RequestMapping(path = "/", params = "name")
277+
List<Reservation> name(@RequestParam String name) {
278+
return reservationDao.selectByName(name);
279+
}
280+
```
281+
282+
<img width="80%" src="https://qiita-image-store.s3.amazonaws.com/0/1852/618907ba-bdc0-ad8b-e33e-c3ae2c6f64d6.png" />
283+
284+
<img width="80%" src="https://qiita-image-store.s3.amazonaws.com/0/1852/d8f0ff19-f88b-dcee-e478-9a7ae7bae549.png" />
285+
286+
[Source code](https://github.com/making/doma2-spring-boot-demo)
287+
288+
48289
## License
49290

50291
Licensed under the Apache License, Version 2.0.

0 commit comments

Comments
 (0)