Spring Data JPA

一、概念

JPA(Java Persistence API)是Sun官方提出的Java持久化规范。为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。

Spring Data JPA是spring基于ORM框架、JPA规范的基础上封装的一套JPA应用框架,底层使用了Hibernate的JPA技术实现,可使开发者用极简的代码即可实现对数据的访问和操作。提供了包括增删改查等在内的常用功能,且易于扩展。

Spring Data JAP让我们解脱了DAO层的工作,基本上所有的CRUD都可以依赖于它来实现。

JAR包:spring-Boot-starter-data-jpa.jar

二、Repository

1.建立entity相关的注解:

@Entity:用于实体类上。

@Table:指定Entity所要映射的数据库表,如果缺省,系统默认采用类名作为映射表的表名。

@Id:声明此属性为主键。

@GeneratedValue(strategy=GenerationType, generator=""):

strategy表示主键生成策略,有AUTO, INDENTITY, SEQUENCE和TABLE四种,分别表示让ORM框架自动选择,根据数据库的Identity字段生成,根据数据库表的Sequence字段生成,根据一个额外的表生成主键,默认为AUTO。

generator表示主键生成器的名称,这个属性通常和ORM框架有关,例如,hibernate可以指定uuid等主键生成方式。

例:

1)SEQUENCE

@Id@GeneratedValue(strategy=GenarationType.SEQUENCE, genetator="aaa")@SequenceGenerator(name="aaa", sequenceName="seq_xxx")

2)IDENTIFY

@Id@GeneratedValue(strategy=GenarationType.IDENTIFY)

3)AUTO

@Id@GeneratedValue(strategy=GenarationType.AUTO)

@Column(nullable=false, unique=true……)

1.1JPA主键@Id、@IdClass、@Embeddable、@EmbeddedId

1)自动主键

@Id @GeneratedValue一起使用(以上介绍)。

2)应用设置主键

如果一个实体有一个没有@GeneratedValue标记的主键字段,则不会生成自动主键值,并且应用程序负责通过初始化主键字段来设置主键。这必须在持久化实体对象之前完成。

3)复合主键

由多个主键字段组成。当一个实体有多个主键字段时,JPA需要定义一个特殊的ID类,该类是使用@IdClass注释附加到实体类的。如果实体对象必须按照检索实体部分中所示的主键来检索实体对象,那么就需要ID类。

例:

实体类:

@Entity @IdClass(ProjectId.class)

public class Project{

@Id int departmentId;

@Id long projectId;}

ID类:

class ProjectId{

int departmentId;

long projectId;}

4)嵌入式主键

复合主键的另一种方式是使用嵌入式的类。主键字段是在可嵌入类中定义的。该实体包含一个单独的主键字段,该字段用@EmbeddedId注释,并包含一个可嵌入类的实例。当使用这个表单时,没有定义一个单独的ID类,因为可嵌入的类本身可以表示完整的主键值。

例:

实体类:

public class Project{

@EmbeddedId ProjectId id;

}

主键类:

@Embeddable

class ProjectId{

int departmentId;

long projectId;}

注意,复合主键类必须满足:实现Serializable接口;有默认的public无参数构造方法;重写equals和hashCode方法。

2.声明repository接口,可继承JpaRepository, PagingAndSortingRepository, CrudRepository

实际上,JpaRepository实现了PagingAndSortingRepository接口,PagingAndSortingRepository接口实现了CrudRepository接口,CrudRepository接口实现了Repository接口。

Repository接口是一个标识接口,里面是空的;

CrudRepository接口定义了增删改查方法;

PagingAndSortingRepository接口用于分页和排序;

由于JpaRepository接口继承了以上所有接口,所以拥有它们声明的所有方法。

3.直接声明接口不需要具体实现就能完成数据库的操作,其实现原理:

声明的repository接口被注入了一个动态代理,被代理的类是JpaRepository的一个实现SimpleJpaRepository。

Spring会在启动的时候扫描所有继承自Repository接口相关的DAO接口,然后为其实例化一个动态代理,同时根据它的方法名、参数等为其装配一系列DB操作组件,在需要注入的时候为对应的接口注入这个动态代理,在DAO方法被调用的时候会走这个动态代理,然后经过一系列的方法拦截路由到最终的DB操作执行器JpaQuertExecution,然后拼装SQL,执行相关操作,返回结果。

4.应用

1)基本查询

分为两种,一种是Spring Data默认已经实现(只继承JpaRepository),一种是根据查询的方法来自动解析成SQL。

2)复杂查询

在实际的开发中我们需要用到分页、删选、连表等查询的时候就需要特殊的方法或者自定义SQL。

分页查询:需要传入参数Pageable,返回Page对象。Pageable是Spring封装的分页实现类,使用的时候需要传入页数、每页条数和排序规则。

自定义SQL查询:在SQL的查询方法上面使用@Query注解,如果涉及到删除和修改,可以加上@Modifying。也可以根据需要添加@Transactional对事务的支持,查询超时的设置等。

多表查询:有两种实现方式,第一种是利用hibernate的级连查询来实现,第二种是创建一个结果集的接口来接收连表查询后的结果。

5. Spring Data JPA常用注解:

@Transient注解:

表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略此属性。

@NamedQuery注解:

用于实体类上,定义多个时使用@NamedQueries。如@NamedQuery(name="User.findByName", Query="select * from User where name=?1")。在自己实现的DAO的Repository 接口里面定义一个同名的方法,然后在使用中,Spring会找找是否有同名的NamedQuery,如果有,那么久不会按照接口定义的方法来解析。

@Query注解:

用于接口中自定义的查询方法上,可以使用JPQL,也可使用本地查询(nativeQuery=true)。所谓本地查询,就是使用原生SQL语句。

注意:方法的参数个数必须和@Query里需要的参数个数一致;

JPQL占位符"?"后的数字代表的是方法参数里的顺序;

如果是like查询,需要在参数的前面或后面加"%";

同样支持更新类的Query语句,添加@Modifying即可。在调用的地方必须加事务,没有事务不能正常执行???

使用@Param注解注入JPQL或者SQL的参数;可以利用SpEL表达式把实体类写成动态的#{#entityName}:是实体类的名称。实体类Book,使用@Entity注解后,Spring会将实体类Book纳入管理。默认#{#entityName}的值就是"Book"。但是如果使用了@Entity(name="book")来注解实体类Book,此时#{#entityName}的值就变成了"book"。因此,可以用@Entity注解实体类时指定name为比实体类对应的表名,在原生SQL语句中,就可以把#{#entityName}作为数据表名使用。

@Modifying注解:

1)可以通过自定义的JPQL完成UPDATE和DELETE操作。注意:JPQL不支持使用INSERT。

2)在@Query注解中编写JPQL语句,但必须使用@Modifying进行修饰,以通知Spring Data这是一个UPDATE或DELETE操作。

3)UPDATE或DELETE操作需要使用事务,此时需要定义Service层,在Service层的方法上添加事务操作。

4)默认情况下,Spring Data的每个方法上有事务,但都是一个只读事务,它们不能完成修改操作。

@EnableJpaRepositories注解:

6.查询策略

create-if-not-found(默认):如果通过@Query指定查询语句,则执行该语句,如果没有,则看看有没有@NamedQuery指定的查询语句,如果还没有,则通过解析方法名进行查询。

查询策略有三种,可更改。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容