Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
라이앤캐처스 크루공간
허창호
연습용
Commits
969fb9e8
Commit
969fb9e8
authored
Feb 06, 2022
by
madvirus
Browse files
Initial Commit
parents
Changes
187
Hide whitespace changes
Inline
Side-by-side
src/main/java/com/myshop/catalog/command/domain/product/Option.java
0 → 100644
View file @
969fb9e8
package
com.myshop.catalog.command.domain.product
;
import
javax.persistence.Column
;
import
javax.persistence.Embeddable
;
@Embeddable
public
class
Option
{
@Column
(
name
=
"option_value"
)
private
String
value
;
@Column
(
name
=
"option_title"
)
private
String
title
;
private
Option
()
{
}
public
Option
(
String
value
,
String
title
)
{
this
.
value
=
value
;
this
.
title
=
title
;
}
public
String
getValue
()
{
return
value
;
}
public
String
getTitle
()
{
return
title
;
}
}
src/main/java/com/myshop/catalog/command/domain/product/Product.java
0 → 100644
View file @
969fb9e8
package
com.myshop.catalog.command.domain.product
;
import
com.myshop.catalog.command.domain.category.CategoryId
;
import
com.myshop.common.jpa.MoneyConverter
;
import
com.myshop.common.model.Money
;
import
javax.persistence.*
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Set
;
@Entity
@Table
(
name
=
"product"
)
public
class
Product
{
@EmbeddedId
private
ProductId
id
;
@ElementCollection
(
fetch
=
FetchType
.
LAZY
)
@CollectionTable
(
name
=
"product_category"
,
joinColumns
=
@JoinColumn
(
name
=
"product_id"
))
private
Set
<
CategoryId
>
categoryIds
;
private
String
name
;
@Convert
(
converter
=
MoneyConverter
.
class
)
private
Money
price
;
private
String
detail
;
@OneToMany
(
cascade
=
{
CascadeType
.
PERSIST
,
CascadeType
.
REMOVE
},
orphanRemoval
=
true
,
fetch
=
FetchType
.
LAZY
)
@JoinColumn
(
name
=
"product_id"
)
@OrderColumn
(
name
=
"list_idx"
)
private
List
<
Image
>
images
=
new
ArrayList
<>();
protected
Product
()
{
}
public
Product
(
ProductId
id
,
String
name
,
Money
price
,
String
detail
,
List
<
Image
>
images
)
{
this
.
id
=
id
;
this
.
name
=
name
;
this
.
price
=
price
;
this
.
detail
=
detail
;
this
.
images
.
addAll
(
images
);
}
public
ProductId
getId
()
{
return
id
;
}
public
String
getName
()
{
return
name
;
}
public
Money
getPrice
()
{
return
price
;
}
public
String
getDetail
()
{
return
detail
;
}
public
List
<
Image
>
getImages
()
{
return
Collections
.
unmodifiableList
(
images
);
}
public
void
changeImages
(
List
<
Image
>
newImages
)
{
images
.
clear
();
images
.
addAll
(
newImages
);
}
public
String
getFirstIamgeThumbnailPath
()
{
if
(
images
==
null
||
images
.
isEmpty
())
return
null
;
return
images
.
get
(
0
).
getThumbnailUrl
();
}
}
src/main/java/com/myshop/catalog/command/domain/product/ProductId.java
0 → 100644
View file @
969fb9e8
package
com.myshop.catalog.command.domain.product
;
import
javax.persistence.Access
;
import
javax.persistence.AccessType
;
import
javax.persistence.Column
;
import
javax.persistence.Embeddable
;
import
java.io.Serializable
;
import
java.util.Objects
;
@Embeddable
@Access
(
AccessType
.
FIELD
)
public
class
ProductId
implements
Serializable
{
@Column
(
name
=
"product_id"
)
private
String
id
;
protected
ProductId
()
{
}
public
ProductId
(
String
id
)
{
this
.
id
=
id
;
}
public
String
getId
()
{
return
id
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
ProductId
productId
=
(
ProductId
)
o
;
return
Objects
.
equals
(
id
,
productId
.
id
);
}
@Override
public
int
hashCode
()
{
return
Objects
.
hash
(
id
);
}
public
static
ProductId
of
(
String
id
)
{
return
new
ProductId
(
id
);
}
}
src/main/java/com/myshop/catalog/command/domain/product/ProductRepository.java
0 → 100644
View file @
969fb9e8
package
com.myshop.catalog.command.domain.product
;
import
org.springframework.data.repository.Repository
;
import
java.util.Optional
;
public
interface
ProductRepository
extends
Repository
<
Product
,
ProductId
>
{
void
save
(
Product
product
);
Optional
<
Product
>
findById
(
ProductId
id
);
void
flush
();
}
src/main/java/com/myshop/catalog/query/category/CategoryData.java
0 → 100644
View file @
969fb9e8
package
com.myshop.catalog.query.category
;
import
com.myshop.catalog.command.domain.category.CategoryId
;
import
javax.persistence.Column
;
import
javax.persistence.EmbeddedId
;
import
javax.persistence.Entity
;
import
javax.persistence.Table
;
@Entity
@Table
(
name
=
"category"
)
public
class
CategoryData
{
@EmbeddedId
private
CategoryId
id
;
@Column
(
name
=
"name"
)
private
String
name
;
protected
CategoryData
()
{
}
public
CategoryData
(
CategoryId
id
,
String
name
)
{
this
.
id
=
id
;
this
.
name
=
name
;
}
public
CategoryId
getId
()
{
return
id
;
}
public
String
getName
()
{
return
name
;
}
}
src/main/java/com/myshop/catalog/query/category/CategoryDataDao.java
0 → 100644
View file @
969fb9e8
package
com.myshop.catalog.query.category
;
import
com.myshop.catalog.command.domain.category.CategoryId
;
import
org.springframework.data.repository.Repository
;
import
java.util.List
;
import
java.util.Optional
;
public
interface
CategoryDataDao
extends
Repository
<
CategoryData
,
CategoryId
>
{
Optional
<
CategoryData
>
findById
(
CategoryId
id
);
List
<
CategoryData
>
findAll
();
}
src/main/java/com/myshop/catalog/query/product/CategoryProduct.java
0 → 100644
View file @
969fb9e8
package
com.myshop.catalog.query.product
;
import
com.myshop.catalog.query.category.CategoryData
;
import
java.util.List
;
public
class
CategoryProduct
{
private
CategoryData
category
;
private
List
<
ProductSummary
>
items
;
private
int
page
;
private
int
size
;
private
long
totalCount
;
private
int
totalPages
;
public
CategoryProduct
(
CategoryData
category
,
List
<
ProductSummary
>
items
,
int
page
,
int
size
,
long
totalCount
,
int
totalPages
)
{
this
.
category
=
category
;
this
.
items
=
items
;
this
.
page
=
page
;
this
.
size
=
size
;
this
.
totalCount
=
totalCount
;
this
.
totalPages
=
totalPages
;
}
public
CategoryData
getCategory
()
{
return
category
;
}
public
List
<
ProductSummary
>
getItems
()
{
return
items
;
}
public
int
getPage
()
{
return
page
;
}
public
int
getSize
()
{
return
size
;
}
public
long
getTotalCount
()
{
return
totalCount
;
}
public
int
getTotalPages
()
{
return
totalPages
;
}
}
src/main/java/com/myshop/catalog/query/product/ImageData.java
0 → 100644
View file @
969fb9e8
package
com.myshop.catalog.query.product
;
import
javax.persistence.Column
;
import
java.time.LocalDateTime
;
public
class
ImageData
{
@Column
(
name
=
"image_path"
)
private
String
path
;
private
LocalDateTime
uploadTime
;
}
src/main/java/com/myshop/catalog/query/product/ProductData.java
0 → 100644
View file @
969fb9e8
package
com.myshop.catalog.query.product
;
import
com.myshop.catalog.command.domain.category.CategoryId
;
import
com.myshop.catalog.command.domain.product.Image
;
import
com.myshop.catalog.command.domain.product.ProductId
;
import
com.myshop.common.jpa.MoneyConverter
;
import
com.myshop.common.model.Money
;
import
javax.persistence.*
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Set
;
@Entity
@Table
(
name
=
"product"
)
public
class
ProductData
{
@EmbeddedId
private
ProductId
id
;
@ElementCollection
@CollectionTable
(
name
=
"product_category"
,
joinColumns
=
@JoinColumn
(
name
=
"product_id"
))
private
Set
<
CategoryId
>
categoryIds
;
private
String
name
;
@Convert
(
converter
=
MoneyConverter
.
class
)
private
Money
price
;
private
String
detail
;
// TODO 목록에서 사용할 것
@OneToMany
(
cascade
=
{
CascadeType
.
PERSIST
,
CascadeType
.
REMOVE
},
orphanRemoval
=
true
,
fetch
=
FetchType
.
EAGER
)
@JoinColumn
(
name
=
"product_id"
)
@OrderColumn
(
name
=
"list_idx"
)
private
List
<
Image
>
images
=
new
ArrayList
<>();
protected
ProductData
()
{
}
public
ProductData
(
ProductId
id
,
String
name
,
Money
price
,
String
detail
,
List
<
Image
>
images
)
{
this
.
id
=
id
;
this
.
name
=
name
;
this
.
price
=
price
;
this
.
detail
=
detail
;
this
.
images
.
addAll
(
images
);
}
public
ProductId
getId
()
{
return
id
;
}
public
String
getName
()
{
return
name
;
}
public
Money
getPrice
()
{
return
price
;
}
public
String
getDetail
()
{
return
detail
;
}
public
List
<
Image
>
getImages
()
{
return
Collections
.
unmodifiableList
(
images
);
}
public
String
getFirstIamgeThumbnailPath
()
{
if
(
images
==
null
||
images
.
isEmpty
())
return
null
;
return
images
.
get
(
0
).
getThumbnailUrl
();
}
}
src/main/java/com/myshop/catalog/query/product/ProductDataDao.java
0 → 100644
View file @
969fb9e8
package
com.myshop.catalog.query.product
;
import
com.myshop.catalog.command.domain.category.CategoryId
;
import
com.myshop.catalog.command.domain.product.ProductId
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.data.repository.Repository
;
import
java.util.Optional
;
public
interface
ProductDataDao
extends
Repository
<
ProductData
,
ProductId
>
{
Optional
<
ProductData
>
findById
(
ProductId
id
);
Page
<
ProductData
>
findByCategoryIdsContains
(
CategoryId
id
,
Pageable
pageable
);
}
src/main/java/com/myshop/catalog/query/product/ProductQueryService.java
0 → 100644
View file @
969fb9e8
package
com.myshop.catalog.query.product
;
import
com.myshop.catalog.NoCategoryException
;
import
com.myshop.catalog.command.domain.category.CategoryId
;
import
com.myshop.catalog.command.domain.product.ProductId
;
import
com.myshop.catalog.query.category.CategoryData
;
import
com.myshop.catalog.query.category.CategoryDataDao
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.List
;
import
java.util.Optional
;
import
static
java
.
util
.
stream
.
Collectors
.
toList
;
@Service
public
class
ProductQueryService
{
private
ProductDataDao
productDataDao
;
private
CategoryDataDao
categoryDataDao
;
public
ProductQueryService
(
ProductDataDao
productDataDao
,
CategoryDataDao
categoryDataDao
)
{
this
.
productDataDao
=
productDataDao
;
this
.
categoryDataDao
=
categoryDataDao
;
}
@Transactional
public
CategoryProduct
getProductInCategory
(
Long
categoryId
,
int
page
,
int
size
)
{
CategoryData
category
=
categoryDataDao
.
findById
(
new
CategoryId
(
categoryId
))
.
orElseThrow
(()
->
new
NoCategoryException
());
Page
<
ProductData
>
productPage
=
productDataDao
.
findByCategoryIdsContains
(
category
.
getId
(),
Pageable
.
ofSize
(
size
).
withPage
(
page
-
1
));
return
new
CategoryProduct
(
category
,
toSummary
(
productPage
.
getContent
()),
page
,
productPage
.
getSize
(),
productPage
.
getTotalElements
(),
productPage
.
getTotalPages
());
}
private
List
<
ProductSummary
>
toSummary
(
List
<
ProductData
>
products
)
{
return
products
.
stream
().
map
(
prod
->
new
ProductSummary
(
prod
.
getId
().
getId
(),
prod
.
getName
(),
prod
.
getPrice
().
getValue
(),
prod
.
getFirstIamgeThumbnailPath
())).
collect
(
toList
());
}
public
Optional
<
ProductData
>
getProduct
(
String
productId
)
{
return
productDataDao
.
findById
(
new
ProductId
(
productId
));
}
}
src/main/java/com/myshop/catalog/query/product/ProductSummary.java
0 → 100644
View file @
969fb9e8
package
com.myshop.catalog.query.product
;
public
class
ProductSummary
{
private
String
id
;
private
String
name
;
private
int
price
;
private
String
image
;
public
ProductSummary
(
String
productId
,
String
name
,
int
price
,
String
image
)
{
this
.
id
=
productId
;
this
.
name
=
name
;
this
.
price
=
price
;
this
.
image
=
image
;
}
public
String
getId
()
{
return
id
;
}
public
String
getName
()
{
return
name
;
}
public
int
getPrice
()
{
return
price
;
}
public
String
getImage
()
{
return
image
;
}
}
src/main/java/com/myshop/catalog/ui/ProductController.java
0 → 100644
View file @
969fb9e8
package
com.myshop.catalog.ui
;
import
com.myshop.catalog.query.category.CategoryData
;
import
com.myshop.catalog.query.category.CategoryDataDao
;
import
com.myshop.catalog.query.product.CategoryProduct
;
import
com.myshop.catalog.query.product.ProductData
;
import
com.myshop.catalog.query.product.ProductQueryService
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.util.List
;
import
java.util.Optional
;
@Controller
public
class
ProductController
{
private
CategoryDataDao
categoryDataDao
;
private
ProductQueryService
productQueryService
;
public
ProductController
(
CategoryDataDao
categoryDataDao
,
ProductQueryService
productQueryService
)
{
this
.
categoryDataDao
=
categoryDataDao
;
this
.
productQueryService
=
productQueryService
;
}
@RequestMapping
(
"/categories"
)
public
String
categories
(
ModelMap
model
)
{
List
<
CategoryData
>
categories
=
categoryDataDao
.
findAll
();
model
.
addAttribute
(
"categories"
,
categories
);
return
"category/categoryList"
;
}
@RequestMapping
(
"/categories/{categoryId}"
)
public
String
list
(
@PathVariable
(
"categoryId"
)
Long
categoryId
,
@RequestParam
(
name
=
"page"
,
required
=
false
,
defaultValue
=
"1"
)
int
page
,
ModelMap
model
)
{
CategoryProduct
productInCategory
=
productQueryService
.
getProductInCategory
(
categoryId
,
page
,
10
);
model
.
addAttribute
(
"productInCategory"
,
productInCategory
);
return
"category/productList"
;
}
@RequestMapping
(
"/products/{productId}"
)
public
String
detail
(
@PathVariable
(
"productId"
)
String
productId
,
ModelMap
model
,
HttpServletResponse
response
)
throws
IOException
{
Optional
<
ProductData
>
product
=
productQueryService
.
getProduct
(
productId
);
if
(
product
.
isPresent
())
{
model
.
addAttribute
(
"product"
,
product
.
get
());
return
"category/productDetail"
;
}
else
{
response
.
sendError
(
HttpServletResponse
.
SC_NOT_FOUND
);
return
null
;
}
}
}
src/main/java/com/myshop/common/ValidationError.java
0 → 100644
View file @
969fb9e8
package
com.myshop.common
;
public
class
ValidationError
{
private
String
name
;
private
String
code
;
public
ValidationError
(
String
name
,
String
code
)
{
this
.
name
=
name
;
this
.
code
=
code
;
}
public
String
getName
()
{
return
name
;
}
public
String
getCode
()
{
return
code
;
}
public
boolean
hasName
()
{
return
name
!=
null
;
}
public
static
ValidationError
of
(
String
code
)
{
return
new
ValidationError
(
null
,
code
);
}
public
static
ValidationError
of
(
String
name
,
String
code
)
{
return
new
ValidationError
(
name
,
code
);
}
}
src/main/java/com/myshop/common/ValidationErrorException.java
0 → 100644
View file @
969fb9e8
package
com.myshop.common
;
import
java.util.List
;
public
class
ValidationErrorException
extends
RuntimeException
{
private
List
<
ValidationError
>
errors
;
public
ValidationErrorException
(
List
<
ValidationError
>
errors
)
{
this
.
errors
=
errors
;
}
public
List
<
ValidationError
>
getErrors
()
{
return
errors
;
}
}
src/main/java/com/myshop/common/VersionConflictException.java
0 → 100644
View file @
969fb9e8
package
com.myshop.common
;
public
class
VersionConflictException
extends
RuntimeException
{
}
src/main/java/com/myshop/common/event/Event.java
0 → 100644
View file @
969fb9e8
package
com.myshop.common.event
;
public
abstract
class
Event
{
private
long
timestamp
;
public
Event
()
{
this
.
timestamp
=
System
.
currentTimeMillis
();
}
public
long
getTimestamp
()
{
return
timestamp
;
}
}
src/main/java/com/myshop/common/event/EventStoreHandler.java
0 → 100644
View file @
969fb9e8
package
com.myshop.common.event
;
import
com.myshop.eventstore.api.EventStore
;
import
org.springframework.context.event.EventListener
;
import
org.springframework.stereotype.Component
;
@Component
public
class
EventStoreHandler
{
private
EventStore
eventStore
;
public
EventStoreHandler
(
EventStore
eventStore
)
{
this
.
eventStore
=
eventStore
;
}
@EventListener
(
Event
.
class
)
public
void
handle
(
Event
event
)
{
eventStore
.
save
(
event
);
}
}
src/main/java/com/myshop/common/event/Events.java
0 → 100644
View file @
969fb9e8
package
com.myshop.common.event
;
import
org.springframework.context.ApplicationEventPublisher
;
public
class
Events
{
private
static
ApplicationEventPublisher
publisher
;
static
void
setPublisher
(
ApplicationEventPublisher
publisher
)
{
Events
.
publisher
=
publisher
;
}
public
static
void
raise
(
Object
event
)
{
if
(
publisher
!=
null
)
{
publisher
.
publishEvent
(
event
);
}
}
}
src/main/java/com/myshop/common/event/EventsConfiguration.java
0 → 100644
View file @
969fb9e8
package
com.myshop.common.event
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
@Configuration
public
class
EventsConfiguration
{
@Autowired
private
ApplicationContext
applicationContext
;
@Bean
public
InitializingBean
eventsInitializer
()
{
return
()
->
Events
.
setPublisher
(
applicationContext
);
}
}
Prev
1
2
3
4
5
6
…
10
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment