Doma2を使ってみる(その3)
主要なクラス
基本クラス
Doma では、データベースのカラム型にマッピング可能なJava型を 基本クラス と呼びます。
エンティティクラスやドメインクラス、DAOインターフェースで使用する
ドメインクラス
ドメインクラスは、カラムにマップできるユーザー定義のクラスです。ドメインクラスの使用はオプションです。
エンティティクラスやDAOインターフェースで使用する
内部ドメインクラス
クラスに @Domain アノテーションを付けられる場合のみ、内部ドメインクラスとして扱われます。
外部ドメインクラス
クラスに @Domain アノテーションを付けられない場合、外部ドメインクラスとして扱われます。
エンティティクラス
エンティティクラスはデータベースのテーブルまたはクエリの結果セットに対応します。
DAOインターフェース
DAOインターフェースは、データベースにアクセスするためのメソッドを宣言します。
クエリ
検索
SELECTステートメントを使用して検索を実行するには、DAOメソッドに @Select アノテーションを付けます。
検索条件
検索条件にはメソッドのパラメータを使用します。使用可能なパラメータの型は次のとおりです。
- 基本クラス
- ドメインクラス
- 任意の型
- 基本クラス や ドメインクラス や任意の型を要素とするjava.util.Optional
- 基本クラス や ドメインクラス や任意の型を要素とするjava.util.Iterable
- java.util.OptionalInt
- java.util.OptionalLong
- java.util.OptionalDouble
基本クラスで検索してみる
テーブルの作成
sql schema.sql
create table t_product (
id varchar(20) primary key,
name varchar(100),
price integer,
stock integer
);
テストデータの投入
sql data.sql
insert into t_product (id, name, price, stock) values ('p01', '消しゴム', 100, 10);
内部ドメインクラス
// 内部ドメインクラス
@Domain(valueType = String::class)
data class ProductId(val value: String)
DAOインターフェース
@Dao
@ConfigAutowireable
interface ProductDao {
@Select
fun selectById(id: String): ProductEntity // 検索条件に基本クラスを使用
}
SQLファイル
sql selectById.sql
select * from t_product where id = /* id */'1'
mainメソッド
@ComponentScan(basePackages = ["com.okr.shopping", "org.seasar.doma"])
@Configuration
class ShoppingApplication {
@Bean
fun dataSource(): DataSource {
val dataSource = EmbeddedDatabaseBuilder()
.addScripts("schema.sql", "data.sql")
.setType(EmbeddedDatabaseType.H2).build()
return dataSource
}
}
fun main(args: Array<String>) {
val context: ApplicationContext = AnnotationConfigApplicationContext(
ShoppingApplication::class.java)
val productDao: ProductDao = context.getBean(ProductDao::class.java)
val product: ProductEntity = productDao.selectByProductId(ProductId("p01"))
System.out.println("[外部ドメインクラスでの検索結果]\nproductId:" + product.id + "\nname:" + product.name + "\nprice:" + product.price +"\nstock:" + product.stock)
}
実行結果
> Task :bootRun
17:50:32.080 [main] INFO org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory -- Starting embedded database: url='jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
17:50:32.173 [main] WARN org.seasar.doma.boot.autoconfigure.DomaAutoConfiguration -- StandardDialect was selected because no explicit configuration and it is not possible to guess from 'spring.datasource.url property'
[外部ドメインクラスでの検索結果]
productId:p01
name:消しゴム
price:100
stock:10
内部ドメインクラスで検索してみる
内部ドメインクラス
Kotlinでドメインクラスを作る場合は
// 内部ドメインクラス
@Domain(valueType = String::class)
data class ProductId(val value: String)
DAOインターフェース
@Dao
@ConfigAutowireable
interface ProductDao {
@Select
fun selectByProductId(productId: ProductId): ProductEntity // 検索条件にドメインクラスを使用
}
SQLファイル
sql selectByProductId.sql
select * from t_product where id = /* productId */'1'
mainメソッド
@ComponentScan(basePackages = ["com.okr.shopping", "org.seasar.doma"])
@Configuration
class ShoppingApplication {
@Bean
fun dataSource(): DataSource {
val dataSource = EmbeddedDatabaseBuilder()
.addScripts("schema.sql", "data.sql")
.setType(EmbeddedDatabaseType.H2).build()
return dataSource
}
}
fun main(args: Array<String>) {
val context: ApplicationContext = AnnotationConfigApplicationContext(
ShoppingApplication::class.java)
val productDao: ProductDao = context.getBean(ProductDao::class.java)
val domainProductId = ProductId("p01")
val product2: ProductEntity = productDao.selectByProductId(domainProductId)
System.out.println("[ドメインクラスでの検索結果]\nproductId:" + product2.id + "\nname:" + product2.name + "\nprice:" + product2.price +"\nstock:" + product2.stock)
}
実行結果
> Task :bootRun
17:50:32.080 [main] INFO org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory -- Starting embedded database: url='jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
17:50:32.173 [main] WARN org.seasar.doma.boot.autoconfigure.DomaAutoConfiguration -- StandardDialect was selected because no explicit configuration and it is not possible to guess from 'spring.datasource.url property'
[ドメインクラスでの検索結果]
productId:p01
name:消しゴム
price:100
stock:10
外部ドメインクラスで検索してみる
外部ドメインクラス
// 外部ドメインクラス
data class ProductId(val value: String)
DomainConvertersクラス
@DomainConverters(ProductIdConverter::class)
class DomainConvertersProvider
ExternalDomainクラス
@ExternalDomain
class ProductIdConverter: DomainConverter<ProductId, String> {
override fun fromDomainToValue(productId: ProductId): String {
return productId.value
}
override fun fromValueToDomain(value: String): ProductId {
return ProductId(value)
}
}
build.gradle.kts
// 以下を追加
kapt {
arguments {
arg("doma.domain.converters", "com.okr.shopping.infla.doma.domain.DomainConvertersProvider")
}
}
DAOインターフェース
@Dao
@ConfigAutowireable
interface ProductDao {
@Select
fun selectByProductId(productId: ProductId): ProductEntity // 検索条件に外部ドメインクラスを使用
}
SQLファイル
sql selectByProductId.sql
select * from t_product where id = /* productId */'1'
mainメソッド
@ComponentScan(basePackages = ["com.okr.shopping", "org.seasar.doma"])
@Configuration
class ShoppingApplication {
@Bean
fun dataSource(): DataSource {
val dataSource = EmbeddedDatabaseBuilder()
.addScripts("schema.sql", "data.sql")
.setType(EmbeddedDatabaseType.H2).build()
return dataSource
}
}
fun main(args: Array<String>) {
val context: ApplicationContext = AnnotationConfigApplicationContext(
ShoppingApplication::class.java)
val productDao: ProductDao = context.getBean(ProductDao::class.java)
val product: ProductEntity = productDao.selectByProductId(ProductId("p01"))
System.out.println("[任意の型での検索結果]\nproductId:" + product.id + "\nname:" + product.name + "\nprice:" + product.price +"\nstock:" + product.stock)
}
実行結果
> Task :bootRun
18:35:27.951 [main] INFO org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory -- Starting embedded database: url='jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
18:35:28.038 [main] WARN org.seasar.doma.boot.autoconfigure.DomaAutoConfiguration -- StandardDialect was selected because no explicit configuration and it is not possible to guess from 'spring.datasource.url property'
[任意の型での検索結果]
productId:p01
name:消しゴム
price:100
stock:10
任意の型で検索してみる
任意の型
class Product : Serializable {
var id: String? = null
var name: String? = null
var price: Int? = null
var stock: Int? = null
}
DAOインターフェース
@Dao
@ConfigAutowireable
interface ProductDao {
@Select
fun selectByProduct(product: Product): ProductEntity// 検索条件に任意のクラスを使用
}
SQLファイル
sql selectByProductId.sql
select * from t_product where id = /* product.id */'1'
mainメソッド
@ComponentScan(basePackages = ["com.okr.shopping", "org.seasar.doma"])
@Configuration
class ShoppingApplication {
@Bean
fun dataSource(): DataSource {
val dataSource = EmbeddedDatabaseBuilder()
.addScripts("schema.sql", "data.sql")
.setType(EmbeddedDatabaseType.H2).build()
return dataSource
}
}
fun main(args: Array<String>) {
val context: ApplicationContext = AnnotationConfigApplicationContext(
ShoppingApplication::class.java)
val productDao: ProductDao = context.getBean(ProductDao::class.java)
val product: ProductEntity = productDao.selectByProduct(Product().apply {
id = "p01"
})
System.out.println("[任意の型での検索結果]\nproductId:" + product.id + "\nname:" + product.name + "\nprice:" + product.price +"\nstock:" + product.stock)
}
実行結果
> Task :bootRun
16:32:50.173 [main] INFO org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory -- Starting embedded database: url='jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
16:32:50.260 [main] WARN org.seasar.doma.boot.autoconfigure.DomaAutoConfiguration -- StandardDialect was selected because no explicit configuration and it is not possible to guess from 'spring.datasource.url property'
任意の型での検索結果]
productId:p01
name:消しゴム
price:100
stock:10
IN句で検索してみる
DAOインターフェース
@Dao
@ConfigAutowireable
interface ProductDao {
@Select
fun selectByIds(ids: List<String>): List<ProductEntity> // 検索条件にListを使用
}
SQLファイル
sql selectByIds.sql
select * from t_product where id in /* ids */('1', '2')
mainメソッド
fun main(args: Array<String>) {
val context: ApplicationContext = AnnotationConfigApplicationContext(
ShoppingApplication::class.java)
val productDao: ProductDao = context.getBean(ProductDao::class.java)
val products: List<ProductEntity> = productDao.selectByIds(listOf("p01", "p02", "p03"))
products.forEach { product ->
System.out.println("[任意の型での検索結果]\nproductId:" + product.id + "\nname:" + product.name + "\nprice:" + product.price +"\nstock:" + product.stock)
}
}
実行結果
> Task :bootRun
16:41:11.977 [main] INFO org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory -- Starting embedded database: url='jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
16:41:12.069 [main] WARN org.seasar.doma.boot.autoconfigure.DomaAutoConfiguration -- StandardDialect was selected because no explicit configuration and it is not possible to guess from 'spring.datasource.url property'
[任意の型での検索結果]
productId:p01
name:消しゴム
price:100
stock:10
[任意の型での検索結果]
productId:p02
name:ノート
price:200
stock:20
[任意の型での検索結果]
productId:p03
name:pname03
price:300
stock:30