Reference by 실전! 스프링 부트와 JPA 활용 1 - 웹 애플리케이션 개발
Settings
- Create project
- Spring boot starter
- dependencies : web, thymeleaf, jpa, h2, lombok, validation, devtools
-
Download lombok plugin
- build.gradle
- Add spring-boot-devtools(for recompile)
- Add P6Spy
- h2 database
- Download
- Go to h2/bin and excute h2-1.4.200.jar(os : window)
- Connect DB
- Domain
- Connect DB
-
@ManyToOne
,@OneToMany
Don’t use@ManyToMany
. It cannot add colums in middle table.
So create middle entity and mapping with@ManyToOne
and@OneToMany
.
- Download Bootstrap
View
- Thymeleaf Template Engine
- Spring Boot thymeleaf View Name
(resources:templates/) + {ViewName} + (.html)
- Spring Boot thymeleaf View Name
- Template location
resource/templates/hello.html
- Skip
null
when use ?
Entity
-
fetch = FetchType.LAZY
-
EAGER
is hard to expect and follow which SQL will excute. - To check related entities in DB together, use
fetch
,join
or Entity Graph Function. - Need to set
fetch = FetchType.LAZY
in@OneToOne
,@ManyToOne
.
-
Application Architecture
- Hierarchy Structure
- controller, web: web level
- service: business logic, transaction process
- repository: use JPA directly, use entity manager
- domain: gather entities
Member
Repository
-
@Repository
: Register as a spring bin -
@PersistenceContext
: InsertEntityManager
-
@PersistenceUnit
: InsertEntityManagerFactory
Service
-
@Transactional
: Transaction, perpetuity context-
readOnly=true
: Use for read-only methods
-
-
@Autowired
: Use for many Generator Injection- If there is only one Generator, it can be skipped
-
final
: Use to check error unsetted~Repository
Test
-
@RunWith(SpringRunner.class)
: Combinate Spring and test -
@SpringBootTest
: Excute Spring Boot first, then test -
@Transactional
: Support repeatable test- Rollback after the test
-
//Given
,//When
,//Then
- Setting for Test Case
- Run in isolated environment and initialize data at end
- Use Memory DB
- Add Setting file for Test
test/resources/application.yml
Item
Entity
-
addStock()
: Increase stock quantity when modify wtock quantity or cancel order -
removeStock()
: Decrease stock quantity. When stock is lack, generate error.
Repository
-
save()
- Execute
persist()
for newid
- Excutee
merge()
for existedid
- Execute
Order
Entity
-
createdOrder()
: Create Order Entity -
cancle()
: Change order status to cancle
Repository
-
findAll(OrderSearch orderSearch)
: Create queries dynamically in search condition to check order entities
Service
-
order()
: Create Order Entity -
cancleOrder()
: Request cancel to Order -
findOrders()
: Search Order Entity withOrderSearch
conditionDomain Model Pattern: Entity has business logic
Transaction Script Pattern: Service has business logic
Test
- Generate
NotEnoughStockException
when order exceeds stock quantity
OrderItem
Entity
-
createOrderItem()
: Create OrderItem Entity and callitem.removeStock(count)
to decrease stock quantity as much as order -
cancle()
: CallgetItem().addStock(count)
to increase stock quantity as much as cancled order -
getTotalPrice()
: Return count * price
Controller
- Save
Model
object to send View - Press
Submit
, then request url with POST method- After the change, redirect
redirect:/~
- Excute method
- After the change, redirect
- Press
Modify
, then request url with GET method- Execute
updateItemForm()
method and callitemService.findOne(itemId)
- send result to View
- Execute
- Always use change detection when changing an entity.
UI
- Main
- Member
- Product
- Order
Demo Video
- Member
- Product
- Modify
- Order
- Cancle
- Search orders