Skip to content

Instantly share code, notes, and snippets.

@disc99
Last active March 9, 2021 12:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save disc99/7f2c66270bf79d8e2f1630129a39c351 to your computer and use it in GitHub Desktop.
Save disc99/7f2c66270bf79d8e2f1630129a39c351 to your computer and use it in GitHub Desktop.
Doma one-to-many mapping
package com.example.demo;
import lombok.EqualsAndHashCode;
import java.util.List;
import java.util.function.Function;
import static java.util.stream.Collectors.toList;
@EqualsAndHashCode
public class CacheKey<E> {
List<Function<E, Object>> type;
List<Object> value;
public CacheKey(List<Function<E, Object>> identifier, E entity) {
this.type = identifier;
this.value = identifier.stream()
.map(f -> f.apply(entity))
.collect(toList());
}
}
package com.example.demo;
import lombok.Value;
import java.util.Map;
@Value
public class MappingObject<ENTITY, PARENT> {
ENTITY entity;
PARENT parent;
Map<CacheKey<ENTITY>, Object> cache;
public static <ENTITY, PARENT> MappingObject<ENTITY, PARENT> create(Map<CacheKey<ENTITY>, Object> cache, ENTITY entity, PARENT parent) {
return new MappingObject<>(entity, parent, cache);
}
public <CHILD> MappingObject<ENTITY, CHILD> child(CHILD child) {
return new MappingObject<>(entity, child, cache);
}
}
package com.example.demo;
import java.util.*;
import java.util.function.*;
import java.util.stream.Collector;
public class Mappings {
private static final Consumer NONE = t -> {};
public static <T, R> Collector<T, ?, List<R>> entityMapping(Consumer<MappingObject<T, List<R>>> accumulator) {
Map<CacheKey<T>, Object> cache = new HashMap<>();
return Collector.of(
ArrayList::new,
(list, t) -> accumulator.accept(MappingObject.create(cache, t, list)),
(List<R> l1, List<R> l2) -> {
l1.addAll(l2);
return l1;
}
);
}
@SuppressWarnings("unchecked")
public static <ENTITY, PARENT, OBJECT> MappingObject<ENTITY, PARENT> mapping(MappingObject<ENTITY, PARENT> mappingObject, List<Function<ENTITY, Object>> identifier, Function<ENTITY, OBJECT> creator, BiConsumer<PARENT, OBJECT> setter, Consumer<MappingObject<ENTITY, OBJECT>> nestedMapping) {
if (identifier.stream().allMatch(f -> f.apply(mappingObject.getEntity()) != null)) {
OBJECT object = (OBJECT) mappingObject.getCache().computeIfAbsent(new CacheKey<>(identifier, mappingObject.getEntity()), k -> {
OBJECT o = creator.apply(mappingObject.getEntity());
setter.accept(mappingObject.getParent(), o);
return o;
});
nestedMapping.accept(mappingObject.child(object));
}
return mappingObject;
}
@SuppressWarnings("unchecked")
public static <ENTITY, PARENT, OBJECT> MappingObject<ENTITY, PARENT> mapping(MappingObject<ENTITY, PARENT> mappingObject, List<Function<ENTITY, Object>> identifier, Function<ENTITY, OBJECT> creator, BiConsumer<PARENT, OBJECT> setter) {
return mapping(mappingObject, identifier, creator, setter, NONE);
}
@SuppressWarnings("unchecked")
public static <ENTITY, PARENT, OBJECT> PARENT mapping(Map<CacheKey<ENTITY>, Object> cache, ENTITY entity, PARENT parent, List<Function<ENTITY, Object>> identifier, Function<ENTITY, OBJECT> creator, BiConsumer<PARENT, OBJECT> setter, Consumer<OBJECT> nestedMapping) {
if (identifier.stream().allMatch(f -> f.apply(entity) != null)) {
OBJECT object = (OBJECT) cache.computeIfAbsent(new CacheKey<>(identifier, entity), k -> {
OBJECT o = creator.apply(entity);
setter.accept(parent, o);
return o;
});
nestedMapping.accept(object);
}
return parent;
}
@SuppressWarnings("unchecked")
public static <ENTITY, PARENT, OBJECT> PARENT mapping(Map<CacheKey<ENTITY>, Object> cache, ENTITY entity, PARENT parent, List<Function<ENTITY, Object>> identifier, Function<ENTITY, OBJECT> creator, BiConsumer<PARENT, OBJECT> setter) {
return mapping(cache, entity, parent, identifier, creator, setter, (Consumer<OBJECT>) NONE);
}
}
package com.example.demo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import org.junit.jupiter.api.Test;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collector;
import static com.example.demo.Mappings.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class MappingTest {
List<ResultEntity> entities = List.of(
new ResultEntity(1, "user1", 1, "tweet1", 1, "comment1", 1, new Date(1)),
new ResultEntity(1, "user1", 1, "tweet1", 1, "comment1", 2, new Date(2)),
new ResultEntity(2, "user2", 2, "tweet2", 2, "comment2", 3, new Date(3)),
new ResultEntity(2, "user2", 2, "tweet2", 3, "comment3", 3, new Date(3)),
new ResultEntity(2, "user2", 2, "tweet2", 4, "comment4", 3, new Date(3)),
new ResultEntity(2, "user2", 2, "tweet2", 2, "comment2", 4, new Date(4)),
new ResultEntity(2, "user2", 2, "tweet2", 3, "comment3", 4, new Date(4)),
new ResultEntity(2, "user2", 2, "tweet2", 4, "comment4", 4, new Date(4)),
new ResultEntity(3, "user3", 4, "tweet4", null, null, null, null),
new ResultEntity(2, "user2", 5, "tweet5", null, null, null, null),
new ResultEntity(4, "user4", null, null, null, null, null, null)
);
List<User> expected = List.of(
new User(1, "user1", List.of(
new Tweet(1, "tweet1", List.of(
new Comment(1, "comment1")
), List.of(
new Like(1, new Date(1)),
new Like(2, new Date(2))
))
)),
new User(2, "user2", List.of(
new Tweet(2, "tweet2", List.of(
new Comment(2, "comment2"),
new Comment(3, "comment3"),
new Comment(4, "comment4")
), List.of(
new Like(3, new Date(3)),
new Like(4, new Date(4))
)),
new Tweet(5, "tweet5", List.of(), List.of())
)),
new User(3, "user3", List.of(new Tweet(4, "tweet4", List.of(), List.of()))),
new User(4, "user4", List.of())
);
static class UserDao {
List<ResultEntity> entities;
public UserDao(List<ResultEntity> entities) {
this.entities = entities;
}
List<ResultEntity> findUserList() {
return entities;
};
<R> R findUserCollect(Collector<ResultEntity, ?, R> collector) {
return entities.stream().collect(collector);
}
}
UserDao userDao = new UserDao(entities);
@Test
void test__01_基本的なマッピング() throws Exception {
List<ResultEntity> userList = userDao.findUserList();
List<User> users = new ArrayList<>();
for (ResultEntity entity : userList) {
User user = null;
for (User u : users) {
if (u.getId().equals(entity.getUserId())) {
user = u;
}
}
if (user == null) {
user = new User(entity.getUserId(), entity.getUserName(), new ArrayList<>());
users.add(user);
}
if (entity.getTweetId() != null) {
Tweet tweet = null;
for (Tweet t : user.getTweets()) {
if (t.getId().equals(entity.getTweetId())) {
tweet = t;
}
}
if (tweet == null) {
tweet = new Tweet(entity.getTweetId(), entity.getTweet(), new ArrayList<>(), new ArrayList<>());
user.getTweets().add(tweet);
}
if (entity.getCommentId() != null) {
List<Comment> comments = tweet.getComments();
if (comments.stream().noneMatch(c -> c.getId().equals(entity.getCommentId()))) {
comments.add(new Comment(entity.getCommentId(), entity.getComment()));
}
}
if (entity.getLikeId() != null) {
List<Like> likes = tweet.getLikes();
if (likes.stream().noneMatch(c -> c.getId().equals(entity.getLikeId()))) {
likes.add(new Like(entity.getLikeId(), entity.getLikeTime()));
}
}
}
}
assertJson(users, expected);
}
@Test
void test__02_Streamの利用() throws Exception {
List<User> users = userDao.findUserList().stream()
.reduce(new ArrayList<>(), (list, entity) -> {
User user = null;
for (User u : list) {
if (u.getId().equals(entity.getUserId())) {
user = u;
}
}
if (user == null) {
user = new User(entity.getUserId(), entity.getUserName(), new ArrayList<>());
list.add(user);
}
if (entity.getTweetId() == null) {
return list;
}
Tweet tweet = null;
for (Tweet t : user.getTweets()) {
if (t.getId().equals(entity.getTweetId())) {
tweet = t;
}
}
if (tweet == null) {
tweet = new Tweet(entity.getTweetId(), entity.getTweet(), new ArrayList<>(), new ArrayList<>());
user.getTweets().add(tweet);
}
if (entity.getCommentId() != null) {
List<Comment> comments = tweet.getComments();
if (comments.stream().noneMatch(c -> c.getId().equals(entity.getCommentId()))) {
comments.add(new Comment(entity.getCommentId(), entity.getComment()));
}
}
if (entity.getLikeId() != null) {
List<Like> likes = tweet.getLikes();
if (likes.stream().noneMatch(c -> c.getId().equals(entity.getLikeId()))) {
likes.add(new Like(entity.getLikeId(), entity.getLikeTime()));
}
}
return list;
}, (BinaryOperator<List<User>>) Lists::concat);
assertJson(users, expected);
}
@Test
void test__03_キャッシュを利用したマッピング() throws Exception {
Map<Object, Object> cache = new HashMap<>();
List<User> users = userDao.findUserList().stream()
.reduce(new ArrayList<>(), (list, entity) -> {
if (entity.getUserId() != null) {
User user = (User) cache.get("userId:" + entity.getUserId());
if (user == null) {
user = new User(entity.getUserId(), entity.getUserName(), new ArrayList<>());
cache.put("userId:" + entity.getUserId(), user);
list.add(user);
}
if (entity.getTweetId() != null) {
Tweet tweet = (Tweet) cache.get("userId:" + entity.getUserId() + "tweetId:" + entity.getTweetId());
if (tweet == null) {
tweet = new Tweet(entity.getTweetId(), entity.getTweet(), new ArrayList<>(), new ArrayList<>());
cache.put("userId:" + entity.getUserId() + "tweetId:" + entity.getTweetId(), tweet);
user.getTweets().add(tweet);
}
if (entity.getCommentId() != null) {
Comment comment = (Comment) cache.get("userId:" + entity.getUserId() + "tweetId:" + entity.getTweetId() + "commentId" + entity.getCommentId());
if (comment == null) {
comment = new Comment(entity.getCommentId(), entity.getComment());
cache.put("userId:" + entity.getUserId() + "tweetId:" + entity.getTweetId() + "commentId" + entity.getCommentId(), comment);
tweet.getComments().add(comment);
}
}
if (entity.getLikeId() != null) {
Like like = (Like) cache.get("userId:" + entity.getUserId() + "tweetId:" + entity.getTweetId() + "likeId" + entity.getLikeId());
if (like == null) {
like = new Like(entity.getLikeId(), entity.getLikeTime());
cache.put("userId:" + entity.getUserId() + "tweetId:" + entity.getTweetId() + "likeId" + entity.getLikeId(), like);
tweet.getLikes().add(like);
}
}
}
}
return list;
}, (BinaryOperator<List<User>>) Lists::concat);
assertJson(users, expected);
}
@Test
void test__03_キャッシュを汎用化() throws Exception {
List<Function<ResultEntity, Object>> userKey = List.of(ResultEntity::getUserId);
List<Function<ResultEntity, Object>> tweetKey = List.of(ResultEntity::getUserId, ResultEntity::getTweetId);
List<Function<ResultEntity, Object>> commentKey = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getCommentId);
List<Function<ResultEntity, Object>> likeKey = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getLikeId);
Map<CacheKey<ResultEntity>, Object> cache = new HashMap<>();
List<User> users = userDao.findUserList().stream()
.reduce(new ArrayList<>(), (list, entity) -> {
if (entity.getUserId() != null) {
User user = (User) cache.get(new CacheKey<>(userKey, entity));
if (user == null) {
user = new User(entity.getUserId(), entity.getUserName(), new ArrayList<>());
cache.put(new CacheKey<>(userKey, entity), user);
list.add(user);
}
if (entity.getTweetId() != null) {
Tweet tweet = (Tweet) cache.get(new CacheKey<>(tweetKey, entity));
if (tweet == null) {
tweet = new Tweet(entity.getTweetId(), entity.getTweet(), new ArrayList<>(), new ArrayList<>());
cache.put(new CacheKey<>(tweetKey, entity), tweet);
user.getTweets().add(tweet);
}
if (entity.getCommentId() != null) {
Comment comment = (Comment) cache.get(new CacheKey<>(commentKey, entity));
if (comment == null) {
comment = new Comment(entity.getCommentId(), entity.getComment());
cache.put(new CacheKey<>(commentKey, entity), comment);
tweet.getComments().add(comment);
}
}
if (entity.getLikeId() != null) {
Like like = (Like) cache.get(new CacheKey<>(likeKey, entity));
if (like == null) {
like = new Like(entity.getLikeId(), entity.getLikeTime());
cache.put(new CacheKey<>(likeKey, entity), like);
tweet.getLikes().add(like);
}
}
}
}
return list;
}, (BinaryOperator<List<User>>) Lists::concat);
assertJson(users, expected);
}
@Test
void test__04_処理の汎用化() throws Exception {
List<Function<ResultEntity, Object>> userIdentifier = List.of(ResultEntity::getUserId);
List<Function<ResultEntity, Object>> tweetIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId);
List<Function<ResultEntity, Object>> commentIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getCommentId);
List<Function<ResultEntity, Object>> likeIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getLikeId);
Function<ResultEntity, User> userCreator = entity -> new User(entity.getUserId(), entity.getUserName(), new ArrayList<>());
Function<ResultEntity, Tweet> tweetCreator = entity -> new Tweet(entity.getTweetId(), entity.getTweet(), new ArrayList<>(), new ArrayList<>());
Function<ResultEntity, Comment> commentCreator = entity -> new Comment(entity.getCommentId(), entity.getComment());
Function<ResultEntity, Like> likeCreator = entity -> new Like(entity.getLikeId(), entity.getLikeTime());
BiConsumer<List<User>, User> userSetter = List::add;
BiConsumer<User, Tweet> tweetSetter = (parent, object) -> parent.getTweets().add(object);
BiConsumer<Tweet, Comment> commentSetter = (parent, object) -> parent.getComments().add(object);
BiConsumer<Tweet, Like> likeSetter = (parent, object) -> parent.getLikes().add(object);
Map<CacheKey<ResultEntity>, Object> cache = new HashMap<>();
List<User> users = userDao.findUserList().stream()
.reduce(new ArrayList<>(), (list, entity) -> {
if (userIdentifier.stream().allMatch(f -> f.apply(entity) != null)) {
User user = (User) cache.computeIfAbsent(new CacheKey<>(userIdentifier, entity), key -> {
User e = userCreator.apply(entity);
userSetter.accept(list, e);
return e;
});
if (tweetIdentifier.stream().allMatch(f -> f.apply(entity) != null)) {
Tweet tweet = (Tweet) cache.computeIfAbsent(new CacheKey<>(tweetIdentifier, entity), key -> {
Tweet e = tweetCreator.apply(entity);
tweetSetter.accept(user, e);
return e;
});
if (commentIdentifier.stream().allMatch(f -> f.apply(entity) != null)) {
cache.computeIfAbsent(new CacheKey<>(commentIdentifier, entity), key -> {
Comment e = commentCreator.apply(entity);
commentSetter.accept(tweet, e);
return e;
});
}
if (likeIdentifier.stream().allMatch(f -> f.apply(entity) != null)) {
cache.computeIfAbsent(new CacheKey<>(likeIdentifier, entity), key -> {
Like e = likeCreator.apply(entity);
likeSetter.accept(tweet, e);
return e;
});
}
}
}
return list;
}, (BinaryOperator<List<User>>) Lists::concat);
assertJson(users, expected);
}
@Test
void test__05_共通化() throws Exception {
List<Function<ResultEntity, Object>> userIdentifier = List.of(ResultEntity::getUserId);
List<Function<ResultEntity, Object>> tweetIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId);
List<Function<ResultEntity, Object>> commentIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getCommentId);
List<Function<ResultEntity, Object>> likeIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getLikeId);
Function<ResultEntity, User> userCreator = entity -> new User(entity.getUserId(), entity.getUserName(), new ArrayList<>());
Function<ResultEntity, Tweet> tweetCreator = entity -> new Tweet(entity.getTweetId(), entity.getTweet(), new ArrayList<>(), new ArrayList<>());
Function<ResultEntity, Comment> commentCreator = entity -> new Comment(entity.getCommentId(), entity.getComment());
Function<ResultEntity, Like> likeCreator = entity -> new Like(entity.getLikeId(), entity.getLikeTime());
BiConsumer<List<User>, User> userSetter = List::add;
BiConsumer<User, Tweet> tweetSetter = (parent, object) -> parent.getTweets().add(object);
BiConsumer<Tweet, Comment> commentSetter = (parent, object) -> parent.getComments().add(object);
BiConsumer<Tweet, Like> likeSetter = (parent, object) -> parent.getLikes().add(object);
Map<CacheKey<ResultEntity>, Object> cache = new HashMap<>();
List<User> users = userDao.findUserList().stream().reduce(new ArrayList<>(),
(list, entity) -> mapping(cache, entity, list, userIdentifier, userCreator, userSetter,
user -> mapping(cache, entity, user, tweetIdentifier, tweetCreator, tweetSetter,
tweet -> {
mapping(cache, entity, tweet, commentIdentifier, commentCreator, commentSetter);
mapping(cache, entity, tweet, likeIdentifier, likeCreator, likeSetter);
}))
, (BinaryOperator<List<User>>) Lists::concat);
assertJson(users, expected);
}
@Test
void test__06_Collectorの利用() throws Exception {
List<Function<ResultEntity, Object>> userIdentifier = List.of(ResultEntity::getUserId);
List<Function<ResultEntity, Object>> tweetIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId);
List<Function<ResultEntity, Object>> commentIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getCommentId);
List<Function<ResultEntity, Object>> likeIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getLikeId);
Function<ResultEntity, User> userCreator = entity -> new User(entity.getUserId(), entity.getUserName(), new ArrayList<>());
Function<ResultEntity, Tweet> tweetCreator = entity -> new Tweet(entity.getTweetId(), entity.getTweet(), new ArrayList<>(), new ArrayList<>());
Function<ResultEntity, Comment> commentCreator = entity -> new Comment(entity.getCommentId(), entity.getComment());
Function<ResultEntity, Like> likeCreator = entity -> new Like(entity.getLikeId(), entity.getLikeTime());
BiConsumer<List<User>, User> userSetter = List::add;
BiConsumer<User, Tweet> tweetSetter = (parent, object) -> parent.getTweets().add(object);
BiConsumer<Tweet, Comment> commentSetter = (parent, object) -> parent.getComments().add(object);
BiConsumer<Tweet, Like> likeSetter = (parent, object) -> parent.getLikes().add(object);
Map<CacheKey<ResultEntity>, Object> cache = new HashMap<>();
List<User> users = userDao.findUserList().stream().collect(Collector.of(ArrayList::new,
(list, entity) -> mapping(cache, entity, list, userIdentifier, userCreator, userSetter,
user -> mapping(cache, entity, user, tweetIdentifier, tweetCreator, tweetSetter,
tweet -> {
mapping(cache, entity, tweet, commentIdentifier, commentCreator, commentSetter);
mapping(cache, entity, tweet, likeIdentifier, likeCreator, likeSetter);
}))
, (BinaryOperator<List<User>>) Lists::concat));
assertJson(users, expected);
}
@Test
void test__06_Collectorの汎用化() throws Exception {
List<Function<ResultEntity, Object>> userIdentifier = List.of(ResultEntity::getUserId);
List<Function<ResultEntity, Object>> tweetIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId);
List<Function<ResultEntity, Object>> commentIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getCommentId);
List<Function<ResultEntity, Object>> likeIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getLikeId);
Function<ResultEntity, User> userCreator = entity -> new User(entity.getUserId(), entity.getUserName(), new ArrayList<>());
Function<ResultEntity, Tweet> tweetCreator = entity -> new Tweet(entity.getTweetId(), entity.getTweet(), new ArrayList<>(), new ArrayList<>());
Function<ResultEntity, Comment> commentCreator = entity -> new Comment(entity.getCommentId(), entity.getComment());
Function<ResultEntity, Like> likeCreator = entity -> new Like(entity.getLikeId(), entity.getLikeTime());
BiConsumer<List<User>, User> userSetter = List::add;
BiConsumer<User, Tweet> tweetSetter = (parent, object) -> parent.getTweets().add(object);
BiConsumer<Tweet, Comment> commentSetter = (parent, object) -> parent.getComments().add(object);
BiConsumer<Tweet, Like> likeSetter = (parent, object) -> parent.getLikes().add(object);
Map<CacheKey<ResultEntity>, Object> cache = new HashMap<>();
List<User> users = userDao.findUserList().stream().collect(reduceBy(
(list, entity) -> mapping(cache, entity, list, userIdentifier, userCreator, userSetter,
user -> mapping(cache, entity, user, tweetIdentifier, tweetCreator, tweetSetter,
tweet -> {
mapping(cache, entity, tweet, commentIdentifier, commentCreator, commentSetter);
mapping(cache, entity, tweet, likeIdentifier, likeCreator, likeSetter);
}))));
assertJson(users, expected);
}
@Test
void test__07_キャッシュの抽象化() throws Exception {
List<Function<ResultEntity, Object>> userIdentifier = List.of(ResultEntity::getUserId);
List<Function<ResultEntity, Object>> tweetIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId);
List<Function<ResultEntity, Object>> commentIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getCommentId);
List<Function<ResultEntity, Object>> likeIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getLikeId);
Function<ResultEntity, User> userCreator = entity -> new User(entity.getUserId(), entity.getUserName(), new ArrayList<>());
Function<ResultEntity, Tweet> tweetCreator = entity -> new Tweet(entity.getTweetId(), entity.getTweet(), new ArrayList<>(), new ArrayList<>());
Function<ResultEntity, Comment> commentCreator = entity -> new Comment(entity.getCommentId(), entity.getComment());
Function<ResultEntity, Like> likeCreator = entity -> new Like(entity.getLikeId(), entity.getLikeTime());
BiConsumer<List<User>, User> userSetter = List::add;
BiConsumer<User, Tweet> tweetSetter = (parent, object) -> parent.getTweets().add(object);
BiConsumer<Tweet, Comment> commentSetter = (parent, object) -> parent.getComments().add(object);
BiConsumer<Tweet, Like> likeSetter = (parent, object) -> parent.getLikes().add(object);
Map<CacheKey<ResultEntity>, Object> cache = new HashMap<>();
List<User> users = userDao.findUserList().stream().collect(reduceBy(
(list, entity) -> mapping(MappingObject.create(cache, entity, list), userIdentifier, userCreator, userSetter,
user -> mapping(user, tweetIdentifier, tweetCreator, tweetSetter,
tweet -> {
mapping(tweet, commentIdentifier, commentCreator, commentSetter);
mapping(tweet, likeIdentifier, likeCreator, likeSetter);
}))));
assertJson(users, expected);
}
@Test
void test__07_キャッシュの隠蔽() throws Exception {
List<Function<ResultEntity, Object>> userIdentifier = List.of(ResultEntity::getUserId);
List<Function<ResultEntity, Object>> tweetIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId);
List<Function<ResultEntity, Object>> commentIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getCommentId);
List<Function<ResultEntity, Object>> likeIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getLikeId);
Function<ResultEntity, User> userCreator = entity -> new User(entity.getUserId(), entity.getUserName(), new ArrayList<>());
Function<ResultEntity, Tweet> tweetCreator = entity -> new Tweet(entity.getTweetId(), entity.getTweet(), new ArrayList<>(), new ArrayList<>());
Function<ResultEntity, Comment> commentCreator = entity -> new Comment(entity.getCommentId(), entity.getComment());
Function<ResultEntity, Like> likeCreator = entity -> new Like(entity.getLikeId(), entity.getLikeTime());
BiConsumer<List<User>, User> userSetter = List::add;
BiConsumer<User, Tweet> tweetSetter = (parent, object) -> parent.getTweets().add(object);
BiConsumer<Tweet, Comment> commentSetter = (parent, object) -> parent.getComments().add(object);
BiConsumer<Tweet, Like> likeSetter = (parent, object) -> parent.getLikes().add(object);
List<User> users = userDao.findUserList().stream().collect(entityMapping(
list -> mapping(list, userIdentifier, userCreator, userSetter,
user -> mapping(user, tweetIdentifier, tweetCreator, tweetSetter,
tweet -> {
mapping(tweet, commentIdentifier, commentCreator, commentSetter);
mapping(tweet, likeIdentifier, likeCreator, likeSetter);
}))));
assertJson(users, expected);
}
@Test
void test__07_キャッシュの隠蔽とインライン化() throws Exception {
List<Function<ResultEntity, Object>> userIdentifier = List.of(ResultEntity::getUserId);
List<Function<ResultEntity, Object>> tweetIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId);
List<Function<ResultEntity, Object>> commentIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getCommentId);
List<Function<ResultEntity, Object>> likeIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getLikeId);
List<User> users = userDao.findUserList().stream().collect(entityMapping(
list -> mapping(list, userIdentifier,
entity -> new User(entity.getUserId(), entity.getUserName(), new ArrayList<>()),
List::add,
user -> mapping(user, tweetIdentifier,
entity -> new Tweet(entity.getTweetId(), entity.getTweet(), new ArrayList<>(), new ArrayList<>()),
(parent, object) -> parent.getTweets().add(object),
tweet -> {
mapping(tweet, commentIdentifier,
entity -> new Comment(entity.getCommentId(), entity.getComment()),
(parent, object) -> parent.getComments().add(object));
mapping(tweet, likeIdentifier,
entity -> new Like(entity.getLikeId(), entity.getLikeTime()),
(parent, object) -> parent.getLikes().add(object));
}))));
assertJson(users, expected);
}
@Test
void test__08_collect検索() throws Exception {
List<Function<ResultEntity, Object>> userIdentifier = List.of(ResultEntity::getUserId);
List<Function<ResultEntity, Object>> tweetIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId);
List<Function<ResultEntity, Object>> commentIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getCommentId);
List<Function<ResultEntity, Object>> likeIdentifier = List.of(ResultEntity::getUserId, ResultEntity::getTweetId, ResultEntity::getLikeId);
List<User> users = userDao.findUserCollect(entityMapping(
list -> mapping(list, userIdentifier,
entity -> new User(entity.getUserId(), entity.getUserName(), new ArrayList<>()),
List::add,
user -> mapping(user, tweetIdentifier,
entity -> new Tweet(entity.getTweetId(), entity.getTweet(), new ArrayList<>(), new ArrayList<>()),
(parent, object) -> parent.getTweets().add(object),
tweet -> {
mapping(tweet, commentIdentifier,
entity -> new Comment(entity.getCommentId(), entity.getComment()),
(parent, object) -> parent.getComments().add(object));
mapping(tweet, likeIdentifier,
entity -> new Like(entity.getLikeId(), entity.getLikeTime()),
(parent, object) -> parent.getLikes().add(object));
}))));
assertJson(users, expected);
}
private void assertJson(List<User> users, List<User> expected) throws Exception {
ObjectWriter objectWriter = new ObjectMapper().writerWithDefaultPrettyPrinter();
assertEquals(
objectWriter.writeValueAsString(expected),
objectWriter.writeValueAsString(users)
);
}
static class Lists {
static <T> List<T> concat(List<T> list1, List<T> list2) {
list1.addAll(list2);
return list1;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment