本文标题:SpringBoot引入Spring Data JPA
原始链接: https://shuibo.cn/04-spring-boot-spring-data-jpa.html
许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。
1. Jpa介绍
JPA(Java Persistence API)是一种Java持久化解决方案,是Sun官方在JDK5.0后提出的规范(JSR388,接口包在javax.persistence),不是一个产品,例如Hibernate是产品。
JPA是在吸收现有ORM框架的基础上发展而来,总得包括以下:
- ORM映射:支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系
- API:操作实体对象来执行CRUD操作
- 查询语言:通过面向对象而非面向数据库的查询语言(JPQL)查询数据,避免程序的SQL语句紧密耦合
2. 什么是Spring Data Jpa
Spring Data Jpa是Spring Data家族的一部分,Spring Data JPA相对于Java EE中的JPA,配置更简单,以轻量级的方式实现了部分在 EJB 容器环境下才具有的功能,将 EntityManager 的创建与销毁、事务管理等代码抽取出来,并由其统一管理,并且极大的简化了数据库访问层的代码。
Spring Data包含众多子项目除了JPA还有Spring Data MongoDB等等
3. 引入Spring Data Jpa
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
创建Test表(略),设置数据库链接
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
username: root
password: root
jpa:
database: mysql
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
show-sql: true
hibernate:
ddl-auto: update
# create: 每次运行程序时,都会重新创建表,故而数据会丢失
# create-drop: 每次运行程序时会先创建表结构,然后待程序结束时清空表
# upadte: 每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)
# validate: 运行程序会校验数据与数据库的字段类型是否相同,字段不同会报错
# none: 禁用DDL处理
4. 使用Spring Data Jpa增删改查
- 实体类
@Entity
@Table(name = "t_test")
public class Test {
@Id
@GeneratedValue
private Long id;
@Column(name = "username", unique = true, nullable = false, length = 64)
private String username;
@Column(name = "age",unique = true)
private Integer age;
// 忽略 Get Set 方法
. . .
}
- 建立数据库访问层
使用Spring Data JPA建立数据库十分简单,只需要定义一个继承了JpaRepository的接口
public interface TestJpaRepository extends JpaRepository<Test, Long> {}
继承了JpaRepository就相当于有了下面的数据访问操作方法,这些都是Spring Data Jpa封装好的。
@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
List<T> findAll();
List<T> findAll(Sort var1);
List<T> findAllById(Iterable<ID> var1);
<S extends T> List<S> saveAll(Iterable<S> var1);
void flush();
<S extends T> S saveAndFlush(S var1);
void deleteInBatch(Iterable<T> var1);
void deleteAllInBatch();
T getOne(ID var1);
<S extends T> List<S> findAll(Example<S> var1);
<S extends T> List<S> findAll(Example<S> var1, Sort var2);
}
Jpa三种查询方法介绍
1.方法命名查询
/**
* 通过username查询
* @param username username
* @return
*/
List<Test> findByUsername(String username);
/**
* 通过username + age查询
* @param username username
* @param age age
* @return
*/
List<Test> findByUsernameAndAge(String username,Integer age);
/**
* 查询符合年龄条件的前10条数据
* @param age
* @return
*/
List<Test> findFirst10ByAge(Integer age);
/**
* 查询符合Name条件的前10条数据
* @param username
* @return
*/
List<Test> findTop10ByUsername(String username);
2.@NamedQuery查询
Spring Data JPA 支持@NameQuery来定义查询方法,即一个名称映射一个查询语句(要在实体类上写,不是接口里写)
@Entity
@Table(name = "t_test")
@NamedQuery(name="findByAge", query="select t from Test t where t.age=?1")
public class Test {
@Id
@GeneratedValue
private Long id;
@Column(name = "username", unique = true, nullable = false, length = 64)
private String username;
@Column(name = "age",unique = true)
private Integer age;
}
如果要定义多个命名查询,需要使用@NamedQueries
@Entity
@Table(name = "t_test")
@NamedQuery(name="findByAge", query="select t from Test t where t.age=?1")
@NamedQueries({
@NamedQuery(name="findAllTest",query="select t from Test t"),
@NamedQuery(name="findTestWithId",query="SELECT t FROM Test t WHERE t.id = ?1"),
@NamedQuery(name="findTestWithUsername",query="SELECT t FROM Test t WHERE t.username = :username")
})
public class Test {
@Id
@GeneratedValue
private Long id;
@Column(name = "username", unique = true, nullable = false, length = 64)
private String username;
@Column(name = "age",unique = true)
private Integer age;
调用时:
EntityManager em = emf.createEntityManager();
List<Test> tests = em.createNamedQuery("findAllTest").getResultList();//根据Test实体中定义的命名查询
EntityManager em = emf.createEntityManager();
Query query = em.createNamedQuery("findTestWithId");//根据Test实体中定义的命名查询
query.setParameter(1, 2L);
List<Test> tests = query.getResultList();
3.@Query查询
Spring Data JPA 支持@Query来定义查询方法
@Query("select t from Test t where t.username=?1 and t.age=?2")
List<Test> getAllByUsernameAndAge(String username,Integer age);
Spring Data JPA支持使用@Modifying和@Query注解组合来进行更新查询
// int表示的是更新语句所影响的行数
@Modifying
@Query("update Test t set t.username=?1")
int setUserName(String username);
testJpaRepository.findAll();
// 根据id查询
testJpaRepository.getOne(1L);
// 增加
testJpaRepository.save(test);
// 删除
testJpaRepository.delete(test);
// 数据数量(条)
testJpaRepository.count();
...
...
...
支持的关键字、示例及JPQL片段如下表所示:
Keyword | Sample | JPQL Snippet |
---|---|---|
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | indByFirstname,findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age <= ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | ... findByFirstnameNotLike |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection<Age> ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection<Age> ages) | … where x.age not in ?1 |
True | findByActiveTrue() | … where x.active = true |
False | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
... | ... | ... |
具体Spring Data Jpa对方法名的解析规则可参看官方文档4.4.3. Property Expressions
5. 小结
本篇内容主要介绍了在Spring Boot中引入Spring Data JPA以及JPA的简单基础引用,本篇未及地方日后有空再补。
本文GitHub地址:https://github.com/ishuibo/SpringAll