java 在Spring中使用DTO时服务之间的关系

6rqinv9w  于 2023-08-01  发布在  Java
关注(0)|答案(1)|浏览(85)

我对Spring框架还很陌生,我在概念化方面遇到了麻烦,那就是在使用DTO时服务之间的协同作用。
我试着给予一个简单的例子。可能不是最相关的,当然也不是设计得很好,但它说明了我的问题:

@Entity
public class Author {
    private int id;
    private String name;
}

public class AuthorDto {
    private int id;
    private String name;
}

@Entity
public class Book {
    private int id;
    private String title;
    private Author author;
}

public class BookDto {
    private int id;
    private String title;
    private String authorName;
}

// AuthorRepository extends CrudRepository
// BookRepository extends CrudRepository

@Service
public class AuthorService {

    public AuthorDto getByName(String name) {
        Assert.nonNull(name, "name is null");

        Author author = this.authorRepository.getByName(name).orElseThrow(() -> new AuthorNotFoundException(name));
        return AuthorMapper.toDto(author);
    }

}

@Service
public class BookService {

    public BookDto register(BookDto book) {
        // Check book validity.
        Book bookEntity = BookMapper.toEntity(book);

        // How do I get the Author information for entity persistence ?
        Author author = ???
        bookEntity.setAuthor(author);

        bookEntity = this.bookRepository.save(bookEntity);
        return BookMapper.toDto(bookEntity);
    }

}

字符串
①一种解决方案是直接使用AuthorRepository:

public BookDto register(BookDto book) {
    //…
    Author author = this.AuthorRepsitory.getByName(book.getAuthor())
        .orElseThrow(() -> new AuthorNotFoundException(book.getAuthor()));
    //…
}


但是我从AuthorService复制代码。我想这对于像这样的简单情况是可以的,但是对于更复杂的事情,比如管理子对象的创建,这可能会导致错误和遗漏的步骤。
②另一种解决方案是使用AuthorService:

public BookDto register(BookDto book) {
    //…
    Author author = AuthorMapper.toEntity(this.AuthorService.getByName(book.getAuthor()));
    //…
}


但这会增加不必要的步骤(实体到DTO到实体),并将作者与下划线实体管理器分离,可能会在后台添加更多步骤来解决这个问题。
③我的想法是利用protected示波器来简化服务通信:

@Service
public class AuthorServiceImpl implements AuthorService {

    protected Author _getByName(String name) {
        Assert.nonNull(name, "name is null");

        return this.authorRepository.getByName(name)
            .orElseThrow(() -> new AuthorNotFoundException(name));
    }

    public AuthorDto getByName(String name) {
        return AuthorMapper.toDto(this._getByName(name));
    }

}

@Service
public class BookServiceImpl implements BookService {

    public BookDto register(BookDto book) {
        // Do check for book validity.
        Book bookEntity = BookMapper.toEntity(book);

        Author author = this.authorServiceImpl._getByName(book.getAuthor());
        bookEntity.setAuthor(author);

        bookEntity = this.bookRepository.save(bookEntity);
        return BookMapper.toDto(bookEntity);
    }

}


因此每个服务都管理自己的实体,但我不知道这是否是一个好的实践。
我试图找到我的问题的答案,但到目前为止,我看到的大多数都是①,我找到的所有具体示例都是只有一个服务或实体相互独立的简单情况。

vmdwslir

vmdwslir1#

IMO选项#1和#3是最好的。我个人使用#1。#3仅适用于同一包中的服务。但还是很干净。

相关问题