Spring Data概述

  - Spring Data : Spring 的一个子项目。用于简化数据库访问,支持NoSQL 和 关系数据存储。其主要目标是使数据库的访问变得方便快捷。

  - SpringData 项目所支持 NoSQL 存储: MongoDB (文档数据库)、 Neo4j(图形数据库)、 Redis(键/值存储)、 Hbase(列族数据库)

  - SpringData 项目所支持的关系数据存储技术: JDBC、 JPA

  - JPA Spring Data : 致力于减少数据访问层 (DAO) 的开发量. 开发者唯一要做的,就只是声明持久层的接口,其他都交给 Spring Data JPA 来帮你完成!

  - 框架怎么可能代替开发者实现业务逻辑呢?比如:当有一个 UserDao.findUserById() 这样一个方法声明,大致应该能判断出这是根据给定条件的 ID 查询出满足条件的 User 对象。

   Spring Data JPA 做的便是规范方法的名字,根据符合规范的名字来确定方法需要实现什么样的逻辑。

Spring Data Jpa HelloWorld

  - 使用 Spring Data JPA 进行持久层开发需要的四个步骤:

    1、 配置 Spring 整合 JPA

    2、 在 Spring 配置文件中配置 Spring Data,让 Spring 为声明的接口创建代理对象。配置了 <jpa:repositories> 后,Spring 初始化容器时将会扫描 base-package  指定的包目录及其子目录,

      为继承 Repository 或其子接口的接口创建代理对象,并将代理对象注册为 Spring Bean,业务层便可以通过 Spring 自动封装的特性来直接使用该对象。

    3、声明持久层的接口,该接口继承  Repository,Repository 是一个标记型接口,它不包含任何方法,如必要,Spring Data 可实现 Repository 其他子接口,其中定义了一些常用的增删改查,以及分页相关的方法。

    4、在接口中声明需要的方法。Spring Data 将根据给定的策略(具体策略稍后讲解)来为其生成实现代码。

  - 搭建环境:

    1、同时下载 Spring Data Commons 和 Spring Data JPA 两个发布包:

      > Commons 是 Spring Data 的基础包

      > 并把相关的依赖 JAR 文件加入到 CLASSPATH 中

    2、在 Spring 的配置文件中配置 Spring Data:

      

  - 示例代码:

      

Repository 接口概述

  - Repository 接口是 Spring Data 的一个核心接口,它不提供任何方法,开发者需要在自己定义的接口中声明需要的方法 ,public interface Repository<T, ID extends Serializable> { }

  - Spring Data可以让我们只定义接口,只要遵循 Spring Data的规范,就无需写实现类。

  - 与继承 Repository 等价的一种方式,就是在持久层接口上使用 @RepositoryDefinition 注解,并为其指定 domainClass 和 idClass 属性。两种方式是完全等价的

  - Repository 的子接口:

    > 基础的 Repository 提供了最基本的数据访问功能,其几个子接口则扩展了一些功能。它们的继承关系如下:

      >> Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类

      >> CrudRepository: 继承 Repository,实现了一组 CRUD 相关的方法

      >> PagingAndSortingRepository: 继承 CrudRepository,实现了一组分页排序相关的方法

      >> JpaRepository: 继承 PagingAndSortingRepository,实现一组 JPA 规范相关的方法

      >> 自定义的 XxxxRepository 需要继承 JpaRepository,这样的 XxxxRepository 接口就具备了通用的数据访问控制层的能力。

      >> JpaSpecificationExecutor: 不属于Repository体系,实现一组 JPA Criteria 查询相关的方法

SpringData 方法定义规范

  - 简单条件查询:

    > 简单条件查询: 查询某一个实体类或者集合

    > 按照 Spring Data 的规范,查询方法以 find | read | get 开头, 涉及条件查询时,条件的属性用条件关键字连接,要注意的是:条件属性以首字母大写。

    > 例如:定义一个 Entity 实体类

         class User{

            private String firstName;

            private String lastName;

         }      

      >> 使用And条件连接时,应这样写: findByLastNameAndFirstName(String lastName,String firstName);

      >> 条件的属性名称与个数要与参数的位置与个数一一对应

  - 支持的关键字

    > 直接在接口中定义查询方法,如果是符合规范的,可以不用写实现,目前支持的关键字写法如下:

      

      

  - 查询方法解析流程

    > 假如创建如下的查询:findByUserDepUuid(),框架在解析该方法时,首先剔除 findBy,然后对剩下的属性进行解析,假设查询实体为Doc:

      >> 先判断 userDepUuid (根据 POJO 规范,首字母变为小写)是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,继续第二步;

      >> 从右往左截取第一个大写字母开头的字符串(此处为Uuid),然后检查剩下的字符串是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设 user 为查询实体的一个属性;

      >> 接着处理剩下部分(DepUuid),先判断 user 所对应的类型是否有depUuid属性,如果有,则表示该方法最终是根据 “ Doc.user.depUuid” 的取值进行查询;否则继续按照步骤 2 的规则从右往左截取,最终表示根据 “Doc.user.dep.uuid” 的值进行查询。

      >> 可能会存在一种特殊情况,比如 Doc包含一个 user 的属性,也有一个 userDep 属性,此时会存在混淆。可以明确在属性之间加上 "_" 以显式表达意图,比如 "findByUser_DepUuid()" 或者 "findByUserDep_uuid()"

    > 特殊的参数: 还可以直接在方法的参数上加入分页或排序的参数,比如:

      >> Page<UserModel> findByName(String name, Pageable pageable);

      >> List<UserModel> findByName(String name, Sort sort);

使用 @Query 注解

  - 使用@Query自定义查询

    > 这种查询可以声明在 Repository 方法中,摆脱像命名查询那样的约束,将查询直接在相应的接口方法中声明,结构更为清晰,这是 Spring data 的特有实现。

      

  - 索引参数与命名参数

    > 索引参数如下所示,索引值从1开始,查询中 ”?X” 个数需要与方法定义的参数个数相一致,并且顺序也要一致

    > 命名参数(推荐使用这种方式):可以定义好参数名,赋值时采用@Param("参数名"),而不用管顺序。

      

    > 如果是 @Query 中有 LIKE 关键字,后面的参数需要前面或者后面加 %,这样在传递参数值的时候就可以不加 %:

      >> @Query("select o from UserModel o where o.name like ?1%")

         public List<UserModel> findByUuidOrAge(String name);

      >> @Query("select o from UserModel o where o.name like %?1")

        public List<UserModel> findByUuidOrAge(String name);

      >> @Query("select o from UserModel o where o.name like %?1%")   

        public List<UserModel> findByUuidOrAge(String name);

  - 用@Query来指定本地查询

    > 还可以使用@Query来指定本地查询,只要设置nativeQuery为true,比如:

      >> @Query(value="select * from tbl_user where name like %?1" ,nativeQuery=true)

         public List<UserModel> findByUuidOrAge(String name);

@Modifying 注解和事务

  - @Query 与 @Modifying 执行更新操作

    > @Query 与 @Modifying 这两个 annotation一起声明,可定义个性化更新操作,例如只涉及某些字段更新时最为常用,示例如下:

      

    > 注意:

      >> 方法的返回值应该是 int,表示更新语句所影响的行数

      >> 在调用的地方必须加事务,没有事务不能正常执行

事务

  - Spring Data 提供了默认的事务处理方式,即所有的查询均声明为只读事务。

  - 对于自定义的方法,如需改变 Spring Data 提供的事务默认方式,可以在方法上注解 @Transactional 声明

  - 进行多个 Repository 操作时,也应该使它们在同一个事务中处理,按照分层架构的思想,这部分属于业务逻辑层,因此,需要在 Service 层实现对多个 Repository 的调用,并在相应的方法上声明事务。

CrudRepository 接口

  - CrudRepository

    > CrudRepository 接口提供了最基本的对实体类的添删改查操作 :

      >> T save(T entity);//保存单个实体

      >> Iterable<T> save(Iterable<? extends T> entities);//保存集合

      >> T findOne(ID id);//根据id查找实体

      >> boolean exists(ID id);//根据id判断实体是否存在

      >> Iterable<T> findAll();//查询所有实体,不用或慎用!

      >> long count();//查询实体数量

      >> void delete(ID id);//根据Id删除实体

      >> void delete(T entity);//删除一个实体

      >> void delete(Iterable<? extends T> entities);//删除一个实体的集合

      >> void deleteAll();//删除所有实体,不用或慎用!

PagingAndSortingRepository接口

  - PagingAndSortingRepository

    > 该接口提供了分页与排序功能 :

      >> Iterable<T> findAll(Sort sort); //排序

      >> Page<T> findAll(Pageable pageable); //分页查询(含排序功能)

JpaRepository接口

  - JpaRepository

    > 该接口提供了JPA的相关功能

      >> List<T> findAll(); //查找所有实体

      >> List<T> findAll(Sort sort); //排序、查找所有实体

      >> List<T> save(Iterable<? extends T> entities);//保存集合

      >> void flush();//执行缓存与数据库同步

      >> T saveAndFlush(T entity);//强制执行持久化

      >> void deleteInBatch(Iterable<T> entities);//删除一个实体集合

JpaSpecificationExecutor接口

  - JpaSpecificationExecutor

    > 不属于Repository体系,实现一组 JPA Criteria 查询相关的方法

      

    > Specification:封装 JPA Criteria 查询条件。通常使用匿名内部类的方式来创建该接口的对象

自定义 Repository 方法

  - 为某一个 Repository 上添加自定义方法

    > 步骤:

      1、 定义一个接口: 声明要添加的, 并自实现的方法

      2、 提供该接口的实现类: 类名需在要声明的 Repository 后添加 Impl, 并实现方法

      3、 声明 Repository 接口, 并继承 1) 声明的接口

      4、 使用.

      >>  注意: 默认情况下, Spring Data 会在 base-package 中查找 "接口名Impl" 作为实现类. 也可以通过 repository-impl-postfix 声明后缀.

  - 为所有的 Repository 都添加自实现的方法

    > 步骤:

      1、声明一个接口, 在该接口中声明需要自定义的方法, 且该接口需要继承 Spring Data 的 Repository.

      2、提供 1) 所声明的接口的实现类. 且继承 SimpleJpaRepository, 并提供方法的实现

      3、定义 JpaRepositoryFactoryBean 的实现类, 使其生成 1) 定义的接口实现类的对象

      4、修改 <jpa:repositories /> 节点的 factory-class 属性指向 3) 的全类名

      >> 注意: 全局的扩展实现类不要用 Imp 作为后缀名, 或为全局扩展接口添加 @NoRepositoryBean 注解告知  Spring Data: Spring Data 不把其作为 Repository

JavaEE高级-Spring Data学习笔记的更多相关文章

  1. JavaEE高级-通用Mapper学习笔记

    通用 Mapper 笔记 1 引入 1.1作用 替我们生成常用增删改查操作的 SQL 语句. 1.2代码官方发布地址 https://gitee.com/free https://gitee.com/ ...

  2. SpringBoot + Spring Security 学习笔记(三)实现图片验证码认证

    整体实现逻辑 前端在登录页面时,自动从后台获取最新的验证码图片 服务器接收获取生成验证码请求,生成验证码和对应的图片,图片响应回前端,验证码保存一份到服务器的 session 中 前端用户登录时携带当 ...

  3. Spring框架学习笔记(1)

    Spring 框架学习笔记(1) 一.简介 Rod Johnson(spring之父) Spring是分层的Java SE/EE应用 full-stack(服务端的全栈)轻量级(跟EJB比)开源框架, ...

  4. JavaEE精英进阶课学习笔记《博学谷》

    JavaEE精英进阶课学习笔记<博学谷> 第1章 亿可控系统分析与设计 学习目标 了解物联网应用领域及发展现状 能够说出亿可控的核心功能 能够画出亿可控的系统架构图 能够完成亿可控环境的准 ...

  5. Spring MVC 学习笔记一 HelloWorld

    Spring MVC 学习笔记一 HelloWorld Spring MVC 的使用可以按照以下步骤进行(使用Eclipse): 加入JAR包 在web.xml中配置DispatcherServlet ...

  6. SpringBoot + Spring Security 学习笔记(五)实现短信验证码+登录功能

    在 Spring Security 中基于表单的认证模式,默认就是密码帐号登录认证,那么对于短信验证码+登录的方式,Spring Security 没有现成的接口可以使用,所以需要自己的封装一个类似的 ...

  7. Spring框架学习笔记(5)——Spring Boot创建与使用

    Spring Boot可以更为方便地搭建一个Web系统,之后服务器上部署也较为方便 创建Spring boot项目 1. 使用IDEA创建项目 2. 修改groupid和artifact 3. 一路n ...

  8. Spring框架学习笔记(8)——spring boot+mybatis plus+mysql项目环境搭建

    之前写的那篇Spring框架学习笔记(5)--Spring Boot创建与使用,发现有多小细节没有提及,,正好现在又学习了mybatis plus这款框架,打算重新整理一遍,并将细节说清楚 1.通过I ...

  9. Spring Boot 学习笔记(六) 整合 RESTful 参数传递

    Spring Boot 学习笔记 源码地址 Spring Boot 学习笔记(一) hello world Spring Boot 学习笔记(二) 整合 log4j2 Spring Boot 学习笔记 ...

随机推荐

  1. Spotlight_on_linux 安装和监控

    一.下载 下载并安装 Spotlight_on_linux 二.建立连接 注意:用户名不能使用root连接,需要自己创建个用户root权限的用户 1.useradd  xiaoxitest   2.p ...

  2. es索引基本操作(1)

    1:创建索引 创建索引的时候可以通过number_of_shards和number_of_replicas来指定当前索引的分片和副本数量: PUT demo_index1   {     " ...

  3. Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?

    if first time to install docker, be noted the docker engine started as root copied from: http://blog ...

  4. @清晰掉 Sizeof与字符串

    Sizeof与字符串 1.以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符 如在代码中写  "abc",那么编译器帮你存储的是"abc/0" 2 ...

  5. 八、RF的内置变量

    1.表示“空”的变量 ${EMPTY} 空 适用输入空的案例 2.表示“空格”的变量 ${SPACE} 空格,如果是需要5个空格可以这样写${SPACE*5} 3.目录的绝对路径 ${CURDIR} ...

  6. VASP学习笔记--简单的VASP运行实例:CrI3做非磁的优化

    一.总体思路 1)写入INCAR: 2)写入POSCAR,就是坐标文件: 3)写入KPOINTS文件,就是K点的选择: 4)写入POTCAR,写入POTCAR(找到势文件,然后按照POSCAR中的元素 ...

  7. Spring框架中的依赖注入

    依赖注入(DI : Dependency Injection)是基于.xml配置文件内节点的书写. 注入类型: 1.设置注入,调用了Bean的setXXX()进行值注入 普通属性(value值表示要显 ...

  8. 【奇技淫巧】使用 SSH 转发 Sock5 流量

    标题:使用 SSH 转发 Sock5 流量 日期:2018-06-27 介绍:使用 ssh 来做个 sock5 的代理,穿透到内网中做后渗透 0x01. 基本信息 在 ubuntu(10.211.55 ...

  9. 移动端自动化==>什么是Appium

    转自:http://www.imdsx.cn/ 手机App分为两大类,原生App(Native App)和混合APP(Hybrid App) 原生App(Native App) 原生App实际就是我们 ...

  10. C# 打印倒三角

    void test6(int num) { try { #region 方法1 int maxstar = (num - 1) * 2 + 1; string line = ""; ...