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片段如下表所示:

KeywordSampleJPQL Snippet
AndfindByLastnameAndFirstname… where x.lastname = ?1 and x.firstname = ?2
OrfindByLastnameOrFirstname… where x.lastname = ?1 or x.firstname = ?2
Is,EqualsindByFirstname,findByFirstnameIs,findByFirstnameEquals… where x.firstname = ?1
BetweenfindByStartDateBetween… where x.startDate between ?1 and ?2
LessThanfindByAgeLessThan… where x.age < ?1
LessThanEqualfindByAgeLessThanEqual… where x.age <= ?1
GreaterThanfindByAgeGreaterThan… where x.age > ?1
GreaterThanEqualfindByAgeGreaterThanEqual… where x.age >= ?1
AfterfindByStartDateAfter… where x.startDate > ?1
BeforefindByStartDateBefore… where x.startDate < ?1
IsNullfindByAgeIsNull… where x.age is null
IsNotNull,NotNullfindByAge(Is)NotNull… where x.age not null
LikefindByFirstnameLike… where x.firstname like ?1
NotLikefindByFirstnameNotLike… findByFirstnameNotLike
StartingWithfindByFirstnameStartingWith… where x.firstname like ?1 (parameter bound with appended %)
EndingWithfindByFirstnameEndingWith… where x.firstname like ?1 (parameter bound with prepended %)
ContainingfindByFirstnameContaining… where x.firstname like ?1 (parameter bound wrapped in %)
OrderByfindByAgeOrderByLastnameDesc… where x.age = ?1 order by x.lastname desc
NotfindByLastnameNot… where x.lastname <> ?1
InfindByAgeIn(Collection ages)… where x.age in ?1
NotInfindByAgeNotIn(Collection ages)… where x.age not in ?1
TruefindByActiveTrue()… where x.active = true
FalsefindByActiveFalse()… where x.active = false
IgnoreCasefindByFirstnameIgnoreCase… 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

   
     
本文作者:      
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
扫码关注不迷路!

发表评论

电子邮件地址不会被公开。 必填项已用*标注