JPA的使用
JPA 也是一种常见的操作数据源方式。在企业中,使用 JPA 的情况也比较频繁,因为在开发过程中,可以使用 JPA 的 API 默认语法,在面对复杂的业务时,还可以在接口上添加注解,然后在注解中书写 SQL 语句,两者结合,可以更加高效地书写代码。下面对 JPA 进行介绍。
JPA概述
JPA 是 Java Persistence API 的缩写,定义了对象关系映射以及持久化实体对象的标准接口,是 JCP 组织发布的 Java EE 标准之一,也是 JSR 规范的一部分。符合 JPA 标准的框架,都会提供相同的 API,方便开发。
JPA 除了支持持久化,还可以支持事务、并发等。JPA 提供简单的编程模型,开发实体对象和接口都比较简单。
但是,这种方式并没有被广泛使用。因为 JPA 需要依赖 Hibernate 才可以存活,随着 Hibernate 的市场缩水,JPA 使用也相应地减少。但作为 Spring Boot 支持的连接数据库的一种方式,这里会介绍它的使用方式。
JPA使用实例
首先,要使用 JPA 需要引入依赖,依赖如下所示。
<!--JPA引入-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
然后,需要在配置文件中添加配置项,这里需在原有的数据源的基础上进行添加,主要是添加与 Hibernate 有关的配置项,因为需要 Hibernate 的支持。在 application.properties 中的配置项如下所示。
spring.datasource.url=jdbc:mysql://localhost:3308/test
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
spring.datasource.dbcp2.max-idle=10
spring.datasource.dbcp2.max-total=50
spring.datasource.dbcp2.max-wait-millis=100000
spring.datasource.dbcp2.initial-size=5
spring.datasource.dbcp2.connection-properties=characterEncoding=utf8
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jmx.enable=false
其中,spring.jpa.hibernate.ddl-auto 有几个常用的配置项,可以配置的还有 create、create-drop、validate。这里选择使用 update,表示自动更新的意思。
create:每次加载时,会删除以前的表,然后重新执行生成新的表,这种方式会让数据库数据丢失。
create-drop:每次加载都会生成新的表,但是在 sessionFactory 关闭时删除表。
spring.jmx.enable 需要配置,不然在 datasource 关闭时,会报错。
在正式写程序之前,展示一些程序结构,方便重现程序,程序结构如图6.6所示。

在 pojo 包下新建一个数据实体类,同时,这个实体类使用的是上文建立的 t_user 表。代码如下所示。
package com.springBoot.dataSource.pojo;
import javax.persistence.*;
@Entity
@Table(name = "t_user")
public class NewUser {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(length = 32)
private String username;
@Column(length = 32,name="password")
private String password;
public NewUser(int id, String username, String password){
this.id=id;
this.username=username;
this.password=password;
}
public NewUser(){
}
//set and get
}
其中,使用注解 @Entity 进行声明,表示这个类是实体类,并对应数据库中的表。@Table 注解是可选的注解,如果没有写,则说明表名与实体的名称一样,否则使用 name 属性进行声明。@Id 注解用于标明主键。@GeneratedValue 注解声明注解采用什么方式进行生成。@Column 注解声明实体属性的表字段的含义,如果数据库字段的名称与类属性的名称不一致,则需要使用 name 属性进行对应,如果是相同,则不需要使用 name 属性。需要注意的是,如果字段不声明长度,系统会使用 255 作为字段的长度。
在上面的程序中,我们使用了两个构造函数。需要注意的是,如果显示使用带参的构造函数,不带任何参数的构造函数也是需要写的,因为 Hibernate 需要使用反射创建对象。
然后,我们新建 UserRepository 接口,它需要继承 JpaRepository 接口。代码如下所示。
package com.springBoot.dataSource.dao;
public interface UserRepository extends JpaRepository<NewUser,Long> {
public List<NewUser> findNewUserById(Long id);
@Query("select art from com.springBoot.dataSource.pojo.NewUser art where username=:username")
public List<NewUser> queryByUsername(@Param("username")String username);
}
上面代码我们实现了两个方法,都是查询,第一个方法符合 JPA 的命名规范,第二个方法则自己实现 JPQL。上面的代码中,使用了 JpaRepository 接口,这里稍做说明,如图6.7所示。

在 JPA 中顶级接口是 Repository,然后 CrudRepository 接口进行了扩展,定义了一些对实体的 “增删改查” 操作。因为功能还不够强大,PagingAndSortingRepository 接口继续增加了排序和分页的功能。这时 JpaRepository 继承了 QueryByExampleExecutor 与 PagingAndSortingRepository,功能更加强大。所以我们在这里使用 JpaRepository 即可。
然后,进行测试。这里继续使用测试类,代码如下所示。
package com.springBoot.dataSource.test;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
@SpringBootApplication
@EnableJpaRepositories(basePackages ="com.springBoot.dataSource.dao")
@EntityScan("com.springBoot.dataSource.pojo")
public class NewUserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
public void test(){
List<NewUser> list=userRepository.queryByUsername("tom");
System.out.println(list);
System.out.println("======");
}
}
上面的代码中,添加了 @EnableJpaRepositories 注解,这个注解指定要扫描的 JPA 包。还添加了 @EntityScan 注解,用于指定有被注解过的 @Entity 的包。为了配合上面的代码,在数据表中手动添加了两条数据,如图6.8所示。

最后,进行测试,为了简化,直接使用断点调试,结果如图6.9所示。
