SpringBoot - 整合SpringData与JPA

前面说过对于数据访问层,无论是SQL还是NOSQL,Spring Boot默认采用整合
Spring Data的方式进行统一处理,添加大量自动配置,屏蔽了很多设置。引入各种xxxTemplate,xxxRepository来简化我们对数据访问层的操作。对我们来说只需要进行简单的设置即可。

结构示意图如下:

这里写图片描述


【1】SpringData

如下图所示,SpringBoot提供了许多data-starter(地址):

这里写图片描述


Spring Data 项目的目的是为了简化构建基于Spring 框架应用的数据访问技术,包括非关系数据库、Map-Reduce 框架、云数据服务等等。另外也包含对关系数据库的访问支持。

① Spring Data 包含多个子项目:

–Spring Data Commons
–Spring Data JPA
–Spring Data KeyValue
–Spring Data LDAP
–Spring Data MongoDB
–Spring Data Gemfire
–Spring Data REST
–Spring Data Redis
–Spring Data for Apache Cassandra
–Spring Data for Apache Solr
–Spring Data Couchbase (community module)
–Spring Data Elasticsearch (community module)
–Spring Data Neo4j (community module)


② SpringData特点

SpringData为我们提供使用统一的API来对数据访问层进行操作—–这主要是Spring Data Commons项目来实现的。

Spring Data Commons让我们在使用关系型或者非关系型数据访问技术时都基于Spring提供的统一标准,标准包含了CRUD(创建、获取、更新、删除)、查询、排序和分页的相关操作。


③ 统一的Repository接口

接口结构图如下:

这里写图片描述

说明如下:

Repository<T, ID extends Serializable>:统一接口

RevisionRepository<T, ID extends Serializable, N extends Number & Comparable<N>>:基于乐观锁机制

CrudRepository<T, ID extends Serializable>:基本CRUD操作

PagingAndSortingRepository<T, ID extends Serializable>:基本CRUD及分页

④ 提供数据访问模板类xxxTemplate

如:MongoTemplate、RedisTemplate等


⑤ JPA与Spring Data

1)JpaRepository基本功能

编写接口继承JpaRepository既有crud及分页等基本功能。


2)定义符合规范的方法命名

在接口中只需要声明符合规范的方法,即拥有对应的功能,如下图所示(官网地址):

这里写图片描述
这里写图片描述

3)@Query自定义查询,定制查询SQL


4)Specifications查询(Spring Data JPA支持JPA2.0的Criteria查询)


【2】SpringBoot整合JPA

这里使用单个示例进行过程讲解。

① 编写一个实体类(bean)和数据表进行映射,并且配置好映射关系

源码示例如下:

//使用JPA注解配置映射关系
@Entity //告诉JPA这是一个实体类(和数据表映射的类)
@Table(name = "tbl_user") //@Table来指定和哪个数据表对应;如果省略默认表名就是user;
public class User {

    @Id //这是一个主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)//自增主键
    private Integer id;

    @Column(name = "last_name",length = 50) //这是和数据表对应的一个列
    private String lastName;
    @Column //省略默认列名就是属性名
    private String email;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

② 编写一个Dao接口来操作实体类对应的数据表(Repository)

UserRepository 源码示例如下:

//继承JpaRepository来完成对数据库的操作
public interface UserRepository extends JpaRepository<User,Integer> {
    List<User> findByEmail(String email);
}

JpaRepository接口示例如下:

@NoRepositoryBean
public interface JpaRepository<T, ID extends Serializable>
        extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {

    /*
     * (non-Javadoc)
     * @see org.springframework.data.repository.CrudRepository#findAll()
     */
    List<T> findAll();

    /*
     * (non-Javadoc)
     * @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort)
     */
    List<T> findAll(Sort sort);

    /*
     * (non-Javadoc)
     * @see org.springframework.data.repository.CrudRepository#findAll(java.lang.Iterable)
     */
    List<T> findAll(Iterable<ID> ids);

    /*
     * (non-Javadoc)
     * @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable)
     */
    <S extends T> List<S> save(Iterable<S> entities);

    /**
     * Flushes all pending changes to the database.
     */
    void flush();

    /**
     * Saves an entity and flushes changes instantly.
     * 
     * @param entity
     * @return the saved entity
     */
    <S extends T> S saveAndFlush(S entity);

    /**
     * Deletes the given entities in a batch which means it will create a single {@link Query}. Assume that we will clear
     * the {@link javax.persistence.EntityManager} after the call.
     * 
     * @param entities
     */
    void deleteInBatch(Iterable<T> entities);

    /**
     * Deletes all entities in a batch call.
     */
    void deleteAllInBatch();

    /**
     * Returns a reference to the entity with the given identifier.
     * 
     * @param id must not be {@literal null}.
     * @return a reference to the entity with the given identifier.
     * @see EntityManager#getReference(Class, Object)
     */
    T getOne(ID id);

    /* (non-Javadoc)
     * @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example)
     */
    @Override
    <S extends T> List<S> findAll(Example<S> example);

    /* (non-Javadoc)
     * @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example, org.springframework.data.domain.Sort)
     */
    @Override
    <S extends T> List<S> findAll(Example<S> example, Sort sort);

}

其中PagingAndSortingRepository又继承自CrudRepository,PagingAndSortingRepository源码如下:

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {

    /**
     * Returns all entities sorted by the given options.
     * 
     * @param sort
     * @return all entities sorted by the given options
     */
    Iterable<T> findAll(Sort sort);

    /**
     * Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.
     * 
     * @param pageable
     * @return a page of entities
     */
    Page<T> findAll(Pageable pageable);
}

③ 在application.yml文件中对jpa进行配置

示例如下:

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1/test
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
    hibernate:
#     更新或者创建数据表结构
      ddl-auto: update
#    控制台显示SQL
    show-sql: true

④ 编写Controller进行简单测试

UserController源码如下:

@RestController
public class UserController {

    @Autowired
    UserRepository userRepository;

    @GetMapping("/user/{id}")
    public User getUser(@PathVariable("id") Integer id){

        User user = userRepository.findOne(id);
        List<User> list = userRepository.findByEmail("[email protected]");
        System.out.println(list.get(0));
        return user;
    }

    @GetMapping("/user")
    public User insertUser(User user){
        User save = userRepository.save(user);
        return save;
    }

}

启动项目,测试结果如下:

1)插入数据

这里写图片描述

数据库显示:

这里写图片描述


② 获取数据

这里写图片描述
这里写图片描述

更多JPA的使用参考博客:博客地址

猜你喜欢

转载自blog.csdn.net/j080624/article/details/80827953