一、Spring data jpa介绍

一、Spring data jpa介绍

引自

Spring Data JPA Tutorial: Introduction(https://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-introduction/)

正文

通常来说,我们使用JPA去实现我们的DAO(data access object)层,需要花费大量的时间,一般而言,我们会使用下面的步骤:

  1. 创建一个抽象的DAO类,去提供针对entity的通用CRUD操作,这个类在我的项目里通常被叫做BaseDao、AbstractDAO偶尔也被叫做CommonDao。
  2. 创建一个具体的实现类,去继承这个抽象的DAO类,然后编写具体的行为。

大概的实现方式如下:

  • BaseDao 接口定义
  • BaseDao Hibernate抽象实现类
  • 某业务Dao的接口定义
  • 某业务Dao的接口实现
 
/**
 * BaseDao接口设计
 * @param <T> 类
 * @param <PK> 主键类型
 * @Author Tan
 * @DATE 17-4-21 下午9:10
 */
public interface BaseDao<T,PK> {
    //添加  
     void add(T t);
    //删除  
     void delete(T t);
    //更新  
     void update(T t);
    //根据id查询  
     T findOne(PK id);
    //查询所有  
     List<T> findAll();
}


/**
 * BaseDao Hibernate实现,删除了部分代码
 * @param <T> 类
 * @param <PK> 主键类型
 * @Author Tan
 * @DATE 17-4-21 下午9:10
 */
public abstract class BaseDaoImpl<T,PK> extends HibernateDaoSupport implements BaseDao<T,PK>  {
    //添加
    public void add(T t){
        this.getHibernateTemplate().save(t);
    }
    //删除
    public void delete(T t){
        this.getHibernateTemplate().delete(t);
    }
    //更新
    public void update(T t){
        this.getHibernateTemplate().update(t);
    }
    //根据id查询
    public T findOne(PK id){
        return (T)this.getHibernateTemplate().get(clazzP, id);
    }
    //查询所有
    public List<T> findAll(){
        return (List<T>) this.getHibernateTemplate().find("from "+clazzP.getSimpleName());
    }
}


/**
 * Student的Dao设计
 * @Author Tan
 * @DATE 17-4-21 下午9:27
 */
public interface StudentDao extends BaseDao<Student,Long> {
}



/**
 * Student的具体Dao实现
 * @Author Tan
 * @DATE 17-4-21 下午9:29
 */
public class StudentDaoImpl extends BaseDaoImpl<Long> implements StudentDao {
}

 

 

说实话,这样很麻烦,我们依然要写很多代码去实现我们的数据库查询和调用。更坑爹的是,每次我们在创建新的数据库查询的时候,我们都不得不干一遍上面的事情,太浪费时间了。

实际上,在我以前经历的某个项目的框架中,按照上面的思路,做了进一步的优化,就是实现一个通用Dao。大致的思路是在上述的BaseDao中追加对于Hql和Sql的支持,不使用范型,id的生成策略写死成UUID。然后我们就有了一个真正意义上万能的通用DAO。在那个项目中,Dao层完全被这一个CommonDao给代替了。所以,不妨设想一下,我们当时遇到了什么问题?

这篇文章会介绍什么是Spring-data-jpa,我们将了解这到底是个什么,并且将理顺一下Spring data的repository的接口。

题外话:前文说了,spring data jpa是为了解决传统DAO层的问题,他们为这种强壮的DAO层命名为repository,令我们困惑的是其中文翻译通常是仓库,看起来词不达意,但是“repository system”通常被翻译为“处置库系统” ,瞬间了然。

所以spring data jpa的思想就可以被描述为spring data jpa是向某实体提供处置库(repository)的解决方案,至于这个处置库里到底包含了什么,我们下面继续说。

什么是Spring Data APIS?

再次强调,Spring Data JPA不是一个JPA供应商(例如hibernate)。它是一个在JPA供应商基础上增加的额外一个抽象层(处置库层),本质上是个库或者说框架。通常来说,如果我们选用Spring Data JPA,那么程序调用的方式就变成了如下的模式:

  • Spring Data JPA:根据Spring Data的处置库接口,去创建一个JPA标准的处置库。
  • Spring data common:Spring data project提供的数据存储基础框架。
  • JPA供应商提供 Java Persitence API的实现。

下面这个图描述了处置库层的: 

推荐阅读: spring data jpa 、jpa、ORM的区别

你一定在想,Spring data JPA的这种设计让我们的应用程序变得更加复杂了,哈哈,你猜对了。它确实在我们的处置层里追加了一层,但是,这种设计能让我们减少代码量。如果是这个目的的话,那么现在听起来,就还可以接受了吧?

Spring data Repositoris介绍

Spring data JPA层的本质是在程序处置层中根据Spring data common Project提供的接口做特定存储的子项目。 当然,我们在使用Spring data jpa的过程中,并不需要了解它是如何实现的抽象处置库,但是我们必须非常熟悉SPring data的处置接口。 这些接口主要包含下述内容:


第一层接口:SPring data Commons project提供如下的接口:


第二层接口:Spring data JPA提供如下接口:


处置库的继承关系如下: 

说的差不多了,但是我们怎么用它? 后面的文章会回答这个问题,但是原则上一般使用一下的步骤:

  1. 创建一个继承Spring data repository 的接口。
  2. 如果我们有特定需求,在这个接口中创建特定的执行方法。
  3. 将这个接口注入到其他系统组件中,我们就可以直接用了。

Repository(处置库)到底是什么?

个人理解,DAO(Data Access Object)层就是我们应用程序针对于数据库的Repository,它是程序中DO(Data Object)与数据库的桥梁,将程序对实体的操作,翻译成sql语言,这也是ORM的本质。

什么叫处置库?处置库里有什么?

更便于理解的叫法应该是“处理库”,这里放的是一些“处理方法”。对于数据库而言,我们的处理方法无非就是CRUD(create,Retrieve,Update,Delete),也就是我们说的增删改查。这也就是上文中“CrudRepository<T, ID extends Serializable>”产生的根本。

而实际业务中,我们对数据库的操作,可能更为细化,那么这些更加细化的需求,则是我们某个处置库里需要追加的特有的方法。

举例: 上文中的BaseDao就是通用处置库,而StudentDao则是一个学生对象特有的处置库。

QueryDSL参考

关于这部分内容,感兴趣可以参考QueryDSL的源码

这里是项目的一个单元测试,可以感受一下效果。

assertEquals(Arrays.asList(),
                query().from(entity, entity2)
                        .where(bigd1.add(bigd2).loe(new BigDecimal("1.00")))
                        .select(entity).fetch());

总结

本位尝试在描述下面的两件事:

  • Spring data jpa 并不是一个JPA供应商,它是Java Persistence API (和JPA供应商)的在处置层(传统DAO层)的封装。
  • Spring data为实现不同的目的,提供了多种接口。

下一章,我们将了解SPring data JPA的必要依赖。

备注

原文作者简介:

Petri Kainulainen is passionate about software development and continuous improvement. He is specialized in software development with the Spring Framework and is the author of Spring Data book.

声明:

这里并不是原文100%的翻译,而是追加了个人的一些想法和补充,原文地址在本文最上方,请自行判断阅读哪一个版本。

posted @ 2017-04-22 23:09  Tan1  阅读(102)  评论(0编辑  收藏  举报