Spring Data JPA 的应用
前言
前面讲解了JPA相关的基础知识,让我们明白了JPA在数据层上添加注解,从而实现了自动生成的功能。我们今天看一下Spring封装的JPA—Spring Data JPA ,在下面的网址上可以找到相关的文档。
spring.io
一、Spring Data JPA
Spring Data JPA 是应用于Dao层的一个框架,简化数据库开发的,作用和MyBatis框架一样,但是在使用方式和底层机制是有所不同的。最明显的一个特点,Spring Data JPA 开发Dao的时候,很多场景我们连sql语句都不需要开发。由Spring出品。Spring Data JPA 是 Spring 基于JPA 规范的基础上封装的一套 JPA 应用框架,可使开发者用极简的代码即可实现对数据库的访问和操作。它提供了包括增删改查等在内的常用功能!学习并使用 Spring Data JPA 可以极大提高开发效率。这和我们基于Hibernate的JPA还是有区别的。
Hiberanate 是一套成熟的 ORM 框架,而且 Hiberanate 实现了 JPA 规范,所以可以称 Hiberanate 为 JPA 的一种实现方式,我们使用 JPA 的 API 编 程,意味着站在更高的⻆度去看待问题(面向接口编程)。Spring Data JPA 是 Spring 提供的一套对 JPA 操作更加高级的封装,是在 JPA 规范下的专⻔用来进行数 据持久化的解决方案。
二、案例
首先明确一下操作思路:
1.构建工程,创建表,不过多详述。
2.创建工程导入依赖,网上有很多例子,可以根据自己的项目和工具版本导入兼容的依赖。
3.配置 Spring 的配置文件,就是配置指定框架执行的细节。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/jpa
https://www.springframework.org/schema/data/jpa/spring-jpa.xsd
">
<!--对Spring和SpringDataJPA进行配置-->
<!--1、创建数据库连接池druid-->
<!--引入外部资源文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--第三方jar中的bean定义在xml中-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--2、配置一个JPA中非常重要的对象,entityManagerFactory
entityManager类似于Mybatis中的SqlSession
entityManagerFactory类似于Mybatis中的SqlSessionFactory
-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!--配置数据源-->
<property name="dataSource" ref="dataSource"/>
<!--配置包扫描(实体类所在的包)-->
<property name="packagesToScan" value="com.riemann.pojo"/>
<!--指定jpa的具体实现,也就是hibernate-->
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider"></bean>
</property>
<!--jpa方言配置,不同的jpa实现对于类似于beginTransaction等细节实现起来是不一样的,
所以传入JpaDialect具体的实现类-->
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"></bean>
</property>
<!--配置具体provider,hibearnte框架的执行细节-->
<property name="jpaVendorAdapter" >
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!--定义hibernate框架的一些细节-->
<!--
配置数据表是否自动创建
因为我们会建立pojo和数据表之间的映射关系
程序启动时,如果数据表还没有创建,是否要程序给创建一下
-->
<property name="generateDdl" value="false"/>
<!--
指定数据库的类型
hibernate本身是个dao层框架,可以支持多种数据库类型的,这里就指定本次使用的什么数据库
-->
<property name="database" value="MYSQL"/>
<!--
配置数据库的方言
hiberante可以帮助我们拼装sql语句,但是不同的数据库sql语法是不同的,所以需要我们注入具体的数据库方言
-->
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>
<!--是否显示sql
操作数据库时,是否打印sql
-->
<property name="showSql" value="true"/>
</bean>
</property>
</bean>
<!--3、引用上面创建的entityManagerFactory
<jpa:repositories> 配置jpa的dao层细节
base-package:指定dao层接口所在包
-->
<jpa:repositories base-package="com.riemann.dao" entity-manager-factory-ref="entityManagerFactory"
transaction-manager-ref="transactionManager"/>
<!--4、事务管理器配置
jdbcTemplate/mybatis 使用的是DataSourceTransactionManager
jpa规范:JpaTransactionManager
-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!--5、声明式事务配置-->
<!--
<tx:annotation-driven/>
-->
<!--6、配置spring包扫描-->
<context:component-scan base-package="com.riemann"/>
</beans>
4.编写实体类 Resume,使用 JPA 注解配置映射关系。
@Data
@Entity
@Table(name = "tb_resume")
public class Resume {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "address")
private String address;
@Column(name = "phone")
private String phone;
}
上面:
@Entity和@Table表示实体类和数据表映射关系
@Id 标识主键
@GeneratedValue 标识主键的生成策略,有两种,一种是GenerationType.IDENTITY:依赖数据库中主键自增功能,另一种是 GenerationType.SEQUENCE:依靠序列来产生主键。
@Column 建立属性和字段映射
5.编写一个符合 Spring Data JPA 的 Dao 层接口。
public interface ResumeDao extends JpaRepository<Resume, Long>, JpaSpecificationExecutor<Resume> {
@Query("from Resume where id=?1 and name=?2")
List<Resume> findByJpql(Long id, String name);
//可以使用Optional替换List
@Query(value = "select * from tb_resume where name like ?1 and address like ?2", nativeQuery = true)
//使用原生sql语句查询,需要将nativeQuery属性设置为true,默认为false(jpql)
List<Resume> findBySql(String name, String address);
List<Resume> findByNameLikeAndAddress(String name, String address);
}
上面:
JpaRepository<操作的实体类类型,主键类型>封装了基本的CRUD操作
JpaSpecificationExecutor<操作的实体类类型>封装了复杂的查询(分页、排序等)
6.操作 ResumeDao 接口对象完成 Dao 层开发。
我们的业务经常性要满足查询需要,在增加,删除,更新方面其实运用较少。下面是查询常用方式
方式一:调用继承的接口中的方法 findOne(),findById()
方式二:可以引入jpql(jpa查询语言)语句进行查询 (=====>>>> jpql 语句类似于sql,只不过sql操作的是数据表和字段,jpql操作的是对象和属性,比如 from Resume where id=xx) hql
方式三:可以引入原生的sql语句
方式四:可以在接口中自定义方法,而且不必引入jpql或者sql语句,这种方式叫做方法命名规则查询,也就是说定义的接口方法名是按照一定规则形成的,那么框架就能够理解我们的意图
方式五:动态查询
service层传入dao层的条件不确定,把service拿到条件封装成一个对象传递给Dao层,这个对象就叫做Specification(对条件的一个封装)
// 根据条件查询单个对象
Optional findOne(@Nullable Specification var1);
// 根据条件查询所有
List findAll(@Nullable Specification var1);
写一个动态查询以供参考
@Test
public void testSpecfication() {
/* 借助于两个参数完成条件拼装,select * from tb_resume where name='张三'
* Root: 获取需要查询的对象属性
* CriteriaBuilder:构建查询条件,内部封装了很多查询条件(模糊查询,精准查询)
*/
Specification specification = new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
// 获取到name属性
Path<Object> name = root.get("name");
// 使用CriteriaBuilder针对name属性构建条件(精准查询)
Predicate predicate = criteriaBuilder.equal(name, "张三");
return predicate;
}
};
Optional<Resume> optional = resumeDao.findOne(specification);
Resume resume = optional.get();
System.out.println(resume);
}
总结
Spring Data 是现在很多大型企业必备的中级技能,因为大型企业有着众多数据需要处理,所以十分看重数据处理能力,JPA 是应用于Dao层的一个框架,也是Spring Data 的一个重要成员,而且比Hibernate更加高级。