Java Spring Boot 扩展 CrudRepository
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30880927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Boot extending CrudRepository
提问by James Watkins
I'm using Hibernate in a Spring Boot app. I'm making a new CrudRepository for all my Model objects, to do basic CRUD tasks. They look like this:
我在 Spring Boot 应用程序中使用 Hibernate。我正在为我的所有模型对象创建一个新的 CrudRepository,以执行基本的 CRUD 任务。它们看起来像这样:
@Repository
public interface FoobarCrudRepo extends CrudRepository<Foobar, Long> {
}
But then I always need to do some additional things, like custom search queries with inequalities and such. I follow a pattern like this:
但是我总是需要做一些额外的事情,比如带有不等式的自定义搜索查询等等。我遵循这样的模式:
@Repository
public class FoobarDao {
@PersistenceContext
EntityManager em;
public List<Foobar> findFoobarsByDate(Date date) {
String sql = "select fb from Foobar fb where createdDate > :date";
...
return query.getResultList();
}
}
My question is, can I combine these two concepts into a single class? I tried making it an abstract class, like so:
我的问题是,我可以将这两个概念组合成一个类吗?我试着把它变成一个抽象类,像这样:
@Repository
public abstract class FoobarCrudRepo extends CrudRepository<Foobar, Long> {
@PersistenceContext
EntityManager em;
public List<Foobar> findFoobarsByDate(Date date) {
String sql = "select fb from Foobar fb where createdDate > :date";
...
return query.getResultList();
}
}
But then Spring didn't create a bean for it.
但是 Spring 并没有为它创建一个 bean。
How can I accomplish this?
我怎样才能做到这一点?
Thanks!
谢谢!
采纳答案by jst
There are lots of ways you could probably accomplish this. If you really need absolute control try this
有很多方法可以做到这一点。如果你真的需要绝对控制试试这个
interface FoobarRepositoryCustom{
List<Foobar> findFoobarsByDate(Date date);
}
interface FoobarRepository extends CrudRepository<Foobar, Long>, FoobarRepositoryCustom
public class FoobarRespoitoryImpl implements FoobarRepositoryCustom{
@PersistenceContext private EntityManager em;
public List<Foobar> findFoobarsByDate(Date date) {
String sql = "select fb from Foobar fb where createdDate > :date";
...
return query.getResultList();
}
}
There is also the possibility to go a simpler route and the query can be auto generated for you based on the method name. In your example you could just add this to your FoobarCrudRepo and Spring should do the rest assuming Foobar has a property named CreatedDate
也有可能走更简单的路线,并且可以根据方法名称为您自动生成查询。在您的示例中,您可以将它添加到您的 FoobarCrudRepo 中,假设 Foobar 有一个名为 CreatedDate 的属性,Spring 应该完成剩下的工作
List<Foobar> findByCreatedDateGreaterThan(Date date);
For reference on how Spring can generate queries based on the method name see this http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
有关 Spring 如何根据方法名称生成查询的参考,请参阅此http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
回答by pmverma
The problem here is abstract
keyword.
这里的问题是abstract
关键字。
@Repository
public abstract class FoobarCrudRepo extends CrudRepository<Foobar, Long>
Spring will not create a bean for a class unless it is a concrete class. That's why you are getting a bean for it.
Spring 不会为类创建 bean,除非它是一个具体的类。这就是为什么你要得到一个豆子。
回答by Hervian
Completely new to Spring Data, but having searched a bit it is my impression that you do not have to leave the interface to create custom logic - rather you would create either an annotated interface method, an interface method that follows a special naming scheme or a default interface method with custom logic:
对 Spring Data 完全陌生,但经过一些搜索后,我的印象是您不必离开接口来创建自定义逻辑 - 而是您可以创建带注释的接口方法、遵循特殊命名方案的接口方法或具有自定义逻辑的默认接口方法:
Screenshot from Baeldung: Introduction to Spring.
Baeldung: Introduction to Spring 的截图。
Hereis a link to the documentation. Notice "table 4. Supported keywords inside method names" which can be used to create interface methods, whose name conveys information to the code generator about which query to create (See part of table below).
这是文档的链接。请注意“表 4. 方法名称中支持的关键字”,它可用于创建接口方法,其名称向代码生成器传达有关要创建哪个查询的信息(参见下表的部分内容)。
回答by Rahul Wasnik
This is what worked for me...
这对我有用...
@SpringBootApplication(scanBasePackages = { "com.myproject" })
@EnableJpaRepositories(basePackages="com.myproject.sprinbootapp.repository")
@EntityScan("com.myproject.sprinbootapp.model")
public class SpringbootAppWithDatabaseApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootAppWithDatabaseApplication.class, args);
}
}
@Service
public class TopicService {
@Autowired
private TopicRepository topicRepository;
private List<Topics> topics = new ArrayList<Topics>();
public List<Topics> getAllTopics(){
List<Topics> listOfTopics = new ArrayList<Topics>();
topicRepository.findAll().forEach(listOfTopics::add);;
return listOfTopics;
}
}
@Entity
public class Topics {
@Id
private String id;
private String name;
public Topics(){
}
getters and setters...
}
public interface TopicRepository extends CrudRepository<Topics, String> {
}
回答by Bodhi Hu
we can use the JPA EntityManager
for direct sql actions:
我们可以将 JPAEntityManager
用于直接的 sql 操作:
public interface VerificationsRepository extends
CrudRepository<Verification, Integer>,
DAOAccess
{ }
interface DAOAccess {
List findByEmail(String email);
}
class DAOAccessImpl implements DAOAccess {
@PersistenceContext private EntityManager em;
public List findByEmail(String email) {
String sql =
"select * from verifications where email = ?";
Query query = em.createNativeQuery(sql, Verification.class)
.setParameter(1, email);
return query.getResultList();
}
}