Spring data JPA的简单用法

1、导入jar包。

org.springframework.boot

spring-boot-starter-data-jpa

2、配置文件

#spring data jpa

spring.jpa.generate-ddl=true

spring.jpa.show-sql=true

spring.jpa.hibernate.ddl-auto=update

3、实体的定义


4、定义Repository接口,继承Repository接口。

/**

* 1、Repository是一个空接口,即是一个标记接口

* 2、若我们定义的接口继承了Repository,则该接口会被IOC容器识别为一个Repository Bean,纳入到IOC容器中,

* 进而可以在该接口中定义满足一些规范的方法。

*3、实际上,也可以通过@RepositoryDefinition()注解的方式来替代继承Repository接口

*@RepositoryDefinition(domainClass= Person.class,idClass = Integer.class)

*/

public interfacePersonRepositoryextendsRepository {

Person findByLastName(String lastName);

}

说明:Repository接口中,泛型是对应的实体,类型是对应实体的主键。

5、Repository的子接口。

CrudRepository接口:继承Repository接口,实现了增删改查方法。

JpaRepository接口:继承PagingAndStoringRepository,实现了一组JPA规范的相关方法。

PagingAndStoringRepository接口:继承CrudRepository接口,实现了分页排序相关的方法。

SimpleJpaRepository接口:

JpaSpecificationExcutor接口:不属于Repository体系,实现一组Criteria查询相关方法。

6、Repository接口中声明方法的规范

1、查询方法以 find | read | get 开头;

2、涉及条件查询时,条件的属性用条件关键字连接,要注意的是:条件属性以首字母大写

例如:定义一个 Entity 实体类 class User{

private String firstName;

private String lastName; }

使用And条件连接时,应这样写: findByLastNameAndFirstName(String lastName,String firstName); 条件的属性名称与个数要与参数的位置与个数一一对应

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


4、支持级联查询

若当前类有符合条件的属性,则优先使用,而不使用级联属性。若要使用级联属性,则属性之间使用下划线进行分割。


使用关键字进行查询例子:

//where lastName like ?%

List findByLastNameStartingWith(String lastName);

//where lastName like ?% and id< ?

List getByLastNameStartingWithAndIdLessThan(String lastName,Integer id);

//where lastName in (?,?) or birth

List findByEmailIOrBirthLessThan(List email, Date birth);

//where a.id>?

List findByAddress_IdGreaterThan(Integer id);

5、@Query注解(查询)

//查询Id最大的那个Person(注意:from后面跟着的实体名Person)

//使用@Query注解可以自定义JPQL,语句实现更灵活的查询

@Query("select p from Person p where p.id=(select max(p2.id) from Person p2)")

Person findMaxIdPerson();;

//为Query注解传递参数方式1:使用占位符(参数有顺序)

@Query("select p from Person p where p.lastName=?1 and p.email=?2")

List testQueryAnnotationParams(String lastName,String email);

//为Query注解传递参数方式2:命名参数的方式(参数无顺序)

@Query("select p from Person p where p.lastName=:lastName and p.email=:email")

List testQueryAnnotationParams2(@Param("email") String email,@Param("lastName") String lastName);

//Like参数的传递(在占位符上使用%)

@Query("select p from Person p where p.lastName like %?1% or p.email like %?2%")

List testQueryAnnotationLikeParam(String lastName,String email);

//Like参数的传递(在占位符上使用%)

@Query("select p from Person p where p.lastName like %?% or p.email like %?%")

List testQueryAnnotationLikeParam2(@Param("lastName") String lastName,@Param("email ") String email);

//使用原生的SQL注解

@Query(value ="select count(id) from person",nativeQuery =true)

intgetPersonCount();

6、Modifying注解

//可以通过自定义的JPQL完成update和delete操作,注意:JPQL不支持插入语句(insert)

//在Query注解中,编写JPQL语句,但必须使用@Modiying进行修饰,以通知spring data,这是一个update或者是delete

//update或者是delete操作需要使用事物,此时需要定义Service层,在Service层上添加事物操作

//默认情况下,springdata的每个方法上都是有事物的,但都是一个只读事物,他们不能完成修改操作

@Modifying

@Query("update Person p set p.email=?1 where id=?2")

intupdatePersonLastName(String email,Integer id);

Service层的事物:

@Service

public classPersonServiceImplimplementsPersonService {

@Autowired

privatePersonRepositorypersonRepository;

@Override

@Transactional

public intupdateLastName(String email, Integer id) {

intcount=personRepository.updatePersonLastName("dd",1);

returncount;

}

}

7、CrudRepository子接口

public interfacePersonRepositoryextendsCrudRepository

Service接口:

public interfacePersonService {

intupdateLastName(String email,Integer id);

voidsavePersons(List list);

}

Service接口实现:

@Service

public classPersonServiceImplimplementsPersonService {

@Autowired

privatePersonRepositorypersonRepository;

@Override

@Transactional

public intupdateLastName(String email, Integer id) {

intcount=personRepository.updatePersonLastName("dd",1);

returncount;

}

@Transactional

@Override

public voidsavePersons(List list) {

personRepository.save(list);

}

}

批量添加测试:

@Test

public voidtestSave() {

List persons =newArrayList<>();

for(inti ='a'; i >='z'; i++) {

Person person =newPerson();

person.setBirth(newDate());

person.setLastName("彩虹"+(char)i);

person.setEmail((char)i+"836908728@qq.com"+(char)i);

person.setId(i +10);

persons.add(person);

}

personService.savePersons(persons);

}

8、PageAndSortingRepository子接口

(是一个只读操作,不需要事物)

//pageNo的记录是从1开始

intpageNo =6-1;

intpageSize =5;

//Pageable接口通常使用的其PageRequest实现类,其中封装了分页的相关信息(page,size,sort)

//排序相关,Sort封装了排序的信息

//Order是针对于某一个属性进行升序还是降序

Order order1=newSort.Order(Direction.DESC,"id");

Order order2=newSort.Order(Direction.ASC,"email");

//sort可以包含多个

Sort sort=newSort(order1,order2);

PageRequest pageable =newPageRequest(pageNo, pageSize,sort);

Page page =personRepository.findAll(pageable);

System.out.println("总记录数:"+ page.getTotalElements());

System.out.println("当前第几页:"+ (page.getNumber()+1));

System.out.println("总页数:"+ page.getTotalPages());

System.out.println("当前页面的list:"+ page.getContent());

System.out.println("当前页面的记录数:"+ page.getNumberOfElements());

9、JpaRepository接口:是PagingAndSortingRepository的子接口

public interfacePersonRepositoryextendsJpaRepository

@Test

public voidtestJpaRepository() {

Person person =newPerson();

person.setBirth(newDate());

person.setLastName("云南");

person.setEmail("836908728@qq.com");

person.setId(27);

Person person1 =personRepository.saveAndFlush(person);

System.out.println(person == person1);

}

9、JpaSpecificationExecutor接口,不属于Repository体系

(实现带查询条件的分页)

public interfacePersonRepositoryextendsJpaRepository,JpaSpecificationExecutor

@Test

/**

* 实现带查询条件的分页:

* 使用JpaSpecificationExecutor的PagefindAll(Specificationspec,Pageable pageable)

* Specification:封装了JPA Criteria查询的查询条件

* Pageable:封装了请求分页的信息,例如:pageNo,pageSize,Sort

*/

public voidtestJpaSpecificationExecutor(){

intpageNo=3-1;

intpageSize=5;

PageRequest pageRequest=newPageRequest(pageNo,pageSize);

Specification specification=newSpecification() {

/**

*

*@paramroot:代表查询的实体类

*@paramcriteriaQuery:可以从中得到root对象,即告知JPA Criteria查询要查询哪一个实体类,还可以添加查询条件

*                    还可以结合EntityManager对象得到最终查询的TypeQuery对象

*@paramcriteriaBuilder:CriteriaBuilder 用于创建Criteria相关对象的工厂,当然可以从中获取到Predicate对象

*@returnPredicate类型,代表一个查询条件

*/

@Override

//如:实现id>5

publicPredicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {

Path path=root.get("id");

Predicate predicate=criteriaBuilder.gt(path,5);

returnpredicate;

}

};

Page page=personRepository.findAll(specification,pageRequest);

System.out.println("总记录数:"+ page.getTotalElements());

System.out.println("当前第几页:"+ (page.getNumber() +1));

System.out.println("总页数:"+ page.getTotalPages());

System.out.println("当前页面的list:"+ page.getContent());

System.out.println("当前页面的记录数:"+ page.getNumberOfElements());

}

10、自定义Repository接口

•步骤:

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

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

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

–使用.

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

如:定义一个接口:


2、实现接口


3、继承自定义接口

public interfacePersonRepositoryextendsJpaRepository,JpaSpecificationExecutor,TestRepository

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

推荐阅读更多精彩内容