简体   繁体   English

Spring Boot扩展了CrudRepository

[英]Spring Boot extending CrudRepository

I'm using Hibernate in a Spring Boot app. 我在Spring Boot应用程序中使用Hibernate。 I'm making a new CrudRepository for all my Model objects, to do basic CRUD tasks. 我正在为我的所有Model对象创建一个新的CrudRepository,以执行基本的CRUD任务。 They look like this: 它们看起来像这样:

@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! 谢谢!

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中,Spring应该做其余的假设Foobar有一个名为CreatedDate的属性

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

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:Spring简介的屏幕截图。

Here is 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.方法名称中支持的关键字 ”,可用于创建接口方法,其名称向代码生成器传达有关要创建哪个查询的信息(请参阅下表中的部分)。

在此输入图像描述

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. Spring不会为类创建bean,除非它是一个具体的类。 That's why you are getting a bean for it. 这就是你为它获得一个豆子的原因。

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> {

}

we can use the JPA EntityManager for direct sql actions: 我们可以使用JPA EntityManager进行直接的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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM