简体   繁体   中英

Spring - JPA - Hibernate how to use EntityManager

I'm trying to build REST application using following tech stack:

  • Spring
  • VueJs
  • JPA (Hibernate)

This is my first experience in writing Sping application and web app development overall.

I have 4 tables in my DataBase:

  • Language
  • Sentence
  • Rule
  • User

For example in Rule there is :

Rule create(EntityManagerFactory factory, String type, String hint, String help, Language language); 
List<Rule> readAll(EntityManagerFactory factory);
Rule readID(EntityManagerFactory factory, int id); 
void update(EntityManagerFactory factory, String type, String hint, String help, Language language);

So there is my questions:

  1. When I create Controllers for each table, I use the CRUD methods to modify (or not) my database, and I return a view for my HTML and VueJS part. But my method need an EntityManagerFactory, should I create a field in each Controllers class or this is not how I'm supposed to do ?
  2. Do I need to create a bean file and configure it or persistence.xml and pom.xml are enough?

Thanks

If you are using spring Boot then you don't need entity manager. All you need to do is to define Datasource in you properties file. And create a Bean in our Configuration class just like:

@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource datasource() {
    return DataSourceBuilder.create().build();
}

Now rest of the things you can handle with repositories.They will be like:

import org.springframework.data.repository.CrudRepository;

public interface RuleRepository extends CrudRepository<Rule, Long>  {

}

In your controllers you will use it like:

@Autowired
private RuleRepository ruleRepository;

@Get
@Path("/getRule/:id")
public Rule find(@PathParam("id")Long id){
    return ruleRepository.findOne(id);
}

These dependencies I used in my gradle project. You will find Maven version for same:

compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile group: 'mysql', name: 'mysql-connector-java'

Seems like your first question can be broken up into multiple concerns.

When I create Controllers for each table, I use the CRUD methods to modify (or not) my database, and I return a view for my HTML and VueJS part. But my method need an EntityManagerFactory, should I create a field in each Controllers class or this is not how I'm supposed to do?

Since you have already accepted an answer that recommends the use of spring-data-jpa . You will be dealing with entities and repositories.

Entities are JPA managed beans that will interact with your database.

@Entity
@Table(name = "rule")
public class Rule {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    long id;
    String type;
    ...
    @OneToOne
    @JoinColumn(...)
    Language language;
}

Repositories will provide all the necessary operations required to perform an action against your database. With JPA you can create an interface that extends CrudRepository which would provide you with some CRUD operations that come free with it. findOne(/* id */) , delete() , save()

@Repository
public interface RuleRepository extends CrudRepository<Rule, Long> {

     // You can easily specify custom finders
     public List<Rule> findByType(String type);

}

But my method need an EntityManagerFactory, should I create a field in each Controllers class or this is not how I'm supposed to do?

It's typically frowned upon to have a request/response object to be JPA entity. See the linked answer for should i use jpa entity in rest request and/or response

There are multiple approaches that you can take to take a controller request and send a response to your client side project.

@Controller
public class RuleController {
    @Autowired
    private RuleRepository ruleRepository;

    // Approach 1: Use Request Parameters - enforce inputs
    @PostMapping("/rule/:id")
    public Rule postWithRequestParams(@PathParam("id") Long id, 
                    @RequestParam("type") String type, 
                    @RequestParam("hint") String hint, 
                    @RequestParam("languageField1") String languageField1) {
        Rule inputRule = new Rule(id, type, hint, new Language(languageField1));

        Rule responseRule = ruleRepository.save(inputRule);
        return responseRule; // I would imagine you would want to set up a model for the response itself
    }



    // Approach 2: Use RequestBody - serialize Rule from the request
    @PostMapping("/rule/:id")
    public Rule postWithRequestParams(@PathParam("id") Long id, @RequestBody Rule inputRule) {
        Rule responseRule = ruleRepository.save(inputRule);
        return responseRule;
    }

Do I need to create a bean file and configure it or persistence.xml and pom.xml are enough?

If you have added spring-boot-starter-data-jpa as a dependency, a lot of the bean configuration has already been done for you.

In your main/src/resources (you should have an application.properties or application.yml )

spring.datasource.url= # JDBC url of the database.
spring.datasource.username= # Login user of the database.
spring.datasource.password= # Login password of the database.

Spring does a lot of the magic and heavy lifting for you.

You definitely need to have a look on Spring Boot ( http://start.spring.io ), it allows easier to start web app development. As for persistence layer you could use Spring Data JPA (already includes Hibernate) module which also can be easily integrated with Spring Boot. The beauty of Spring Data that is already have written by default most queries like save(), remove(), find() and so on. You only need to define Objects which will be used by Spring Data.

Update: See my Spring Boot REST API example here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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