2021-10-09

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更加高级。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值