如何使用Spring Boot与MySQL数据库和JPA?

31
我想要使用MySQL和JPA设置Spring Boot。为此,我创建了一个名为Person的类:
package domain;

import javax.persistence.*;

@Entity
@Table(name = "person")
public class Person {

@Id
@GeneratedValue
private Long id;

@Column(nullable = false)
private String firstName;

// setters and getters
}

人员仓库。
package repository;

import domain.Person;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.CrudRepository;


public interface PersonRepository extends CrudRepository<Person, Long> {

Page<Person> findAll(Pageable pageable);
}

人员控制器
package controller;

import domain.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import repository.PersonRepository;

@Controller
public class PersonController {

@Autowired
private PersonRepository personRepository;

@RequestMapping("/")
@ResponseBody
public String test() {
    Person person = new Person();
    person.setFirstName("First");
    person.setLastName("Test");
    personRepository.save(person);
    return "hello";
}
}

开始课程 示例:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Example {

public static void main(String[] args) throws Exception {
    SpringApplication.run(Example.class, args);
}

}

对于数据库配置,我创建了application.properties文件。
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.globally_quoted_identifiers=true

spring.datasource.url=jdbc:mysql://localhost/test_spring_boot
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driverClassName=com.mysql.jdbc.Driver

所以我的项目结构如下:

enter image description here

但是结果是,我有一些例外情况:
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [Example]; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/security/config/annotation/authentication/configurers/GlobalAuthenticationConfigurerAdapter.class] cannot be opened because it does not exist

作为例子,我使用:spring-boot-sample-data-jpa/pom.xml

那个链接想要告诉我们什么?这是Spring Boot Data JPA示例的1.2.2.BUILD-SNAPSHOT的pom.xml文件。另外,请问你是如何运行这个应用程序的? - Steve
@Steve,我在IDE IDEA中运行了我的Example.java。 - somebody
它能从命令行运行吗? - Steve
1
不是答案。但是,如果你遇到了问题,可能是因为你正在使用已弃用的驱动程序类名。请改用 spring.datasource.driverClassName=com.mysql.cf.jdbc.Driver - Sushant Paudel
7个回答

29

我像你一样创建了一个项目。结构看起来像这样:

project structure

类只是从你的代码里复制粘贴过来的。

我将 application.properties 文件改成了这样:

spring.datasource.url=jdbc:mysql://localhost/testproject
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update

但我认为你的问题在于你的pom.xml文件中:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.1.RELEASE</version>
</parent>

<artifactId>spring-boot-sample-jpa</artifactId>
<name>Spring Boot JPA Sample</name>
<description>Spring Boot JPA Sample</description>

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

检查这些文件的差异。希望这可以帮助到您。

更新1:我更改了我的用户名。示例的链接现在为https://github.com/Yannic92/stackOverflowExamples/tree/master/SpringBoot/MySQL


我复制了你的更改。这非常令人难过,但我仍然遇到异常 Caused by: java.io.FileNotFoundException: class path resource [org/springframework/security/config/annotation/authentication/configurers/GlobalAuthenticationConfigurerAdapter.class] cannot be opened because it does not exist - somebody
你的项目中有比你向我们展示的更多内容。你的问题与Spring Security有关。你的Maven依赖中是否仍然包含Spring Security? - Yannic Bürgmann
不,我没有。我展示了所有的架构和类。 - somebody
等一下,我会把我的项目上传到GitHub上,这样你就可以从那里获取了。它应该是和你的项目完全一样,并且能够正常运行。 - Yannic Bürgmann
您的代码真的很好用!我找不到您的项目和我的之间的区别。无论如何,谢谢你! - somebody

3

当将类移动到特定的包中,例如repository、controller和domain,仅使用通用的@SpringBootApplication是不够的。

您需要指定组件扫描的基本包。

@ComponentScan("base_package")

针对JPA

@EnableJpaRepositories(basePackages = "repository")

还需要配置数据源,这样Spring Data才知道要在哪里查找存储库接口。


3
是的和不是。如果你使用@SpringBootApplication,那么你所有的组件都必须与使用@SpringBootApplication注解的类在同一级别或更低的级别。在这个例子中是这样的,所以不需要@ComponentScan - Yannic Bürgmann

3
请添加mysql-connector-java依赖项。保留html,不要解释。
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>

并在 application.properties 中添加以下属性:

# Data Source properties
spring.datasource.url=jdbc:mysql://localhost:3306/yourDatabaseName?useSSL=false
spring.datasource.username=root
spring.datasource.password=YourPassword
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# JPA properties 
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update

2

对于基于Jpa的应用程序:基础包扫描 @EnableJpaRepositories(basePackages = "repository") 你可以尝试一下!!!
项目结构

com
 +- stack
     +- app
     |   +- Application.java
     +- controller
     |   +- EmployeeController.java
     +- service
     |   +- EmployeeService.java
     +- repository
     |   +- EmployeeRepository.java
     +- model
     |   +- Employee.java
-pom.xml
dependencies: 
    mysql, lombok, data-jpa

application.properties

#Data source :
spring.datasource.url=jdbc:mysql://localhost:3306/employee?useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.generate-ddl=true
spring.datasource.driverClassName=com.mysql.jdbc.Driver

#Jpa/Hibernate :
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto = update

Employee.java

@Entity
@Table (name = "employee")
@Getter
@Setter
public class Employee {

    @Id
    @GeneratedValue (strategy = GenerationType.IDENTITY)
    private Long id;

    @Column (name = "first_name")
    private String firstName;
    @Column (name = "last_name")
    private String lastName;
    @Column (name = "email")
    private String email;
    @Column (name = "phone_number")
    private String phoneNumber;
    @Column (name = "emp_desg")
    private String desgination;
}

EmployeeRepository.java

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}

EmployeeController.java

@RestController
public class EmployeeController {

    @Autowired
    private EmployeeService empService;

    @GetMapping (value = "/employees")
    public List<Employee> getAllEmployee(){
        return empService.getAllEmployees();
    }

    @PostMapping (value = "/employee")
    public ResponseEntity<Employee> addEmp(@RequestBody Employee emp, HttpServletRequest 
                                         request) throws URISyntaxException {
        HttpHeaders headers = new HttpHeaders();
        headers.setLocation(new URI(request.getRequestURI() + "/" + emp.getId()));
        empService.saveEmployee(emp);
        return new ResponseEntity<Employee>(emp, headers, HttpStatus.CREATED);
    }

EmployeeService.java

public interface EmployeeService {
    public List<Employee> getAllEmployees();
    public Employee saveEmployee(Employee emp);
}

EmployeeServiceImpl.java

@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    private EmployeeRepository empRepository;

    @Override
    public List<Employee> getAllEmployees() {
        return empRepository.findAll();
    }

    @Override
    public Employee saveEmployee(Employee emp) {
        return empRepository.save(emp);
    }
}

EmployeeApplication.java

@SpringBootApplication
@EnableJpaRepositories(basePackages = "repository")
public class EmployeeApplication {
    public static void main(String[] args) {
        SpringApplication.run(EmployeeApplication.class, args);
    }
}

0
spring boot reference中,它说:

当一个类没有包声明时,它被认为是在“默认包”中。通常不建议使用“默认包”,应该避免使用。这可能会对使用@ComponentScan、@EntityScan或@SpringBootApplication注释的Spring Boot应用程序造成特定问题,因为每个jar文件中的每个类都将被读取。

com
 +- example
     +- myproject
         +- Application.java
         |
         +- domain
         |   +- Customer.java
         |   +- CustomerRepository.java
         |
         +- service
         |   +- CustomerService.java
         |
         +- web
             +- CustomerController.java

在您的情况下,您必须在@SpringBootApplication注释中添加scanBasePackages。就像这样:@SpringBootApplication(scanBasePackages={"domain","contorller"..})

0

你的代码在默认包中,也就是说你将所有文件都放在了src/main/java目录下,没有自定义的包。我强烈建议你创建一个包并将源文件放入其中。

Ex-
 src->
     main->
          java->
                com.myfirst.example
                   Example.java
                com.myfirst.example.controller
                   PersonController.java
                com.myfirst.example.repository
                  PersonRepository.java
                com.myfirst.example.model
                   Person.java

我希望它能解决你的问题。


-10

您可以将Application.java移动到java文件夹下的一个文件夹中。


这并没有为问题提供答案。如果要批评或请求作者澄清,请在其帖子下留言 - 您始终可以对自己的帖子发表评论,并且一旦您获得足够的声誉。- [来自评论审核] (/review/low-quality-posts/10777423) - Shahzad Barkati
我尝试运行应用程序,但在将主类移动到文件夹后仍然遇到相同的异常。移动主类后,应用程序可以成功运行。 - wuyuexin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接