Есть приложение, читающее файлы из файловой системы и загружающее в БД часть содержимого.
Есть сервисные классы, в них ряд методов, но возвращаемые типы в методах повторяются.
Хотелось бы сделать без спринг шелла, без команд в мейне.
У возвращаемого автора должны быть проинициализированы поля books и genres. Там должны находится
книги которые писал автор и жанры в которых он работал. В свою очередь у каждой книги должна быть
информация в каком жанре она написана и какие у нее авторы. А жанр должен хранить список книг относящихся к нему
и авторов работающих в данном жанре.
Таким образом возвращая автора сервис слою мы должны загрузить кучу информации из базы данных, и это будет не один запрос, а очень много.
-----------------------------------com.example.Example.java-----------------------------------
package com.example;
import java.util.List;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
@Generated("jsonschema2pojo")
public class Example {
@SerializedName("total_count")
@Expose
public Long totalCount;
@SerializedName("incomplete_results")
@Expose
public Boolean incompleteResults;
@SerializedName("items")
@Expose
public List<Item> items = null;
}
-----------------------------------com.example.Item.java-----------------------------------
package com.example;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
@Generated("jsonschema2pojo")
public class Item {
@SerializedName("id")
@Expose
public Long id;
@SerializedName("node_id")
@Expose
public String nodeId;
@SerializedName("name")
@Expose
public String name;
@SerializedName("full_name")
@Expose
public String fullName;
@SerializedName("private")
@Expose
public Boolean _private;
@SerializedName("owner")
@Expose
public Owner owner;
@SerializedName("html_url")
@Expose
public String htmlUrl;
@SerializedName("description")
@Expose
public String description;
@SerializedName("fork")
@Expose
public Boolean fork;
}
-----------------------------------com.example.Owner.java-----------------------------------
package com.example;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
@Generated("jsonschema2pojo")
public class Owner {
@SerializedName("login")
@Expose
public String login;
@SerializedName("id")
@Expose
public Long id;
@SerializedName("node_id")
@Expose
public String nodeId;
@SerializedName("avatar_url")
@Expose
public String avatarUrl;
@SerializedName("gravatar_id")
@Expose
public String gravatarId;
@SerializedName("url")
@Expose
public String url;
@SerializedName("html_url")
@Expose
public String htmlUrl;
@SerializedName("followers_url")
@Expose
public String followersUrl;
@SerializedName("following_url")
@Expose
public String followingUrl;
@SerializedName("gists_url")
@Expose
public String gistsUrl;
@SerializedName("starred_url")
@Expose
public String starredUrl;
@SerializedName("subscriptions_url")
@Expose
public String subscriptionsUrl;
@SerializedName("organizations_url")
@Expose
public String organizationsUrl;
@SerializedName("repos_url")
@Expose
public String reposUrl;
@SerializedName("events_url")
@Expose
public String eventsUrl;
@SerializedName("received_events_url")
@Expose
public String receivedEventsUrl;
@SerializedName("type")
@Expose
public String type;
@SerializedName("site_admin")
@Expose
public Boolean siteAdmin;
}
@Entity
@Data
@Table(name = "users")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class User {
//...
@JsonBackReference
@ToString.Exclude
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "users_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
}
@Entity
@Data
@EqualsAndHashCode(callSuper = false)
@Table(name = "roles")
public class Role implements GrantedAuthority {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long roleId;
@JsonBackReference
@ToString.Exclude
@ManyToMany(mappedBy = "roles")
private Collection<User> users;
@JsonBackReference
@ToString.Exclude
@ManyToMany
@JoinTable(
name = "roles_privileges",
joinColumns = @JoinColumn(name = "role_id"),
inverseJoinColumns = @JoinColumn(name = "privilege_id"))
private Collection<Privilege> privileges;
@Enumerated(EnumType.STRING)
private UserRole name;
public Role() {
super();
}
public Role(UserRole name) {
super();
this.name = name;
}
@Override
public String getAuthority() {
return name.name();
}
}
public enum UserRole {
USER,
ADMIN
}
@Entity
@Data
@EqualsAndHashCode(callSuper = false)
@Table(name = "privileges")
public class Privilege {
@Enumerated(EnumType.STRING)
private UserPrivilege name;
@JsonBackReference
@ToString.Exclude
@ManyToMany(mappedBy = "privileges")
private Collection<Role> roles;
}
public enum UserPrivilege {
ADMIN_PRIVILEGE,
READ_PRIVILEGE,
WRITING_COMMENTS_PRIVILEGE
}
Scanner scanner = new Scanner(System.in);
System.out.println("Введите слово\n");
String word = scanner.nextLine();
String[] splittedWord = word.split("");
for (String character : splittedWord) {
System.out.print(character.repeat(3));
}
Я сделал зависимость клиента от сервера, то есть удалил класс User из клиента и импортировал этот класс из серверного модуля.
Подскажите как лучше изучать spring, какой современный стек?
Converter<S,T>
), который сконвертирует ваш Request в Response.@PostMapping(path = "/save",
produces = {"application/xml", "text/xml"}, consumes =
MediaType.ALL_VALUE)
public ResponseEntity<Response> pay(@RequestBody Request request){
service.save(request);
// тут конвертируем request в response
return ResponseEntity.ok(response);
}
}
public class response {
public int p_id;
public int status;
public String message;
public int id;
public Date dts;
public String text;
}
Единственное что смущает, что и книга и курс выпущены в 2019 году.
Насколько актуальны они будут для начального погружения в Java?
Если есть что-то более свежее, можете посоветовать?
orElseThrow()
или возвращать другой объект (orElse()
) или новый объект и т.д.Optional<Vote> voteOptional = voteRepository.findById(voteId);
if(voteOptional.isEmpty()) {
throw new ApiException("Vote with id " + id +
"is not in DB");
}
Vote vote = voteRepository.findById(voteId).orElseThrow(VoteNotFoundException::new);
Но с другой стороны, если с фронта все правильно настроено, то таких ситуаций и не должно быть.
Разместить прямо в дто в каждом.
Converter<S, T>
), то для каждого entity нужно создать свой класс. Что касается расположения пакетов, то есть разные практики. Например, в пакет user закинуть User, UserCreationDto, UserRepository, UserService, UserToDtoConverter и т.д.@Service
@RequiredArgsConstructor
public class MapperService {
private final ModelMapper modelMapper;
/**
* Note: outClass object must have default constructor with no arguments
*
* @param <D> type of result object.
* @param <T> type of source object to map from.
* @param entity entity that needs to be mapped.
* @param outClass class of result object.
* @return new object of <code>outClass</code> type.
*/
public <D, T> D map(final T entity, Class<D> outClass) {
return modelMapper.map(entity, outClass);
}
/**
* Note: outClass object must have default constructor with no arguments
*
* @param entityList list of entities that needs to be mapped
* @param outCLass class of result list element
* @param <D> type of objects in result list
* @param <T> type of entity in <code>entityList</code>
* @return list of mapped object with <code><D></code> type.
*/
public <D, T> List<D> mapAll(final Collection<T> entityList, Class<D> outCLass) {
return entityList.stream().map(entity -> map(entity, outCLass)).collect(Collectors.toList());
}
/**
* Maps {@code source} to {@code destination}.
*
* @param source object to map from
* @param destination object to map to
*/
public <S, D> D map(final S source, D destination) {
modelMapper.map(source, destination);
return destination;
}
}
Создать отдельный класс DTOUtils и все туда скинуть ( но тогда там вперемешку будут методы конвертации всех классов )
Сделать пакет dtoutils и там создать много классов ( для каждого дто свой, они будут только хранить дто методы и все )
3 вариант выглядит как самый благоразумный, но создавать отдельный класс для одного метода это как-то не очень.
Converter<S, T>