Spring Boot之Spring Data JPA 入门

时间:2021-03-19 20:33:13

Spring Data JPA也用很久了,这里记录一下最直接的用法


首先,添加依赖,以下是一个简单项目的依赖,连接的数据库是MySql

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


<dependencies>
    <!--spring boot-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!--MySql-->
    <dependency>
        <groupId>MySQL</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>6.0.4</version>
    </dependency>
    <!--/MySql-->
</dependencies>


application.yml的配置如下,默认连接到mytest库。这里显式指定了

  • jpa.hibernate.ddl-auto=none,目的是解除代码同数据库实际的表结构的绑定
  • jpa.hibernate.naming.physical-strategy,Hibernate处理实体的字段时,如果遇到大写字母默认会在前面加下划线,这个配置显式指明要直接输出
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mytest?serverTimezone=GMT%2B8&useSSL=true
    username: AbcUser
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

  jpa:
    hibernate:
      ddl-auto: none
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

数据库里只有一个非常简单的表user_table

Spring Boot之Spring Data JPA 入门


接下来利用IDEA来创建这个表的实体

去database窗口建立好数据库链接

Spring Boot之Spring Data JPA 入门

看看模块有没有用到JPA

Spring Boot之Spring Data JPA 入门

这样就能找到Persistence窗口了

Spring Boot之Spring Data JPA 入门

在Persistence窗口里找到刚才添加的数据源,右键,就能找到生成菜单了

Spring Boot之Spring Data JPA 入门

窗口里一般就设置下输出目录,把需要的表勾选上,点ok,就可以生成实体了

Spring Boot之Spring Data JPA 入门


实体创建好了,就可以去写个repository了,jpa的写法非常简单

public interface JpaUser extends JpaRepository<UserTable, Integer> {

}

就这样,不用写更多的东西了,JpaRepository里已经有简单的增删查改、分页功能了


DAO层的东西就这么多,接下来写个service去调用

@Service
public class UserService {

    private final JpaUser jpaUser;

    @Autowired
    public UserService(JpaUser jpaUser) {
        this.jpaUser = jpaUser;
    }

    public List<UserTable> getAllUser(){
        return jpaUser.findAll();
    }
}

controller也很简单

@Controller
@RequestMapping("Go")
public class GoController {

    @Autowired
    public UserService userService;

    @RequestMapping(value = "/GetDefault")
    @ResponseBody
    public String getDefault() {
        List<UserTable> data = userService.getAllUser();
        if(data.size()>0){
            return data.get(0).getName();
        }else{
            return "No User";
        }
    }
}


默认情况下访问localhost:8080/Go/GetDefault就能看到数据了,到这里jpa就用上了

补充几个注意点:

  • 就这个项目来看,项目的启动类只需要一个注解@SpringBootApplication
  • 会出现spring启动失败的情况,抛出异常org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;这里看到异常是因为没有找到方法javax.persistence.Table.indexes(),网上很多在说实体的@Table同@Entity的问题,找一下文档,发现这个方法是在Java Persistence 2.1开始才有的,但是项目里引用的是2.0——那么解决办法就是到Project Structure里去掉javax.persistence的引用,然后在pom文件里添加
    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.persistence</artifactId>
        <version>3.0-b29</version>
    </dependency>
  • jpa的事务处理,要在@Service的类的方法上添加@Transactional,如果在没有@Service的类里使用@Transactional,事务就不生效了