Spring Data JPA 的使用(山东数漫江湖)
pring data jpa介绍
什么是JPA
JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据。
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率!
spring data jpa让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现
简单查询
基本查询也分为两种,一种是spring data默认已经实现,一种是根据查询的方法来自动解析成SQL。
spring data jpa 默认预先生成了一些基本的CURD的方法,例如:增、删、改等等
public interface ItemRepository extends JpaRepository<Item, Integer>, JpaSpecificationExecutor<Item> {
//空的,可以什么都不用写
}
@Test
public void test1() throws Exception {
Item item = new Item();
itemRepository.save(item);
List<Item> itemList = itemRepository.findAll();
Item one = itemRepository.findOne(1);
itemRepository.delete(item);
long count = itemRepository.count();
}
自定义简单查询
Item findByItemName(String itemName);
List<Item> findByItemNameLike(String itemName);
Long deleteByItemId(Integer id);
List<Item> findByItemNameLikeOrderByItemNameDesc(String itemName);
具体的关键字,使用方法和生产成SQL如下表所示
Keyword | Sample | JPQL snippet |
---|---|---|
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age ⇐ ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection age) | … where x.age not in ?1 |
TRUE | findByActiveTrue() | … where x.active = true |
FALSE | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
分页查询
Page<Item> findALL(Pageable pageable);
@Test
public void test1() throws Exception {
int page=1,size=10;
Sort sort = new Sort(Sort.Direction.DESC, "id");//根据id降序排序
Pageable pageable = new PageRequest(page, size, sort);
Page<Item> pageResult = itemRepository.findALL(pageable);
List<Item> itemList = pageResult.getContent();
}
自定义SQL查询
在SQL的查询方法上面使用
@Query
注解,如涉及到删除和修改在需要加上@Modifying
.也可以根据需要添加@Transactional
对事物的支持
//自定分页查询 一条查询数据,一条查询数据量
@Query(value = "select i from Item i",
countQuery = "select count(i.itemId) from Item i")
Page<Item> findall(Pageable pageable);
//nativeQuery = true 本地查询 就是使用原生SQL查询
@Query(value = "select * from item where item_id = ?1", nativeQuery = true)
Item findAllItemById(int id);
@Transactional
@Modifying
@Query("delete from Item i where i.itemId = :itemId")
void deleteInBulkByItemId(@Param(value = "itemId") Integer itemId);
//#{#entityName}就是指定的@Entity,这里就是Item
@Query("select i from #{#entityName} i where i.itemId = ?1")
Item findById(Integer id);
命名查询
在实体类上使用@NameQueries注解
在自己实现的DAO的Repository接口里面定义一个同名的方法
然后就可以使用了,Spring会先找是否有同名的NamedQuery,如果有,那么就不会按照接口定义的方法来解析。
//命名查询
@NamedQueries({
@NamedQuery(name = "Item.findItemByitemPrice",
query = "select i from Item i where i.itemPrice between ?1 and ?2"),
@NamedQuery(name = "Item.findItemByitemStock",
query = "select i from Item i where i.itemStock between ?1 and ?2"),
})
@Entity
@Data
public class Item implements Serializable {
@Id
@GeneratedValue
@Column(name = "item_id")
private int itemId;
private String itemName;
private Integer itemPrice;
private Integer itemStock;
}
/**
* 这里是在domain实体类里@NamedQuery写对应的HQL
* @NamedQuery(name = "Item.findItemByitemPrice",
baseQuery = "select i from Item i where i.itemPrice between ?1 and ?2"),
* @param price1
* @param price2
* @return
*/
List<Item> findItemByitemPrice(Integer price1, Integer price2);
List<Item> findItemByitemStock(Integer stock1, Integer stock2);
那么spring data jpa是怎么通过这些规范来进行组装成查询语句呢?
Spring Data JPA框架在进行方法名解析时,会先把方法名多余的前缀截取掉,比如 find、findBy、read、readBy、get、getBy,然后对剩下部分进行解析。
假如创建如下的查询:findByUserDepUuid()
,框架在解析该方法时,首先剔除 findBy,然后对剩下的属性进行解析
- 先判断 userDepUuid (根据 POJO 规范,首字母变为小写)是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,继续第二步;
- 从右往左截取第一个大写字母开头的字符串此处为Uuid),然后检查剩下的字符串是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设user为查询实体的一个属性;
- 接着处理剩下部分(DepUuid),先判断 user 所对应的类型是否有depUuid属性,如果有,则表示该方法最终是根据
Doc.user.depUuid
的取值进行查询;否则继续按照步骤 2 的规则从右往左截取,最终表示根据Doc.user.dep.uuid
的值进行查询。 - 可能会存在一种特殊情况,比如 Doc包含一个 user 的属性,也有一个 userDep 属性,此时会存在混淆。可以明确在属性之间加上 "_" 以显式表达意图,比如
findByUser_DepUuid()
或者findByUserDep_uuid()
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Spring Data JPA 的使用(山东数漫江湖)的更多相关文章
- Spring Session加Redis(山东数漫江湖)
session是一个非常常见的概念.session的作用是为了辅助http协议,因为http是本身是一个无状态协议.为了记录用户的状态,session机制就应运而生了.同时session也是一个非常老 ...
- SSM三大框架整合详细总结(Spring+SpringMVC+MyBatis)(山东数漫江湖)
使用 SSM ( Spring . SpringMVC 和 Mybatis )已经很久了,项目在技术上已经没有什么难点了,基于现有的技术就可以实现想要的功能,当然肯定有很多可以改进的地方.之前没有记录 ...
- Spring boot集成RabbitMQ(山东数漫江湖)
RabbitMQ简介 RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统 MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过读写出 ...
- Spring整合Quartz分布式调度(山东数漫江湖)
前言 为了保证应用的高可用和高并发性,一般都会部署多个节点:对于定时任务,如果每个节点都执行自己的定时任务,一方面耗费了系统资源,另一方面有些任务多次执行,可能引发应用逻辑问题,所以需要一个分布式的调 ...
- Spring boot 集成Dubbox(山东数漫江湖)
前言 因为工作原因,需要在项目中集成dubbo,所以去查询dubbo相关文档,发现dubbo目前已经不更新了,所以把目光投向了dubbox,dubbox是当当网基于dubbo二次开发的一个项目,dub ...
- Spring+SpringMVC+MyBatis整合(山东数漫江湖)
Spring+SpringMVC+MyBatis(SSM)在我们项目中是经常用到的,这篇文章主要讲解使用Intellij IDEA整合SSM,具体环境如下: 数据库:MySQL5.7 依赖管理:Mav ...
- Spring mvc详解(山东数漫江湖)
Spring mvc框架 Spring web MVC 框架提供了模型-视图-控制的体系结构和可以用来开发灵活.松散耦合的 web 应用程序的组件.MVC 模式导致了应用程序的不同方面(输入逻辑.业务 ...
- 快速搭建springmvc+spring data jpa工程
一.前言 这里简单讲述一下如何快速使用springmvc和spring data jpa搭建后台开发工程,并提供了一个简单的demo作为参考. 二.创建maven工程 http://www.cnblo ...
- spring boot(五):spring data jpa的使用
在上篇文章springboot(二):web综合开发中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jpa 常见用法以及注意事项 使用spr ...
随机推荐
- 用 C# 实现文件信息统计(wc)命令行程序
软件的需求分析 程序处理用户需求的模式为: wc.exe [parameter][filename] 在[parameter]中,用户通过输入参数与程序交互,需实现的功能如下: 1.基本功能 支持 - ...
- LintCode-372.在O(1)时间复杂度删除链表节点
在O(1)时间复杂度删除链表节点 给定一个单链表中的一个等待被删除的节点(非表头或表尾).请在在O(1)时间复杂度删除该链表节点. 样例 给定 1->2->3->4,和节点 3,删除 ...
- 用glob()函数返回目录下的子文件以及子目录
glob() 函数返回匹配指定模式的文件名或目录 相对于readdir()和opendir()来说,使用glob()函数会方便很多 代码1: <?php function getfilename ...
- perf使用的问题,再看perf record,perf record 设置的采样频率,采样频率是如何体现在
当perf stat -e branches 是统计 再看perf record,perf record是为了是记录时间发生的时候的调用栈, 在我的测试代码中总共有200,000,000条branch ...
- codeforces 730 j.bottles
J. Bottles time limit per test 2 seconds memory limit per test 512 megabytes input standard input ou ...
- fzu1686-神龙的难题
给出一个n\times m的01矩阵,以及\(h,w\),表示一次可以把矩阵的一个\(h\times w\)的小矩阵变为全0,问至少要多少次可以把整个矩阵变为全0.\(n,m\le 15\). 分析 ...
- 【bzoj1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 后缀数组+离散化
题目描述 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个“模式”. John的牛奶按质量可以被赋予一 ...
- Go语言【第九篇】:Go数据结构之:数组
Go语言数组 Go语言提供了数组类型的数据结构.数组时具有相同唯一类型的一组已编号且长度固定的数据项序列,中类型可以是任意的原始类型如整形.字符串或者自定义类型. 相对于声明number0,numbe ...
- C# 连接Oracle数据库以及一些简单的操作
拖了很久今天终于在博客园写了自己第一篇随笔: 话不多说,我们直接进入正题: 1.连接数据库 using (OracleConnection conn = new OracleConnection(&q ...
- Square Root of Permutation - CF612E
Description A permutation of length n is an array containing each integer from 1 to n exactly once. ...