Spring Boot Kotlin - Data JPA
ជំពូកនេះនឹងពន្យល់អ្នកពី Spring Data JPA's Dependency ជាអ្វីហើយអាចធ្វើអ្វីបានខ្លះនៅលើកម្មវិធី Spring Boot។
Spring Boot Data JPA
វាជាផ្នែកដ៏ធំមួយរបស់គ្រួសារនៃ Spring Data។ វាផ្តល់នូវលក្ខណៈងាយស្រួលក្នុងការ implement នូវ JPA repository ដើម្បីមកប្រើប្រាស់។ នៅពេលដែលអ្នកអាចប្រើប្រាស់នូវ JPA repository បានគឺអ្នកអាចធ្វើការបង្កើតទិន្នន័យ, កែប្រែទិន្នន័យ, លុបទិន្នន័យ, និងបង្ហាញទិន្នន័យពី table នៅក្នុង database បានយ៉ាងងាយស្រួល។
បើសិនជាអ្នកចង់ប្រើ dependency មួយនេះ អ្នកត្រូវបន្ថែមនូវ dependency មួយនេះនៅក្នុងឯកសារ build.gradle.kts:
dependencies {
  implementation("org.springframework.boot:spring-boot-starter-data-jpa")
}
បន្ទាប់ពីអ្នកបន្ថែមនូវ spring-boot-starter-data-jpa's dependency រួចរាល់គឺអ្នកត្រូវបន្ថែមនូវ dependency មួយទៀតដែលបញ្ជាក់ប្រភេទនៃ database ដែលអ្នកត្រូវប្រើ:
dependencies {
  runtimeOnly("org.postgresql:postgresql")
}
សម្រាប់ក្នុងមេរៀននេះគឺនឹងនាំអ្នកទៅប្រើប្រាស់ Database Postgresql។
JPA ជាមួយនឹងការចាប់ផ្តើមជាមួយនឹងកម្មវិធី Spring Boot
វាមានវិធីជាច្រើនក្នុងការចាប់ផ្តើមជាមួយនឹង JPA តែអ្វីដែលខាងយើងនឹងបង្ហាញអ្នក គឺការចាប់ផ្តើមជាមួយនឹងឯកសារ application.properties ស្ថិតនៅក្នុង src/main/resources/application.properties ហើយយើងនឹងធ្វើការប្តូរនូវប្រភេទឯកសារទៅជាឯកសារប្រភេទ yml វិញព្រោះឯកសារប្រភេទ yml អាចជួយយើងបានច្រើនទាក់ទងនឹងការកាត់បន្ថយនូវភាពច្រំដែលនៃការសរសេរ config។
spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/springboot-db
    username: springboot-db
    password: springboot-db
    driver-class-name: org.postgresql.Driver
  jpa:
    database: postgresql
    hibernate:
      ddl-auto: update
    database-platform: org.hibernate.dialect.PostgreSQLDialect
    show-sql: true
ចំណុចសំខាន់នៅក្នុងការសរសេរ config ខាងលើនេះគឺ url ដែលអ្នកត្រូវដាក់នូវ url របស់ database របស់អ្នក, username គឺអ្នកត្រូវដាក់នូវ username របស់ database, password គឺអ្នកត្រូវដាក់នូវ password របស់ database, driver-class-name គឺអ្នកត្រូវដាក់នូវ driver របស់ database, database គឺអ្នកត្រូវកំណត់នូវឈ្មោះរបស់ database ដែលអ្នកប្រើ, ddl-auto គឺអ្នកត្រូវកំណត់អំពីសកម្មភាពនៃ table ដែលនៅពេលដែលអ្នក run នូវ application ថាចង់ឲ្យ table បង្កើតថ្មីឬក៏មិនបង្កើតថ្មីទេ តែបើមានកែប្រែគឺត្រូវតែកែប្រែនៅលើ table ដូចគ្នា ហើយសម្រាប់ចំណុចនេះគឺយើងឲ្យតម្លៃ update គឺមានន័យថានៅពេលដែលយើង run នូវ application សារថ្មីគឺវានឹងមិនបង្កើតនូវ table ជាថ្មីនោះទេ តែបើមានអីកែប្រែ វានឹងកែប្រែ table, database-platform គឺអ្នកត្រូវកំណត់នូវប្រភេទនៃ database ដែលអ្នកប្រើ, show-sql គឺអ្នកដាក់នូវតម្លៃ true ឬក៏ false បើសិនជាអ្នកដាក់ true នោះនៅក្នុង console នឹងមាន log បង្ហាញមក តែបើ false វានឹងមិនបង្ហាញ log ទេ។
ចាប់ផ្តើមជាមួយ JPA
JPA មានពាក្យពេញគឺ Java Persistence API ដែលវាមានលក្ខណៈពិសេសត្រង់ថាអាចសរសេរកូដឲ្យមានអន្តរកម្មជាមួយនឹង ORM គឺ Object Relational Mapping។ ម៉្យាងវិញទៀត មុននឹងអាចប្រើប្រាស់ JPA បានអ្នកត្រូវប្រើប្រាស់នូវ Hibernate ដើម្បីបង្កើតជា ORM។ ដូច្នេះដើម្បីបង្កើតបានជា ORM គឺអ្នកត្រូវបង្កើតនូវ entity ហើយនៅពេលកម្មវិធីដំណើរការ entity នោះនឹងទៅបង្កើតជា table នៅក្នុង database ដោយស្វ័យប្រវត្តិ។
ការបង្កើត Entity
import javax.persistence.Entity
@Entity
open class Book {
   ...
}
ខាងលើនេះគឺជាទម្រង់នៃការបង្កើត Entity ហើយអ្នកប្រាកដជាឆ្ងល់ថា Entity គឺជាអ្វី? សម្រាប់ Entity វាជា POJOs(Plain Old Java Objects) Class មួយដែលពិពណ៍នាអំពីទិន្នន័យដែលអាចទាក់ទងទៅនឹង Database បាន។ សម្រាប់ Entity ផ្ទាល់គឺវាជា table នៅក្នុង Database។ ហើយនៅរាល់ instance នីមួយៗនៃ Entity គឺតំណាងឲ្យ row នីមួយៗនៅក្នុង table។
បន្ថែមពីនេះ ដើម្បីអាចបង្កើត Entity បានអ្នកត្រូវប្រើប្រាស់ Annotation @Entity នៅពីលើ Class នោះហើយសម្រាប់ Entity Class គឺត្រូវតែមាននូវ no-arg constructor និង primary key។ លើសពីនេះទៅទៀត សម្រាប់ Entity Class គឺវាមិនអាចជាប្រភេទ final បាននោះទេ ព្រោះ JPA implemenations ត្រូវការផ្តល់ជាមុខងារមួយចំនួនទៅឲ្យ Entity Class របស់អ្នក។
import javax.persistence.Entity
@Entity(name="book")
open class Book {
   ...
}
នៅខាងលើនេះអ្នកបានឃើញហើយថានៅក្នុង Annotation @Entity គឺមានអាគុយម៉ង់់ name ដែលវាប្រើសម្រាប់កំណត់ឈ្មោះទៅឲ្យ entity ហើយជាទូទៅឈ្មោះរបស់ entity គឺគេប្រើវានៅពេលដែលគេចង់ query ទិន្នន័យដោយប្រើ JPQL។
ចំណាំ៖ បើសិនជាអ្នកមិនបានកំណត់នូវអាគុយម៉ង់ name នោះទេ ដូច្នេះ JPA នឹងធ្វើការយកឈ្មោះរបស់ class ទៅប្រើប្រាស់តែម្តង។
import javax.persistence.Entity
import javax.persistence.Id
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
@Entity
open class Book {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private var id: Long
  private var name: String
  // getters and setters
}
នៅខាងលើនេះគឺជាការកំណត់នូវ Primary Key ទៅឲ្យ Entity នីមួយៗ ហើយដើម្បីអាចកំណត់នូវ Primary Key បានគឺអ្នកត្រូវប្រើប្រាស់ Annotation @Id នៅលើ attribute ណាដែលអ្នកចង់ដាក់ជា Primary Key ហើយលើសពីនេះទៅទៀតគឺអ្នកអាចប្រើនូវប្រភេទ generator បានសម្រាប់ primary key ដោយប្រើប្រាស់ Annotation @GeneratedValue ហើយអាគុយម៉ង់់ strategy ហើយតម្លៃមានដូចជា AUTO, TABLE, SEQUENCE, និង IDENTITY ហើយជានិច្ចកាលគេតែងតែប្រើប្រាស់ AUTO ឬក៏ IDENTITY ដែល AUTO គឺវានឹងធ្វើការ generate នូវ id បែបជា auto គឺ generate ទៅតាមម៉ាស៊ីន រីឯ IDENTITY គឺវានឹងធ្វើការ generate នូវ id បែបជាកើនម្តងមួយឯកតា។
import javax.persistence.Entity
import javax.persistence.Table
@Entity
@Table(name="books")
open class Book {
   ...
}
នៅខាងលើនេះគឺអ្នកនឹងមកមើលទាក់ទងនឹង Annotation @Table វិញម្តងដែល Annotation មួយនេះគឺប្រើសម្រាប់ដាក់ឈ្មោះទៅឲ្យ table នៅក្នុង database ហើយអ្នកអាចដាក់ឈ្មោះបានលុះត្រាតែប្រើប្រាស់នូវអាគុយម៉ង់ name ហើយលើសពីនេះទៅទៀត អ្នកក៏អាចកំណត់បន្ថែមទាក់ទងនឹង schema ដែលអ្នកចង់ដាក់ឈ្មោះទៅឲ្យ table ដែលមានដូចខាងក្រោម៖
import javax.persistence.Entity
import javax.persistence.Table
@Entity
@Table(name="books", schema="public")
open class Book {
   ...
}
ចំណាំ៖ បើអ្នកមិនបានប្រើប្រាស់ Annotation @Table ទេ នោះ JPA នឹងធ្វើការយកឈ្មោះរបស់ class ទៅបង្កើតជាឈ្មោះរបស់ table តែម្តង។
import javax.persistence.Entity
import javax.persistence.Id
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Column
@Entity
@Table(name="books")
open class Book {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private var id: Long
  @Column(name="book_name", length=50, nullable=false, unique=false)
  private var name: String
  @Column(name="book_description", columnDefinition="varchar(500) default 'Hello'")
  private var description: String
  // getters and setters
}
ខាងលើនេះគឺអ្នកនឹងមកមើលទាក់ទងនឹង Annotation @Column ដែលប្រើសម្រាប់កំណត់នូវព័ត៌មានមួយចំនួនទៅឲ្យ columns នីមួយៗនៅក្នុង table ហើយការកំណត់គឺមានច្រើន តែក្នុងនេះយើងបង្ហាញអ្នកតែអ្វីដែលគេប្រើច្រើនតែប៉ុណ្ណោះ ដែលមានដូចជា៖
- កំណត់ឈ្មោះទៅឲ្យ 
columnដោយប្រើប្រាស់អាគុយម៉ង់nameហើយប្រភេទទិន្នន័យរបស់អាគុយម៉ង់នេះជាStringហើយបើសិនជាអ្នកមិនបានកំណត់ទេ នោះ JPA នឹងយកឈ្មោះរបស់attributeទៅបង្កើតជាឈ្មោះរបស់columnតែម្តង - កំណត់លក្ខណៈមិនអាចស្ទួនទៅឲ្យ 
columnដោយប្រើប្រាស់អាគុយម៉ង់uniqueហើយប្រភេទទិន្នន័យរបស់អាគុយម៉ង់នេះជាBooleanដូច្នេះបើអ្នកចង់ឲ្យcolumnមួយណាមានលក្ខណៈមិនអាចស្ទួន អ្នកអាចកំណត់តម្លៃtrueទៅកាន់អាគុយម៉ង់នេះបាន ហើយបើសិនជាអ្នកមិនបានកំណត់ទេ នោះcolumnគឺអាចមានតម្លៃស្ទួនគ្នាបាន - កំណត់លក្ខណៈទទេទៅឲ្យ 
columnដោយប្រើប្រាស់អាគុយម៉ង់nullableហើយប្រភេទទិន្នន័យរបស់អាគុយម៉ង់នេះជាBooleanដូច្នេះបើអ្នកចង់ឲ្យcolumnមិនអាចទទេបាន អ្នកអាចកំណត់តម្លៃfalseទៅកាន់អាគុយម៉ង់នេះបាន ហើយបើសិនជាអ្នកមិនបានកំណត់ទេ នោះcolumnគឺអាចមានតម្លៃទទេបាន - កំណត់ប្រវែងទៅឲ្យ 
columnដោយប្រើប្រាស់អាគុយម៉ង់lengthហើយប្រភេទទិន្នន័យរបស់អាគុយម៉ង់នេះជាIntហើយបើសិនជាអ្នកមិនបានកំណត់ទេ នោះ JPA នឹងយកតម្លៃដើមទៅកំណត់ - កំណត់លក្ខណៈការពារមិនឲ្យមានការបង្កើតនិងការកែប្រែទៅឲ្យ 
columnដោយប្រើប្រាស់អាគុយម៉ង់insertableនិងupdatableដែលinsertableធ្វើការការពារនឹងមិនឲ្យមានការបន្ថែមតម្លៃនៅក្នុងcolumnបាននៅពេលoperationរបស់ SQL កំពុងតែinsertហើយបើអ្នកចង់បានការការពារចឹង អាចកំំណត់តម្លៃfalseទៅកាន់អាគុយម៉ង់នេះបាន រីឯupdatableគឺដូចនឹងinsertableដែរតែខុសត្រង់updatableត្រូវប្រើដើម្បីការពារនៅពេលoperationរបស់ SQL កំពុងតែupdateវិញ ហើយលើសពីនេះសម្រាប់ប្រភេទទិន្នន័យវាទាំងពីរនេះគឺBooleanហើយបើសិនជាអ្នកមិនបានកំណត់ពួកវាទេ នោះcolumnគឺអាចបន្ថែមតម្លៃចូលធម្មតា ហើយគ្មានការការពារអីនោះទេ - កំណត់លក្ខណៈ SQL DDL ទៅឲ្យ 
columnដោយប្រើប្រាស់អាគុយម៉ង់columnDefinitionហើយប្រភេទទិន្នន័យរបស់អាគុយម៉ង់នេះជាStringហើយបើសិនជាអ្នកមិនបានកំណត់ទេ នោះវានឹងយកតម្លៃដើមមកប្រើធម្មតា