1.3.4 数据访问
无论互联网应用还是传统软件,对于任何一个系统而言,数据的存储和访问都是不可缺少的。数据访问层的构建可能会涉及多种不同形式的数据存储媒介,本书关注的是最基础也是最常用的数据存储媒介,即关系型数据库。Spring Boot对关系型数据库访问的支持包括两大部分内容,即基于JDBC(Java DataBase Connectivity,Java数据库连接)规范的Spring JDBC组件和支持ORM(Object Relational Mapping,对象关系映射)的Spring Data组件。
1. 数据访问的实战内容
(1)Spring JDBC
针对关系型数据库,Java世界中应用最广泛的就是JDBC规范,但JDBC规范是一种偏底层的实现技术,不适合直接面向业务开发。Spring框架基于JDBC规范,提供了一整套的解决方案,包括常用的JdbcTemplate模板工具类,以及在JdbcTemplate基础上构建的能够进一步简化数据访问操作的SimpleJdbcInsert等组件。
在Spring中,以-Template结尾的模板工具类应用非常广泛,而这些模板工具类的设计和实现最大限度地发挥了模板方法设计模式的优势,并基于回调机制解决了原生JDBC等组件所面临的复杂性问题。JdbcTemplate作为一种典型的模板工具类,其实现过程非常具有代表性,为开发人员如何对底层框架进行封装和扩展提供了范本。因此,本书也将对JdbcTemplate的源码展开讨论,讲解其中的设计理念和实现技巧。
从实战角度讲,Spring JDBC的使用涉及很多技术细节,例如优化事务隔离等级、优化Fetch Size、优化连接池配置、选择合适的Statement、使用批处理、选择合适的提交模式等。针对这些技术细节,我们都将给出对应的实战技巧。
(2)Spring Data
事实上,JdbcTemplate是相对偏底层的一个工具类。作为系统开发最重要的基础功能之一,数据访问层组件的开发方式在Spring Boot中也得到了进一步的简化,并充分发挥了Spring家族中另一个重要成员Spring Data的作用。Spring Data是基于Repository架构模式抽象出来的一套统一的数据访问组件,是一款支持JPA等多种数据访问规范的ORM框架。
在使用Hibernate等ORM框架时,会碰到经典的N+1性能问题。针对该问题存在多种解决方案,常见的包括JOIN FETCH和Entity Graph机制。对于JOIN FETCH,可以使用JPA查询语句和Criteria API这两种实现方式;而对于Entity Graph,可以使用Named Entity Graph和Dynamic Entity Graph。
从实战角度讲,通过统计找到数据访问瓶颈并使用延迟加载减少数据库访问是常见的开发技巧。而另一种常见的开发技巧就是使用多级缓存提升数据访问性能。诸如Mybatis和Hibernate等主流ORM框架都提供了多级缓存机制来确保对内存对象的合理管理。
2. 数据访问的实战案例
针对Spring提供的数据访问功能,我们将分别基于Spring JDBC以及Spring Data JPA给出相应的案例分析。
Spring JDBC中,除了JdbcTemplate之外,还存在一大批非常有用的工具类,包括Named-ParameterJdbcTemplate、SimpleJdbcTemplate、SimpleJdbcInsert和SimpleJdbcCall等。我们将基于一个案例来演示如何使用JdbcTemplate和SimpleJdbcInsert实现数据的高效查询和插入。
Spring Data中所包含的技术组件也非常丰富,我们主要针对Spring Data JPA这款框架给出案例分析。JPA只是一种规范,而不是具体的实现。而Hibernate框架遵循JPA规范,并且还有一些自己的附加特性。在使用JPA规范时,将首选Hibernate这款老牌的ORM框架。