JPA简介及其使用详解

一、Spring data JPA简介

Spring data JPA是Spring在ORM(对象关系映射)框架,以及JPA规范的基础上,封装的一套JPA应用框架,并提供了一整套的数据访问层解决方案。

二.JPA常用注解

注解 解释
@Entity 声明类为实体或表
@Table 声明表名
@Basic 指定非约束明确的各个字段
@Embedded 指定类或它的值是一个可嵌入的类的实例的实体的属性
@Id 指定的类的属性,用于识别(一个表中的主键)
@GeneratedValue 指定如何标识属性可以被初始化,例如自动、手动、或从序列表中获得的值
@Transient 指定的属性,它是不持久的,即:该值永远不会存储在数据库中
@Column 指定持久属性栏属性
@SequenceGenerator 指定在@GeneratedValue注解中指定的属性的值。它创建了一个序列
@TableGenerator 指定在@GeneratedValue批注指定属性的值发生器。它创造了的值生成的表
@AccessType 这种类型的注释用于设置访问类型。如果设置@AccessType(FIELD),则可以直接访问变量并且不需要getter和setter,但必须为public。如果设置@AccessType(PROPERTY),通过getter和setter方法访问Entity的变量
@JoinColumn 指定一个实体组织或实体的集合。这是用在多对一和一对多关联
@UniqueConstraint 指定的字段和用于主要或辅助表的唯一约束
@ColumnResult 参考使用select子句的SQL查询中的列名
@ManyToMany 定义了连接表之间的多对多一对多的关系
@ManyToOne 定义了连接表之间的多对一的关系
@OneToMany 定义了连接表之间存在一个一对多的关系
@OneToOne 定义了连接表之间有一个一对一的关系
@NamedQueries 指定命名查询的列表
@NamedQuery 指定使用静态名称的查询

三、Spring data JPA的功能

Spring data JPA提供给用户使用的,主要有以下几个接口:

  1. Repository:仅仅是一个标识,表明任何继承它的均为仓库接口类,方便Spring自动扫描识别
  2. CrudRepository:继承Repository,实现了一组CRUD相关的方法
  3. PagingAndSortingRepository:继承CrudRepository,实现了一组分页排序相关的方法
  4. JpaRepository:继承PagingAndSortingRepository,实现一组JPA规范相关的方法
  5. JpaSpecificationExecutor:比较特殊,不属于Repository体系,实现一组JPA Criteria查询相关的方法。

四、Spring data JPA接口

1、CrudRepository接口

该接口的定义如下,总共提供了11个方法,基本上可以满足简单的CRUD操作以及批量操作:

@NoRepositoryBean
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {<S extends T> S save(S entity);//保存<S extends T> Iterable<S> save(Iterable<S> entities);//批量保存T findOne(ID id);//根据id查询一个对象boolean exists(ID id);//判断对象是否存在Iterable<T> findAll();//查询所有的对象Iterable<T> findAll(Iterable<ID> ids);//根据id列表查询所有的对象long count();//计算对象的总个数void delete(ID id);//根据id删除void delete(T entity);//删除对象void delete(Iterable<? extends T> entities);//批量删除void deleteAll();//删除所有
}

2、PagingAndSortingRepository接口

PagingAndSortingRepository接口继承了CrudRepository接口。

只要继承了这个接口,Spring data JPA就已经为你提供了分页和排序的功能了。该接口的定义如下,主要提供了两个方法,供使用,其中T是要操作的实体类,ID是实体类主键的类型:

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {Iterable<T> findAll(Sort sort);// 不带分页的排序Page<T> findAll(Pageable pageable);// 带分页的排序
}

3、JpaRepository接口

如果业务需要即提供CRUD操作,又需要提供分页以及排序功能,那么就可以直接继承这个接口。该接口继承了PagingAndSortingRepository接口。

接口定义如下:

public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {List<T> findAll();//查询所有对象,不排序List<T> findAll(Sort sort);//查询所有对象,并排序<S extends T> List<S> save(Iterable<S> entities);//批量保存void flush();//强制缓存与数据库同步T saveAndFlush(T entity);//保存并强制同步void deleteInBatch(Iterable<T> entities);//批量删除void deleteAllInBatch();//删除所有
}

4、JpaSpecificationExecutor接口

该接口提供了对JPA Criteria查询的支持。注意,这个接口很特殊,不属于Repository体系,而Spring data JPA不会自动扫描识别,所以会报找不到对应的Bean,我们只需要继承任意一个继承了Repository的子接口或直接继承Repository接口,Spring data JPA就会自动扫描识别,进行统一的管理。

编写接口如下:

public interface SpecificationExecutorRepository extends CrudRepository<User, Integer>,JpaSpecificationExecutor<User> {
}

Service类

@Service
public class SpecificationExecutorRepositoryManager {@Autowiredprivate SpecificationExecutorRepository dao;/*** 描述:根据name来查询用户*/public User findUserByName(final String name){return dao.findOne(new Specification<User>() {@Overridepublic Predicate toPredicate(Root<User> root, CriteriaQuery<?> query,CriteriaBuilder cb) {Predicate predicate = cb.equal(root.get("name"), name);return predicate;}});}/*** 描述:根据name和email来查询用户*/public User findUserByNameAndEmail(final String name, final String email){return dao.findOne(new Specification<User>() {@Overridepublic Predicate toPredicate(Root<User> root,CriteriaQuery<?> query, CriteriaBuilder cb) {List<Predicate> list = new ArrayList<Predicate>();Predicate predicate1 = cb.equal(root.get("name"), name);Predicate predicate2 = cb.equal(root.get("email"), email);list.add(predicate1);list.add(predicate2);// 注意此处的处理Predicate[] p = new Predicate[list.size()];return cb.and(list.toArray(p));}});}/*** 描述:组合查询*/public User findUserByUser(final User userVo){return dao.findOne(new Specification<User>() {@Overridepublic Predicate toPredicate(Root<User> root,CriteriaQuery<?> query, CriteriaBuilder cb) {Predicate predicate = cb.equal(root.get("name"), userVo.getName());cb.and(predicate, cb.equal(root.get("email"), userVo.getEmail()));cb.and(predicate, cb.equal(root.get("password"), userVo.getPassword()));return predicate;}});}/*** 描述:范围查询in方法,例如查询用户id在[2,10]中的用户*/public List<User> findUserByIds(final List<Integer> ids){return dao.findAll(new Specification<User>() {@Overridepublic Predicate toPredicate(Root<User> root,CriteriaQuery<?> query, CriteriaBuilder cb) {return root.in(ids);}});}/*** 描述:范围查询gt方法,例如查询用户id大于9的所有用户*/public List<User> findUserByGtId(final int id){return dao.findAll(new Specification<User>() {@Overridepublic Predicate toPredicate(Root<User> root,CriteriaQuery<?> query, CriteriaBuilder cb) {return cb.gt(root.get("id").as(Integer.class), id);}});}/*** 描述:范围查询lt方法,例如查询用户id小于10的用*/public List<User> findUserByLtId(final int id){return dao.findAll(new Specification<User>() {@Overridpublic Predicate toPredicate(Root<User> root,CriteriaQuery<?> query, CriteriaBuilder cb) {return cb.lt(root.get("id").as(Integer.class), id);}});}/*** 描述:范围查询between方法,例如查询id在3和10之间的用户*/public List<User> findUserBetweenId(final int start, final int end){return dao.findAll(new Specification<User>() {@Overridepublic Predicate toPredicate(Root<User> root,CriteriaQuery<?> query, CriteriaBuilder cb) {return cb.between(root.get("id").as(Integer.class), start, end);}});}/*** 描述:排序和分页操作*/public Page<User> findUserAndOrder(final int id){Sort sort = new Sort(Direction.DESC, "id");return dao.findAll(new Specification<User>() {@Overridepublic Predicate toPredicate(Root<User> root,CriteriaQuery<?> query, CriteriaBuilder cb) {return cb.gt(root.get("id").as(Integer.class), id);}}, new PageRequest(0, 5, sort));}/*** 描述:只有排序操作*/public List<User> findUserAndOrderSecondMethod(final int id){return dao.findAll(new Specification<User>() {@Overridepublic Predicate toPredicate(Root<User> root,CriteriaQuery<?> query, CriteriaBuilder cb) {cb.gt(root.get("id").as(Integer.class), id);query.orderBy(cb.desc(root.get("id").as(Integer.class)));return query.getRestriction();}});}
}

5、Repository接口

这个接口是最基础的接口,只是一个标志性的接口,没有定义任何的方法,那这个接口有什么用了?既然Spring data JPA提供了这个接口,自然是有它的用处,例如,我们有一部分方法是不想对外提供的,比如我们只想提供增加和修改方法,不提供删除方法,那么前面的几个接口都是做不到的,这个时候,我们就可以继承这个接口,然后将CrudRepository接口里面相应的方法拷贝到Repository接口就可以了。

总结:上述五个接口,开发者到底该如何选择?其实依据很简单,根据具体的业务需求,选择其中之一。因为各个接口之间并不存在功能强弱的问题。

五、Spring data JPA的查询

1、使用 @Query 创建查询

2、使用@NamedQueries创建查询

3、通过解析方法名创建查询

在查询时,通常需要同时根据多个属性进行查询,且查询的条件也格式各样(大于某个值、在某个范围等等),Spring Data JPA 为此提供了一些表达条件查询的关键字,大致如下:

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 findByFirstname,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<Age> ages) … where x.age in ?1
NotIn findByAgeNotIn(Collection<Age> 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)

JPA简介及其使用详解相关推荐

  1. Nginx 反向代理工作原理简介与配置详解

    Nginx 反向代理工作原理简介与配置详解 测试环境 CentOS 6.8-x86_64 nginx-1.10.0 下载地址:http://nginx.org/en/download.html 安装 ...

  2. Android OkHttp3简介和使用详解

    一 OKHttp简介 OKHttp是一个处理网络请求的开源项目,Android 当前最火热网络框架,由移动支付Square公司贡献,用于替代HttpUrlConnection和Apache HttpC ...

  3. FTP服务的简介和配置详解

    FTP服务的简介和配置详解 注意:配置FTP服务时,最好关闭防火墙和selinux 1.FTP服务简介 FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为& ...

  4. Spring Data JPA 之 @Query 语法详解及其应用

    5 Spring Data JPA 之 @Query 语法详解及其应用 5.1 快速体验 @Query 的方法 沿⽤我们之前的例⼦,新增⼀个 @Query 的⽅法: // 通过 query 注解根据 ...

  5. DL之Transformer:Transformer的简介(优缺点/架构详解,基于Transformer的系列架构对比分析)、使用方法(NLP领域/CV领域)、案例应用之详细攻略

    DL之Transformer:Transformer的简介(优缺点/架构详解,基于Transformer的系列架构对比分析).使用方法(NLP领域/CV领域).案例应用之详细攻略 目录 Transfo ...

  6. HAProxy 简介及配置文件详解

    文章目录 1.HAProxy简介 2.HAProxy特点和优点: 3.HAProxy保持会话的三种解决方法 4.HAProxy的balance 8种负载均衡算法: 5.HAProxy 主要工作模式 6 ...

  7. Spark之 spark简介、生态圈详解

    来源:http://www.cnblogs.com/shishanyuan/p/4700615.html 1.简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorith ...

  8. java jpa注解哪个包好,Spring Data JPA 中常用注解详解

    一.java对象与数据库字段转化 @Entity:标识实体类是JPA实体,告诉JPA在程序运行时生成实体类对应表 @Table:设置实体类在数据库所对应的表名 @Id:标识类里所在变量为主键 @Gen ...

  9. 一张图解释什么是遗传算法_遗传算法简介及代码详解

    (allele) 数据值,属性,值 基因座 (locus) 位置, iterator 位置 表现型 (phenotype) 参数集,解码结构,候选解 染色体:又可以叫做基因型个体 (individua ...

  10. git 添加用户名和邮箱_Git实用教程(二) | Git简介及安装详解

    Git实用教程专栏回顾 Git实用教程(一) | 为什么需要版本控制?(以嵌入式项目开发为例) 1.Git简介 Git(官网 https://git-scm.com/)是一个免费开源的分布式版本控制系 ...

最新文章

  1. c和python区别_C语言和python的区别
  2. tensorflow-eagerAPI
  3. Angular CLI 全局 ng.cmd 文件内容分析
  4. 通过快速Java和文件序列化加快速度
  5. C++ 的门门道道 | 技术头条
  6. Pidgin 新QQ插件:pidgin-lwqq
  7. Vue Element校验validate
  8. 大K提醒各位常备DOS杀毒盘
  9. 关于只针对ie7浏览器的css问题
  10. 【扩频通信】基于matlab GUI扩频通信系统仿真【含Matlab源码 772期】
  11. 使用SecureCRT工具上传、下载文件的两种方法
  12. 小猫跳圈-第12届蓝桥杯Scratch省赛3真题第1题
  13. 汽修汽配进销存 好用的汽修汽配行业管理软件 汽修汽配老板最常用的进销存软件
  14. 下载网站的ICO图标方法
  15. 领导力21法则自测题
  16. 一键模拟登陆华师大公共数据库!ver2.0
  17. 如何批量将png格式改成jpg?
  18. 跨国公司“中国设计”
  19. 数字传输系统的最佳接收与误码分析-python实现
  20. ASP.NET 对路径的访问被拒绝

热门文章

  1. excel对比两顺序不同的表格
  2. 软件设计师考试都考什么内容
  3. 软件设计师中级考试,软考
  4. 光谱共焦位移传感器原理和特性
  5. 开氏温度与摄氏度换算_政策丨车厢温度变化2……冷藏保温车国标开始征求意见...
  6. Java技术栈思维导图
  7. GameFramework框架——UI底层框架梳理
  8. 单词毕业设计,微信小程序毕设,小程序毕设源码,单词天天斗 (毕业设计/实战小程序学习/微信小程序完整项目)
  9. 细说 MySQL登录
  10. R语言绘制韦布尔分布图和泊松(Poisson)分布图,并为二项分布(泊松分布)绘制不同颜色