作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我将应用程序分为三层: Controller 、服务、存储库。这非常有用,因为我可以更改任何层上的内容而不影响其他层。
目前,我正在尝试优化一些查询,但有些地方实体图和生成的查询不足以满足我的需求。通过编写 native SQL 并使用现有的 @Entity 映射结果集,我相信我可以更快地生成数据。
假设我有一些界面:
public interface UserRepository extends CrudRepository<User, Long> {}
如何扩展UserRepository
以使用CrudRepository
方法(例如save()
、findById()
)同时还使用我自己的 native 查询方法。
我在带有 Spring Boot 的 Java 8 的每个租户数据库环境中使用 hibernate 作为我的持久性提供程序。我考虑过以下解决方案,但仍不满意:
我在 Spring Data Docs 中找不到任何内容描述如何做到这一点,但我确信我已经在网络上的某个地方看到过这样的解决方案。
为了清楚起见,我希望做这样的事情:
public interface UserRepository extends CrudRepository<User, Long> {};
public class UserRepositoryImpl extends UserRepository {
public User doComplexQuery() {
List<Result> rows = query.("select * from ... ");
User user = new User(rows.get(0));
return user;
}
};
public class UserService {
@Autowired private UserRepository userRepository;
public User getUser() {
return userRepository.doComplexQuery();
}
public User saveUser(User user) {
return userRepository.save(user);
}
}
最佳答案
对我来说,最好和最简单的选择是您所描述的所有选项的组合, projections (如果我理解正确的话)。
我使用 Lombok 创建简单实体
@Data
@Builder
@NoArgConstructor
@AllArgsConstructor
@Entity
public class Model implements Serializable {
//...
private String name;
@OneToMany
private List<Subject> subjects;
}
@Data
@Builder
@NoArgConstructor
@AllArgsConstructor
@Entity
public class Subject implements Serializable {
//...
}
然后定义必要的投影,例如:
public interface ModelSubjects {
List<Subject> getSubjects();
}
public interface SomeProjection {
//...
}
然后根据需要扩展我的存储库:
public interface ModelRepo extends JpaRepository<Model, Long> {
@Query("select distinct m from Model m join fetch m.subjects where ...")
List<Model> getWithJPQLQuery(...);
@Query("select s as subjects from Model m join m.subjects s where ...")
List<ModelSubjects> getSubjectsWithJPQLQuery(...);
@Query(value = "some complex SQL query...", nativeQuery = true)
List<SomeProjection> getWithSQLQuery(...);
@EntityGraph(attributePaths = "subjects")
List<Model> findByName(String name);
}
已更新
复杂的例子(参见答案下的评论):
@Entity
public class Forest {
//...
private String name;
@OneToMany
private List<Tree> trees;
}
@Entity
public class Tree {
//...
@OneToMany
private List<Branch> branches;
}
@Entity
public class Branch {
//...
}
public interface BranchNumberByForest {
String getForestName();
Long getBranchNumber();
}
native 查询
public interface ForestRepo extends JpaRepository<Forest, Long> {
@Query(value = "" +
"select " +
" f.name as forestName, " +
" count(b.*) as branchNumber " +
"from " +
" forests f " +
" left join trees t on t.forest_id = f.id " +
" left join branches b on b.tree_id = t.id " +
"group by " +
" f.name", nativeQuery = true)
List<BranchNumberByForest> getBranchNumbers();
}
与JPQL相同
public interface ForestRepo extends JpaRepository<Forest, Long> {
@Query("" +
"select " +
" f.name as forestName, " +
" count(b) as branchNumber " +
"from " +
" Forest f " +
" left join f.trees t " +
" left join t.branches b " +
"group by " +
" f.name")
List<BranchNumberByForest> getBranchNumbers();
}
关于java - 如何将手动 SQL 行映射与 CrudRepository (Spring Data) 混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51829850/
我是一名优秀的程序员,十分优秀!