Spring中JPA信息库的界面投影的最佳做法?

时间:2018-09-18 06:39:26

标签: java spring-data-jpa nhibernate-projections

我想知道是否有人可以就我目前正在使用的模式提供反馈?它涉及到使一个实体实现一个DTO接口,该接口也用于JpaRepository接口(对于同一实体)(作为投影),以返回具有特定列的查询结果。 DTO接口还具有默认方法,以允许实体的任何实例和DTO代理具有相似的行为。

我要回答的问题是这种模式是否具有诸如性能之类的缺点,可能会阻止其在生产中使用。我也很想听听其他人如何使用JpaRepositories查询特定的数据字段。下面有一个代码示例,说明了我正在使用的模式。

public interface InstructorDTO {
    String getFirstName();
    String getLastName();

    default String getFullName() {
        return getFirstName() + ' ' + getLastName();
    }
}

@Entity
public class Instructor implements InstructorDTO {
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private int id;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

    @Column(unique = true)
    private String email;

    @Override
    public String getFirstName() {
        return this.firstName;
    }

    @Override
    public String getLastName() {
        return this.lastName;
    }

    ...remaining getters and setters
}

@Repository
public interface InstructorRepository extends JpaRepository<Instructor, Integer> {

    <S> S findById(int id, Class<S> type);

    <T> Collection<T> findByEmail(String email, Class<T> type);
}


public class SomeClass {
    @Autowired
    InstructorRepository instructorRepository;

    public void someMethod {
        int id = 1;

        // Returns proxy
        InstructorDTO instructor1 = instructorRepository.findById(id, InstructorDTO.class);

        // Returns Instructor Object
        Instructor instructor2 = instructorRepository.findOne(id);

        System.out.println(instructor1.getFullName()); // returns John Doe
        System.out.println(instructor2.getFullName()); // returns John Doe
    }
}

1 个答案:

答案 0 :(得分:0)

相比之下,此解决方案没有缺点。如果只需要几列,最好使用DTO而不是Entities。

因为如果仅在SQL上使用DTO,将生成用于选择数据的SQL语句。就像您使用实体一样,可以加载渴望的或懒惰的获取关系,这可能会导致n + 1选择问题。

只有在您确实希望实体扩展DTO时才有疑问。我认为这没有道理。

两个建议。